123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725 |
- /* Copyright (c) 2002-2012 Croteam Ltd.
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as published by
- the Free Software Foundation
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
- // WorldEditorView.cpp : implementation of the CWorldEditorView class
- //
- #include "stdafx.h"
- #include "WorldEditor.h"
- #include <Engine/Base/Profiling.h>
- #include <Engine/Base/Statistics.h>
- #include <Engine/Templates/Stock_CTextureData.h>
- #include <Engine/Terrain/TerrainEditing.h>
- #include <Engine/Terrain/TerrainMisc.h>
- #ifdef _DEBUG
- #undef new
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- CTimerValue _tvLastTerrainBrushingApplied;
- static INDEX aiForCreationOfSizingVertices[14][6] =
- {
- {0,0,2,2,5,5},
- {1,1,2,2,5,5},
- {1,1,2,2,4,4},
- {0,0,2,2,4,4},
- {0,0,3,3,5,5},
- {1,1,3,3,5,5},
- {1,1,3,3,4,4},
- {0,0,3,3,4,4},
- {0,1,2,3,5,5},
- {1,1,2,3,4,5},
- {0,1,2,3,4,4},
- {0,0,2,3,4,5},
- {0,1,2,2,4,5},
- {0,1,3,3,4,5},
- };
- static INDEX aiForAllowedSizing[14][6] =
- {
- {1,0,1,0,0,1},
- {0,1,1,0,0,1},
- {0,1,1,0,1,0},
- {1,0,1,0,1,0},
- {1,0,0,1,0,1},
- {0,1,0,1,0,1},
- {0,1,0,1,1,0},
- {1,0,0,1,1,0},
- {0,0,0,0,0,1},
- {0,1,0,0,0,0},
- {0,0,0,0,1,0},
- {1,0,0,0,0,0},
- {0,0,1,0,0,0},
- {0,0,0,1,0,0},
- };
- /////////////////////////////////////////////////////////////////////////////
- // CWorldEditorView
- IMPLEMENT_DYNCREATE(CWorldEditorView, CView)
- BEGIN_MESSAGE_MAP(CWorldEditorView, CView)
- //{{AFX_MSG_MAP(CWorldEditorView)
- ON_WM_CREATE()
- ON_WM_SIZE()
- ON_WM_KILLFOCUS()
- ON_WM_LBUTTONDOWN()
- ON_WM_KEYDOWN()
- ON_WM_KEYUP()
- ON_WM_MOUSEMOVE()
- ON_WM_RBUTTONDOWN()
- ON_WM_LBUTTONUP()
- ON_WM_RBUTTONUP()
- ON_WM_DROPFILES()
- ON_COMMAND(ID_ISOMETRIC_FRONT, OnIsometricFront)
- ON_COMMAND(ID_ISOMETRIC_BACK, OnIsometricBack)
- ON_COMMAND(ID_ISOMETRIC_BOTTOM, OnIsometricBottom)
- ON_COMMAND(ID_ISOMETRIC_LEFT, OnIsometricLeft)
- ON_COMMAND(ID_ISOMETRIC_RIGHT, OnIsometricRight)
- ON_COMMAND(ID_ISOMETRIC_TOP, OnIsometricTop)
- ON_COMMAND(ID_PERSPECTIVE, OnPerspective)
- ON_COMMAND(ID_ZOOM_LESS, OnZoomLess)
- ON_COMMAND(ID_ZOOM_MORE, OnZoomMore)
- ON_COMMAND(ID_MOVE_DOWN, OnMoveDown)
- ON_COMMAND(ID_MOVE_UP, OnMoveUp)
- ON_WM_LBUTTONDBLCLK()
- ON_COMMAND(ID_MEASUREMENT_TAPE, OnMeasurementTape)
- ON_UPDATE_COMMAND_UI(ID_MEASUREMENT_TAPE, OnUpdateMeasurementTape)
- ON_COMMAND(ID_CIRCLE_MODES, OnCircleModes)
- ON_UPDATE_COMMAND_UI(ID_CIRCLE_MODES, OnUpdateCircleModes)
- ON_COMMAND(ID_DESELECT_ALL, OnDeselectAll)
- ON_COMMAND(ID_DELETE_ENTITIES, OnDeleteEntities)
- ON_UPDATE_COMMAND_UI(ID_DELETE_ENTITIES, OnUpdateDeleteEntities)
- ON_WM_SETCURSOR()
- ON_COMMAND(ID_TAKE_SS, OnTakeSs)
- ON_UPDATE_COMMAND_UI(ID_ENTITY_MODE, OnUpdateEntityMode)
- ON_COMMAND(ID_SECTOR_MODE, OnSectorMode)
- ON_UPDATE_COMMAND_UI(ID_SECTOR_MODE, OnUpdateSectorMode)
- ON_COMMAND(ID_POLYGON_MODE, OnPolygonMode)
- ON_UPDATE_COMMAND_UI(ID_POLYGON_MODE, OnUpdatePolygonMode)
- ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
- ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
- ON_COMMAND(ID_CLONE_CSG, OnCloneCSG)
- ON_UPDATE_COMMAND_UI(ID_CLONE_CSG, OnUpdateCloneCsg)
- ON_COMMAND(ID_MEASURE_ON, OnMeasureOn)
- ON_UPDATE_COMMAND_UI(ID_MEASURE_ON, OnUpdateMeasureOn)
- ON_COMMAND(ID_RESET_VIEWER, OnResetViewer)
- ON_COMMAND(ID_COPY_TEXTURE, OnCopyTexture)
- ON_COMMAND(ID_PASTE_TEXTURE, OnPasteTexture)
- ON_COMMAND(ID_CENTER_ENTITY, OnCenterEntity)
- ON_COMMAND(ID_FUNCTION, OnFunction)
- ON_UPDATE_COMMAND_UI(ID_CENTER_ENTITY, OnUpdateCenterEntity)
- ON_COMMAND(ID_DROP_MARKER, OnDropMarker)
- ON_UPDATE_COMMAND_UI(ID_DROP_MARKER, OnUpdateDropMarker)
- ON_COMMAND(ID_TEST_CONNECTIONS, OnTestConnections)
- ON_UPDATE_COMMAND_UI(ID_TEST_CONNECTIONS, OnUpdateTestConnections)
- ON_COMMAND(ID_ALIGN_VOLUME, OnAlignVolume)
- ON_UPDATE_COMMAND_UI(ID_ALIGN_VOLUME, OnUpdateAlignVolume)
- ON_COMMAND(ID_CURRENT_VIEW_PROPERTIES, OnCurrentViewProperties)
- ON_COMMAND(ID_DELETE_MIP, OnDeleteMip)
- ON_UPDATE_COMMAND_UI(ID_DELETE_MIP, OnUpdateDeleteMip)
- ON_COMMAND(ID_PREVIOUS_MIP_BRUSH, OnPreviousMipBrush)
- ON_UPDATE_COMMAND_UI(ID_PREVIOUS_MIP_BRUSH, OnUpdatePreviousMipBrush)
- ON_COMMAND(ID_NEXT_MIP_BRUSH, OnNextMipBrush)
- ON_UPDATE_COMMAND_UI(ID_NEXT_MIP_BRUSH, OnUpdateNextMipBrush)
- ON_COMMAND(ID_CROSSROAD_FOR_C, OnCrossroadForC)
- ON_COMMAND(ID_CHOOSE_COLOR, OnChooseColor)
- ON_UPDATE_COMMAND_UI(ID_CHOOSE_COLOR, OnUpdateChooseColor)
- ON_COMMAND(ID_MENU_COPY_MAPPING, OnMenuCopyMapping)
- ON_COMMAND(ID_MENU_PASTE_MAPPING, OnMenuPasteMapping)
- ON_COMMAND(ID_SET_AS_CSG_TARGET, OnSetAsCsgTarget)
- ON_COMMAND(ID_KEY_PASTE, OnKeyPaste)
- ON_WM_RBUTTONDBLCLK()
- ON_COMMAND(ID_SELECT_BY_TEXTURE_ADJACENT, OnSelectByTextureAdjacent)
- ON_COMMAND(ID_SELECT_BY_TEXTURE_IN_SECTOR, OnSelectByTextureInSector)
- ON_COMMAND(ID_SELECT_BY_COLOR_IN_SECTOR, OnSelectByColorInSector)
- ON_COMMAND(ID_CONUS_PRIMITIVE, OnConusPrimitive)
- ON_COMMAND(ID_TORUS_PRIMITIVE, OnTorusPrimitive)
- ON_COMMAND(ID_TERRAIN_PRIMITIVE, OnTerrainPrimitive)
- ON_COMMAND(ID_SPHERE_PRIMITIVE, OnSpherePrimitive)
- ON_COMMAND(ID_STAIRCASE_PRIMITIVE, OnStaircasePrimitive)
- ON_UPDATE_COMMAND_UI(ID_CONUS_PRIMITIVE, OnUpdateConusPrimitive)
- ON_UPDATE_COMMAND_UI(ID_SPHERE_PRIMITIVE, OnUpdateSpherePrimitive)
- ON_UPDATE_COMMAND_UI(ID_TERRAIN_PRIMITIVE, OnUpdateTerrainPrimitive)
- ON_UPDATE_COMMAND_UI(ID_TORUS_PRIMITIVE, OnUpdateTorusPrimitive)
- ON_UPDATE_COMMAND_UI(ID_STAIRCASE_PRIMITIVE, OnUpdateStaircasePrimitive)
- ON_COMMAND(ID_POPUP_CONUS, OnPopupConus)
- ON_COMMAND(ID_POPUP_SPHERE, OnPopupSphere)
- ON_COMMAND(ID_POPUP_STAIRS, OnPopupStairs)
- ON_COMMAND(ID_POPUP_TERRAIN, OnPopupTerrain)
- ON_COMMAND(ID_POPUP_TORUS, OnPopupTorus)
- ON_UPDATE_COMMAND_UI(ID_MOVE_DOWN, OnUpdateMoveDown)
- ON_UPDATE_COMMAND_UI(ID_MOVE_UP, OnUpdateMoveUp)
- ON_COMMAND(ID_SELECT_LIGHTS, OnSelectLights)
- ON_COMMAND(ID_DISCARD_SHADOWS, OnDiscardShadows)
- ON_COMMAND(ID_COPY_SECTOR_AMBIENT, OnCopySectorAmbient)
- ON_COMMAND(ID_PASTE_SECTOR_AMBIENT, OnPasteSectorAmbient)
- ON_COMMAND(ID_SELECT_ALL_POLYGONS, OnSelectAllPolygons)
- ON_COMMAND(ID_COPY_SECTORS, OnCopySectors)
- ON_COMMAND(ID_DELETE_SECTORS, OnDeleteSectors)
- ON_COMMAND(ID_PASTE_SECTORS, OnPasteSectors)
- ON_COMMAND(ID_CENTER_BCG_VIEWER, OnCenterBcgViewer)
- ON_COMMAND(ID_MENU_PASTE_AS_PROJECTED_MAPPING, OnMenuPasteAsProjectedMapping)
- ON_COMMAND(ID_KEY_PASTE_AS_PROJECTED, OnKeyPasteAsProjected)
- ON_COMMAND(ID_SELECT_ALL_ENTITIES, OnSelectAllEntitiesInSectors)
- ON_COMMAND(ID_SELECT_ALL_SECTORS, OnSelectAllSectors)
- ON_COMMAND(ID_LAST_PRIMITIVE, OnLastPrimitive)
- ON_UPDATE_COMMAND_UI(ID_LAST_PRIMITIVE, OnUpdateLastPrimitive)
- ON_COMMAND(ID_CLONE_TO_MORE_PRECISE_MIP, OnCloneToMorePreciseMip)
- ON_COMMAND(ID_CLONE_TO_ROUGHER_MIP_LEVEL, OnCloneToRougherMipLevel)
- ON_COMMAND(ID_CREATE_EMPTY_MORE_PRECISE_MIP, OnCreateEmptyMorePreciseMip)
- ON_COMMAND(ID_CREATE_EMPTY_ROUGHER_MIP, OnCreateEmptyRougherMip)
- ON_UPDATE_COMMAND_UI(ID_CLONE_TO_MORE_PRECISE_MIP, OnUpdateCloneToMorePreciseMip)
- ON_UPDATE_COMMAND_UI(ID_CLONE_TO_ROUGHER_MIP_LEVEL, OnUpdateCloneToRougherMipLevel)
- ON_UPDATE_COMMAND_UI(ID_CREATE_EMPTY_MORE_PRECISE_MIP, OnUpdateCreateEmptyMorePreciseMip)
- ON_UPDATE_COMMAND_UI(ID_CREATE_EMPTY_ROUGHER_MIP, OnUpdateCreateEmptyRougherMip)
- ON_COMMAND(ID_EDIT_PASTE_ALTERNATIVE, OnEditPasteAlternative)
- ON_COMMAND(ID_SELECT_ALL_ENTITIES_IN_WORLD, OnSelectAllEntitiesInWorld)
- ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE_ALTERNATIVE, OnUpdateEditPasteAlternative)
- ON_COMMAND(ID_ENTITY_MODE, OnEntityMode)
- ON_COMMAND(ID_FIND_TEXTURE, OnFindTexture)
- ON_COMMAND(ID_SELECT_SECTORS_WITH_SAME_NAME, OnSelectSectorsWithSameName)
- ON_COMMAND(ID_SELECT_SECTORS_ARROUND_ENTITY, OnSelectSectorsArroundEntity)
- ON_COMMAND(ID_SELECT_SECTORS_ARROUND_ENTITY_ON_CONTEXT, OnSelectSectorsArroundEntityOnContext)
- ON_COMMAND(ID_INSERT_VERTEX, OnInsertVertex)
- ON_COMMAND(ID_DELETE_VERTEX, OnDeleteVertex)
- ON_COMMAND(ID_SAVE_PICTURES_FOR_ENVIRONMENT, OnSavePicturesForEnvironment)
- ON_UPDATE_COMMAND_UI(ID_SAVE_PICTURES_FOR_ENVIRONMENT, OnUpdateSavePicturesForEnvironment)
- ON_WM_ERASEBKGND()
- ON_COMMAND(ID_CSG_SELECT_SECTOR, OnCsgSelectSector)
- ON_COMMAND(ID_MENU_ALIGN_MAPPING_U, OnMenuAlignMappingU)
- ON_COMMAND(ID_MENU_ALIGN_MAPPING_V, OnMenuAlignMappingV)
- ON_WM_DESTROY()
- ON_COMMAND(ID_FALL_DOWN, OnFallDown)
- ON_COMMAND(ID_PREVIOUS, OnPrevious)
- ON_COMMAND(ID_NEXT, OnNext)
- ON_UPDATE_COMMAND_UI(ID_PREVIOUS, OnUpdatePrevious)
- ON_UPDATE_COMMAND_UI(ID_NEXT, OnUpdateNext)
- ON_COMMAND(ID_REMOVE_UNUSED_TEXTURES, OnRemoveUnusedTextures)
- ON_COMMAND(ID_ROTATE, OnRotate)
- ON_COMMAND(ID_ROTATE_BACK, OnRotateBack)
- ON_COMMAND(ID_SELECT_VISIBLE_SECTORS, OnSelectVisibleSectors)
- ON_COMMAND(ID_EDIT_COPY_ALTERNATIVE, OnEditCopyAlternative)
- ON_COMMAND(ID_ROTATE_LEFT, OnRotateLeft)
- ON_COMMAND(ID_ROTATE_RIGHT, OnRotateRight)
- ON_COMMAND(ID_ROTATE_UP, OnRotateUp)
- ON_COMMAND(ID_ROTATE_DOWN, OnRotateDown)
- ON_COMMAND(ID_SELECT_WHO_TARGETS, OnSelectWhoTargets)
- ON_COMMAND(ID_SELECT_INVALIDTRIS, OnSelectInvalidTris)
- ON_COMMAND(ID_TEST_CONNECTIONS_BACK, OnTestConnectionsBack)
- ON_UPDATE_COMMAND_UI(ID_TEST_CONNECTIONS_BACK, OnUpdateTestConnectionsBack)
- ON_WM_MOUSEWHEEL()
- ON_COMMAND(ID_SELECT_SECTORS_OTHER_SIDE, OnSelectSectorsOtherSide)
- ON_COMMAND(ID_SELECT_LINKS_TO_SECTOR, OnSelectLinksToSector)
- ON_COMMAND(ID_REMAIN_SELECTEDBY_ORIENTATION, OnRemainSelectedByOrientation)
- ON_COMMAND(ID_DESELECT_BY_ORIENTATION, OnDeselectByOrientation)
- ON_COMMAND(ID_VERTEX_MODE, OnVertexMode)
- ON_COMMAND(ID_REOPTIMIZE_BRUSHES, OnReoptimizeBrushes)
- ON_COMMAND(ID_MERGE_VERTICES, OnMergeVertices)
- ON_COMMAND(ID_EXPORT_DISPLACE_MAP, OnExportDisplaceMap)
- ON_COMMAND(ID_CUT_MODE, OnCutMode)
- ON_UPDATE_COMMAND_UI(ID_CUT_MODE, OnUpdateCutMode)
- ON_COMMAND(ID_SELECT_ALL_TARGETS, OnSelectAllTargets)
- ON_COMMAND(ID_SELECT_ALL_TARGETS_ON_CONTEXT, OnSelectAllTargetsOnContext)
- ON_COMMAND(ID_SELECT_CLONES, OnSelectClones)
- ON_COMMAND(ID_SELECT_CLONES_ON_CONTEXT, OnSelectClonesOnContext)
- ON_UPDATE_COMMAND_UI(ID_SELECT_CLONES, OnUpdateSelectClones)
- ON_COMMAND(ID_SELECT_ALL_VERTICES, OnSelectAllVertices)
- ON_COMMAND(ID_SELECT_OF_SAME_CLASS, OnSelectOfSameClass)
- ON_COMMAND(ID_SELECT_OF_SAME_CLASS_ON_CONTEXT, OnSelectOfSameClassOnContext)
- ON_COMMAND(ID_ALTERNATIVE_MOVING_MODE, OnAlternativeMovingMode)
- ON_COMMAND(ID_RE_TRIPLE, OnReTriple)
- ON_COMMAND(ID_SELECT_WHO_TARGETS_ON_CONTEXT, OnSelectWhoTargetsOnContext)
- ON_COMMAND(ID_CLEAR_ALL_TARGETS, OnClearAllTargets)
- ON_COMMAND(ID_SELECT_CSG_TARGET, OnSelectCsgTarget)
- ON_UPDATE_COMMAND_UI(ID_SELECT_CSG_TARGET, OnUpdateSelectCsgTarget)
- ON_COMMAND(ID_REMAIN_SELECTEDBY_ORIENTATION_SINGLE, OnRemainSelectedbyOrientationSingle)
- ON_UPDATE_COMMAND_UI(ID_RE_TRIPLE, OnUpdateReTriple)
- ON_COMMAND(ID_TRIANGULARIZE_POLYGON, OnTriangularizePolygon)
- ON_COMMAND(ID_ENTITY_CONTEXT_HELP, OnEntityContextHelp)
- ON_COMMAND(ID_POPUP_AUTO_FIT_MAPPING, OnPopupAutoFitMapping)
- ON_COMMAND(ID_TRIANGULARIZE_SELECTION, OnTriangularizeSelection)
- ON_UPDATE_COMMAND_UI(ID_TRIANGULARIZE_SELECTION, OnUpdateTriangularizeSelection)
- ON_COMMAND(ID_POPUP_AUTO_FIT_MAPPING_SMALL, OnPopupAutoFitMappingSmall)
- ON_COMMAND(ID_POPUP_AUTO_FIT_MAPPING_BOTH, OnPopupAutoFitMappingBoth)
- ON_COMMAND(ID_RESET_MAPPING_OFFSET, OnResetMappingOffset)
- ON_COMMAND(ID_RESET_MAPPING_ROTATION, OnResetMappingRotation)
- ON_COMMAND(ID_RESET_MAPPING_STRETCH, OnResetMappingStretch)
- ON_COMMAND(ID_CROSSROAD_FOR_L, OnCrossroadForL)
- ON_COMMAND(ID_SELECT_USING_TARGET_TREE, OnSelectUsingTargetTree)
- ON_COMMAND(ID_TARGET_TREE, OnTargetTree)
- ON_UPDATE_COMMAND_UI(ID_TARGET_TREE, OnUpdateTargetTree)
- ON_COMMAND(ID_SWAP_LAYERS_12, OnSwapLayers12)
- ON_COMMAND(ID_SWAP_LAYERS_23, OnSwapLayers23)
- ON_COMMAND(ID_SELECT_DESCENDANTS, OnSelectDescendants)
- ON_COMMAND(ID_CROSSROAD_FOR_CTRL_F, OnCrossroadForCtrlF)
- ON_COMMAND(ID_ROTATE_TO_TARGET_CENTER, OnRotateToTargetCenter)
- ON_COMMAND(ID_ROTATE_TO_TARGET_ORIGIN, OnRotateToTargetOrigin)
- ON_COMMAND(ID_COPY_ORIENTATION, OnCopyOrientation)
- ON_COMMAND(ID_COPY_PLACEMENT, OnCopyPlacement)
- ON_COMMAND(ID_COPY_POSITION, OnCopyPosition)
- ON_COMMAND(ID_PASTE_ORIENTATION, OnPasteOrientation)
- ON_COMMAND(ID_PASTE_PLACEMENT, OnPastePlacement)
- ON_COMMAND(ID_PASTE_POSITION, OnPastePosition)
- ON_COMMAND(ID_ALIGN_B, OnAlignB)
- ON_COMMAND(ID_ALIGN_H, OnAlignH)
- ON_COMMAND(ID_ALIGN_P, OnAlignP)
- ON_COMMAND(ID_ALIGN_X, OnAlignX)
- ON_COMMAND(ID_ALIGN_Y, OnAlignY)
- ON_COMMAND(ID_ALIGN_Z, OnAlignZ)
- ON_COMMAND(ID_AUTOTEXTURIZE_MIPS, OnAutotexturizeMips)
- ON_UPDATE_COMMAND_UI(ID_AUTOTEXTURIZE_MIPS, OnUpdateAutotexturizeMips)
- ON_COMMAND(ID_RANDOM_OFFSET_U, OnRandomOffsetU)
- ON_COMMAND(ID_RANDOM_OFFSET_V, OnRandomOffsetV)
- ON_COMMAND(ID_STRETCH_RELATIVE_OFFSET, OnStretchRelativeOffset)
- ON_COMMAND(ID_DESELECT_HIDDEN, OnDeselectHidden)
- ON_COMMAND(ID_SELECT_HIDDEN, OnSelectHidden)
- ON_COMMAND(ID_SECTORS_TO_BRUSH, OnSectorsToBrush)
- ON_COMMAND(ID_POLYGONS_TO_BRUSH, OnPolygonsToBrush)
- ON_COMMAND(ID_CLONE_POLYGONS, OnClonePolygons)
- ON_COMMAND(ID_DELETE_POLYGONS, OnDeletePolygons)
- ON_COMMAND(ID_KEY_U, OnKeyU)
- ON_COMMAND(ID_KEY_D, OnKeyD)
- ON_COMMAND(ID_FLIP_POLYGON, OnFlipPolygon)
- ON_COMMAND(ID_TERRAIN_MODE, OnTerrainMode)
- ON_UPDATE_COMMAND_UI(ID_TERRAIN_MODE, OnUpdateTerrainMode)
- ON_COMMAND(ID_KEY_M, OnKeyM)
- ON_COMMAND(ID_KEY_BACKSLASH, OnKeyBackslash)
- ON_COMMAND(ID_SELECT_BRUSH, OnSelectBrush)
- ON_COMMAND(ID_SELECT_TERRAIN, OnSelectTerrain)
- ON_COMMAND(ID_ALTITUDE_EDIT_MODE, OnAltitudeEditMode)
- ON_COMMAND(ID_LAYER_TEXTURE_EDIT_MODE, OnLayerTextureEditMode)
- ON_COMMAND(ID_TBRUSH_ALTITUDE, OnTbrushAltitude)
- ON_COMMAND(ID_TBRUSH_EQUILAZE, OnTbrushEquilaze)
- ON_COMMAND(ID_TBRUSH_ERASE, OnTbrushErase)
- ON_COMMAND(ID_TBRUSH_NOISE, OnTbrushNoise)
- ON_COMMAND(ID_TBRUSH_SMOOTH, OnTbrushSmooth)
- ON_COMMAND(ID_OPTIMIZE_TERRAIN, OnOptimizeTerrain)
- ON_COMMAND(ID_RECALCULATE_TERRAIN_SHADOWS, OnRecalculateTerrainShadows)
- ON_COMMAND(ID_VIEW_HEIGHTMAP, OnViewHeightmap)
- ON_COMMAND(ID_IMPORT_HEIGHTMAP, OnImportHeightmap)
- ON_COMMAND(ID_EXPORT_HEIGHTMAP, OnExportHeightmap)
- ON_COMMAND(ID_IMPORT_HEIGHTMAP16, OnImportHeightmap16)
- ON_COMMAND(ID_EXPORT_HEIGHTMAP16, OnExportHeightmap16)
- ON_COMMAND(ID_SELECT_LAYER, OnSelectLayer)
- ON_COMMAND(ID_PICK_LAYER, OnPickLayer)
- ON_COMMAND(ID_KEY_O, OnKeyO)
- ON_UPDATE_COMMAND_UI(ID_KEY_O, OnUpdateKeyO)
- ON_COMMAND(ID_POSTERIZE, OnPosterize)
- ON_COMMAND(ID_EQUILIZE, OnFlatten)
- ON_COMMAND(ID_APPLY_FILTER, OnApplyFilter)
- ON_COMMAND(ID_TE_SMOOTH, OnTeSmooth)
- ON_COMMAND(ID_EDIT_TERRAIN_PREFS, OnEditTerrainPrefs)
- ON_UPDATE_COMMAND_UI(ID_EDIT_TERRAIN_PREFS, OnUpdateEditTerrainPrefs)
- ON_COMMAND(ID_KEY_CTRL_SHIFT_E, OnKeyCtrlShiftE)
- ON_COMMAND(ID_KEY_CTRL_SHIFT_G, OnKeyCtrlShiftG)
- ON_UPDATE_COMMAND_UI(ID_KEY_CTRL_SHIFT_G, OnUpdateKeyCtrlShiftG)
- ON_COMMAND(ID_TERRAIN_LAYER_OPTIONS, OnTerrainLayerOptions)
- ON_UPDATE_COMMAND_UI(ID_TERRAIN_LAYER_OPTIONS, OnUpdateTerrainLayerOptions)
- ON_COMMAND(ID_KEY_CTRL_SHIFT_K, OnKeyCtrlShiftK)
- ON_COMMAND(ID_APPLY_CONTINOUS_NOISE, OnApplyContinousNoise)
- ON_COMMAND(ID_APPLY_MINIMUM, OnApplyMinimum)
- ON_COMMAND(ID_APPLY_MAXIMUM, OnApplyMaximum)
- ON_COMMAND(ID_APPLY_FLATTEN, OnApplyFlatten)
- ON_COMMAND(ID_APPLY_POSTERIZE, OnApplyPosterize)
- ON_COMMAND(ID_OPTIMIZE_LAYERS, OnOptimizeLayers)
- ON_COMMAND(ID_TBRUSH_CONTINOUS_NOISE, OnTbrushContinousNoise)
- ON_COMMAND(ID_TBRUSH_FILTER, OnTbrushFilter)
- ON_COMMAND(ID_TBRUSH_FLATTEN, OnTbrushFlatten)
- ON_COMMAND(ID_TBRUSH_MAXIMUM, OnTbrushMaximum)
- ON_COMMAND(ID_TBRUSH_MINIMUM, OnTbrushMinimum)
- ON_COMMAND(ID_TBRUSH_POSTERIZE, OnTbrushPosterize)
- ON_COMMAND(ID_TERRAIN_PROPERTIES, OnTerrainProperties)
- //}}AFX_MSG_MAP
- ON_COMMAND_RANGE(ID_BUFFER01, ID_BUFFER10, OnKeyBuffer)
- ON_COMMAND_RANGE(ID_EDIT_BUFFER01, ID_EDIT_BUFFER10, OnKeyEditBuffer)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CWorldEditorView construction/destruction
- CWorldEditorView::CWorldEditorView()
- {
- m_iaInputAction = IA_NONE;
- m_iaLastInputAction=IA_NONE;
- m_pbpoTranslationPlane = NULL;
- m_vpViewPrefs = theApp.m_vpViewPrefs[ 0];
- m_ptProjectionType = CSlaveViewer::PT_PERSPECTIVE;
- m_pdpDrawPort = NULL;
- m_pvpViewPort = NULL;
- m_fGridInMeters = 10.0f;
- m_pbpoRightClickedPolygon = NULL;
- m_penEntityHitOnContext = NULL;
- m_iDragVertice = -1;
- m_iDragEdge = -1;
- _pselbvxtSelectOnRender = NULL;
- _pselenSelectOnRender = NULL;
- m_bRequestVtxClickSelect = FALSE;
- m_bRequestVtxLassoSelect = FALSE;
- m_bRequestEntityLassoSelect = FALSE;
- m_strTest="";
- }
- CWorldEditorView::~CWorldEditorView()
- {
- }
- BOOL CWorldEditorView::PreCreateWindow(CREATESTRUCT& cs)
- {
- // TODO: Modify the Window class or styles here by modifying
- // the CREATESTRUCT cs
- return CView::PreCreateWindow(cs);
- }
- static void GetToolTipText(void *pView, char *pToolTipText)
- {
- CWorldEditorView *pWorldEditorView = (CWorldEditorView *) pView;
- pWorldEditorView->GetToolTipText( pToolTipText);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CWorldEditorView drawing
- void CWorldEditorView::RenderBackdropTexture(CDrawPort *pDP,
- FLOAT3D v0, FLOAT3D v1, FLOAT3D v2, FLOAT3D v3,
- CTextureObject &to)
- {
- if( to.GetData() == NULL) return;
- CWorldEditorDoc* pDoc = GetDocument();
- FLOAT3D v0p, v1p, v2p, v3p;
- // create a slave viewer
- CSlaveViewer svViewer(GetChildFrame()->m_mvViewer, m_ptProjectionType, pDoc->m_plGrid, pDP);
- // create a projection for slave viewer
- CAnyProjection3D prProjection;
- svViewer.MakeProjection(prProjection);
- prProjection->Prepare();
- // project current base vertice and convert y coordinate from mathemathical representation
- // into screen representation
- prProjection->ProjectCoordinate( v0, v0p); v0p(2) = pDP->GetHeight() - v0p(2);
- prProjection->ProjectCoordinate( v1, v1p); v1p(2) = pDP->GetHeight() - v1p(2);
- prProjection->ProjectCoordinate( v2, v2p); v2p(2) = pDP->GetHeight() - v2p(2);
- prProjection->ProjectCoordinate( v3, v3p); v3p(2) = pDP->GetHeight() - v3p(2);
- FLOATaabbox3D box;
- box |= v0p;
- box |= v1p;
- box |= v2p;
- box |= v3p;
- if( (box.Size()(1) > 2) && (box.Size()(2) > 2) )
- {
- // create rectangle for backdrop picture
- PIXaabbox2D rectPict;
- rectPict = PIXaabbox2D( PIX2D((SLONG)box.Min()(1), (SLONG)box.Min()(2)),
- PIX2D((SLONG)box.Max()(1), (SLONG)box.Max()(2)) );
- pDP->PutTexture( &to, rectPict);
- }
- }
- BOOL _bCursorMoved=FALSE;
- void CWorldEditorView::RenderView( CDrawPort *pDP)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CChildFrame *pChild = GetChildFrame();
- BOOL bCSGOn = pDoc->m_pwoSecondLayer != NULL;
- BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0;
- BOOL bSpace = (GetKeyState( VK_SPACE)&0x8000) != 0;
- BOOL bCtrl = (GetKeyState( VK_CONTROL)&0x8000) != 0;
- // create a slave viewer
- CSlaveViewer svViewer(GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pDP);
- // copy view's world rendering preferences to global world rendering preferences
- _wrpWorldRenderPrefs = m_vpViewPrefs.m_wrpWorldRenderPrefs;
- _wrpWorldRenderPrefs.SetTextureLayerOn( theApp.m_bTexture1, 0);
- _wrpWorldRenderPrefs.SetTextureLayerOn( theApp.m_bTexture2, 1);
- _wrpWorldRenderPrefs.SetTextureLayerOn( theApp.m_bTexture3, 2);
- // set shadow type from child frame
- _wrpWorldRenderPrefs.SetShadowsType( GetChildFrame()->m_stShadowType);
- // copy view's model rendering preferences to global model rendering preferences
- _mrpModelRenderPrefs = m_vpViewPrefs.m_mrpModelRenderPrefs;
- // copy auto mip modeling flag from child frame
- _wrpWorldRenderPrefs.SetAutoMipBrushingOn( GetChildFrame()->m_bAutoMipBrushingOn);
- // and manual mip factor
- _wrpWorldRenderPrefs.SetManualMipBrushingFactor( GetChildFrame()->m_fManualMipBrushingFactor);
- // view visibility tweaking
- _wrpWorldRenderPrefs.SetVisTweaksOn(GetChildFrame()->m_bShowVisibilityTweaks);
- _wrpWorldRenderPrefs.DisableVisTweaks(GetChildFrame()->m_bDisableVisibilityTweaks);
- _pselbscVisTweaks=&pDoc->m_selSectorSelection;
- _wrpWorldRenderPrefs.SetSelectedEntityModel( theApp.m_pEntityMarkerModelObject);
- _wrpWorldRenderPrefs.SetSelectedPortalModel( theApp.m_pPortalMarkerModelObject);
- _wrpWorldRenderPrefs.SetEmptyBrushModel( theApp.m_pEmptyBrushModelObject);
- // if we are using automatic rendering range
- if( m_vpViewPrefs.m_bAutoRenderingRange)
- {
- // set rendering range of 1.5 x viewer's target distance
- FLOAT fTargetDistance = svViewer.GetTargetDistance();
- // we have to take second layer distance in considiration also
- FLOAT fMinimumRenderRange = fTargetDistance;
- // if second layer's world exists
- if( pDoc->m_pwoSecondLayer != NULL)
- {
- CPlacement3D plViewer = GetChildFrame()->m_mvViewer.GetViewerPlacement();
- // calculate viewer-layer distance
- FLOAT fViewerLayerDistance =
- (plViewer.pl_PositionVector - pDoc->m_plSecondLayer.pl_PositionVector).Length();
- // if current minimum rendering range is smaller than one that viewer-layer
- // distance would request
- if( fMinimumRenderRange < fViewerLayerDistance )
- {
- fMinimumRenderRange = fViewerLayerDistance;
- }
- }
- // don't allow minimum rendering range to drop below 1.5 m
- if( fMinimumRenderRange < 1.5f)
- {
- fMinimumRenderRange = 1.5f;
- }
- _wrpWorldRenderPrefs.SetMinimumRenderRange( fMinimumRenderRange * 1.5f);
- }
- // we are using fixed rendering range
- else
- {
- // set global rendering range from fixed one remembered in prefs
- _wrpWorldRenderPrefs.SetMinimumRenderRange( m_vpViewPrefs.m_fRenderingRange);
- }
- // set visibility of link lines
- _wrpWorldRenderPrefs.SetShowTargetsOn(pChild->m_bShowTargets);
- // set visibility of entity names
- _wrpWorldRenderPrefs.SetShowEntityNamesOn(pChild->m_bShowEntityNames);
- // find out if z buffer clearing should occure
- BOOL bClearZBuffer = FALSE;
- BOOL bClearScreen = TRUE;
- // get world and model polygon fill flags
- BOOL bModelPolygonFilling =
- (_mrpModelRenderPrefs.GetRenderType() & RT_TEXTURE_MASK) != RT_NO_POLYGON_FILL;
- // find out if any of isometric projection modes is currently on
- BOOL bPerspectiveOn = m_ptProjectionType == CSlaveViewer::PT_PERSPECTIVE;
- BOOL bPolygonFillOn = _wrpWorldRenderPrefs.GetPolygonsFillType() != CWorldRenderPrefs::FT_NONE;
- // if something requires clearing of z-buffer
- if( bPolygonFillOn ||
- pDoc->m_bOrientationIcons ||
- ((!bCSGOn && bPerspectiveOn) && GetChildFrame()->m_bSceneRenderingTime) ||
- m_vpViewPrefs.m_bMeasurementTape ||
- theApp.m_bMeasureModeOn || theApp.m_bCutModeOn)
- {
- bClearZBuffer = TRUE;
- }
- // if we will render models using polygon fill, we must clear z-buffer
- if( bModelPolygonFilling)
- {
- bClearZBuffer = TRUE;
- }
- // if rendering will fill whole screen along with z-buffer
- if( bPolygonFillOn && bPerspectiveOn)
- {
- bClearZBuffer = FALSE;
- bClearScreen = FALSE;
- }
- COLOR colBcgFill=m_vpViewPrefs.m_PaperColor;
- if(_wrpWorldRenderPrefs.IsBackgroundTextureOn())
- {
- bClearScreen = TRUE;
- colBcgFill=pDoc->m_woWorld.wo_colBackground;
- }
- // set selected entity model
- _wrpWorldRenderPrefs.SetSelectedEntityModel( theApp.m_pEntityMarkerModelObject);
- // set selected portal model
- _wrpWorldRenderPrefs.SetSelectedPortalModel( theApp.m_pPortalMarkerModelObject);
- // set empty brush model
- _wrpWorldRenderPrefs.SetEmptyBrushModel( theApp.m_pEmptyBrushModelObject);
- switch( pDoc->GetEditingMode())
- {
- case POLYGON_MODE:
- {
- _wrpWorldRenderPrefs.SetSelectionType( CWorldRenderPrefs::ST_POLYGONS);
- break;
- }
- case SECTOR_MODE:
- {
- _wrpWorldRenderPrefs.SetSelectionType( CWorldRenderPrefs::ST_SECTORS);
- break;
- }
- case ENTITY_MODE:
- {
- _wrpWorldRenderPrefs.SetSelectionType( CWorldRenderPrefs::ST_ENTITIES);
- break;
- }
- case VERTEX_MODE:
- {
- _wrpWorldRenderPrefs.SetSelectionType( CWorldRenderPrefs::ST_VERTICES);
- break;
- }
- case TERRAIN_MODE:
- {
- _wrpWorldRenderPrefs.SetSelectionType( CWorldRenderPrefs::ST_NONE);
- break;
- }
- case CSG_MODE:
- {
- _wrpWorldRenderPrefs.SetSelectionType( CWorldRenderPrefs::ST_NONE);
- break;
- }
- default: { FatalError("Unknown editing mode."); break;};
- }
- // if selection shouldn't be rendered and we are not in vertex mode (selection should always be rendered)
- if( !GetChildFrame()->m_bSelectionVisible && (pDoc->GetEditingMode()!= VERTEX_MODE) )
- {
- _wrpWorldRenderPrefs.SetSelectionType( CWorldRenderPrefs::ST_NONE);
- }
- // create a projection for slave viewer
- CAnyProjection3D prProjection;
- svViewer.MakeProjection(prProjection);
- // set object placement
- prProjection->ObjectPlacementL() = pDoc->m_plGrid;
- if( !bPerspectiveOn && !_wrpWorldRenderPrefs.wrp_bApplyFarClipPlaneInIsometricProjection)
- {
- prProjection->FarClipDistanceL() = -1;
- }
- else
- {
- prProjection->FarClipDistanceL() = _wrpWorldRenderPrefs.wrp_fFarClipPlane;
- }
- // prepare the projection
- prProjection->Prepare();
- // if screen clearance is required
- if( bClearScreen)
- {
- try
- {
- m_toBcgPicture.SetData_t(CTString(m_vpViewPrefs.m_achrBcgPicture));
- }
- // if failed
- catch (char *strError)
- {
- (void) strError;
- }
- if( m_toBcgPicture.GetData() != NULL)
- {
- // fill background with bcg picture
- PIXaabbox2D screenBox;
- screenBox = PIXaabbox2D( PIX2D(0,0), PIX2D(pDP->GetWidth(), pDP->GetHeight()) );
- pDP->PutTexture( &m_toBcgPicture, screenBox);
- }
- else
- {
- // clear background using current color form rendering preferences
- pDP->Fill(colBcgFill | CT_OPAQUE);
- }
- if( pDoc->m_woWorld.wo_strBackdropUp != "" && GetChildFrame()->m_bRenderViewPictures)
- {
- FLOAT3D v0 = FLOAT3D(pDoc->m_woWorld.wo_fUpCX-pDoc->m_woWorld.wo_fUpW/2.0f, 0.0f,
- pDoc->m_woWorld.wo_fUpCZ-pDoc->m_woWorld.wo_fUpL/2.0f);
- FLOAT3D v1 = FLOAT3D(pDoc->m_woWorld.wo_fUpCX+pDoc->m_woWorld.wo_fUpW/2.0f, 0.0f,
- pDoc->m_woWorld.wo_fUpCZ-pDoc->m_woWorld.wo_fUpL/2.0f);
- FLOAT3D v2 = FLOAT3D(pDoc->m_woWorld.wo_fUpCX+pDoc->m_woWorld.wo_fUpW/2.0f, 0.0f,
- pDoc->m_woWorld.wo_fUpCZ+pDoc->m_woWorld.wo_fUpL/2.0f);
- FLOAT3D v3 = FLOAT3D(pDoc->m_woWorld.wo_fUpCX-pDoc->m_woWorld.wo_fUpW/2.0f, 0.0f,
- pDoc->m_woWorld.wo_fUpCZ+pDoc->m_woWorld.wo_fUpL/2.0f);
- RenderBackdropTexture( pDP, v0, v1, v2, v3, pDoc->m_toBackdropUp);
- }
- if( pDoc->m_woWorld.wo_strBackdropFt != "" && GetChildFrame()->m_bRenderViewPictures)
- {
- FLOAT3D v0 = FLOAT3D(pDoc->m_woWorld.wo_fFtCX-pDoc->m_woWorld.wo_fFtW/2.0f,
- pDoc->m_woWorld.wo_fFtCY-pDoc->m_woWorld.wo_fFtH/2.0f, 0.0f);
- FLOAT3D v1 = FLOAT3D(pDoc->m_woWorld.wo_fFtCX+pDoc->m_woWorld.wo_fFtW/2.0f,
- pDoc->m_woWorld.wo_fFtCY-pDoc->m_woWorld.wo_fFtH/2.0f, 0.0f);
- FLOAT3D v2 = FLOAT3D(pDoc->m_woWorld.wo_fFtCX+pDoc->m_woWorld.wo_fFtW/2.0f,
- pDoc->m_woWorld.wo_fFtCY+pDoc->m_woWorld.wo_fFtH/2.0f, 0.0f);
- FLOAT3D v3 = FLOAT3D(pDoc->m_woWorld.wo_fFtCX-pDoc->m_woWorld.wo_fFtW/2.0f,
- pDoc->m_woWorld.wo_fFtCY+pDoc->m_woWorld.wo_fFtH/2.0f, 0.0f);
- RenderBackdropTexture( pDP, v0, v1, v2, v3, pDoc->m_toBackdropFt);
- }
- if( pDoc->m_woWorld.wo_strBackdropRt != "" && GetChildFrame()->m_bRenderViewPictures)
- {
- FLOAT3D v0 = FLOAT3D(0.0f, pDoc->m_woWorld.wo_fRtCY-pDoc->m_woWorld.wo_fRtH/2.0f,
- pDoc->m_woWorld.wo_fRtCZ-pDoc->m_woWorld.wo_fRtL/2.0f);
- FLOAT3D v1 = FLOAT3D(0.0f, pDoc->m_woWorld.wo_fRtCY+pDoc->m_woWorld.wo_fRtH/2.0f,
- pDoc->m_woWorld.wo_fRtCZ-pDoc->m_woWorld.wo_fRtL/2.0f);
- FLOAT3D v2 = FLOAT3D(0.0f, pDoc->m_woWorld.wo_fRtCY+pDoc->m_woWorld.wo_fRtH/2.0f,
- pDoc->m_woWorld.wo_fRtCZ+pDoc->m_woWorld.wo_fRtL/2.0f);
- FLOAT3D v3 = FLOAT3D(0.0f, pDoc->m_woWorld.wo_fRtCY-pDoc->m_woWorld.wo_fRtH/2.0f,
- pDoc->m_woWorld.wo_fRtCZ+pDoc->m_woWorld.wo_fRtL/2.0f);
- RenderBackdropTexture( pDP, v0, v1, v2, v3, pDoc->m_toBackdropRt);
- }
- // if object should me rendered as backdrop
- if( GetChildFrame()->m_bRenderViewPictures)
- {
- CObject3D &ob = pDoc->m_o3dBackdropObject;
- FOREACHINDYNAMICARRAY(ob.ob_aoscSectors, CObjectSector, itosc)
- {
- FOREACHINDYNAMICARRAY(itosc->osc_aoedEdges, CObjectEdge, itoe)
- {
- FLOAT3D vtx0 = DOUBLEtoFLOAT(*itoe->oed_Vertex0);
- FLOAT3D vtx1 = DOUBLEtoFLOAT(*itoe->oed_Vertex1);
- prProjection->PreClip( vtx0, vtx0);
- prProjection->PreClip( vtx1, vtx1);
- prProjection->ClipLine(vtx0, vtx1);
- // apply perspective
- FLOAT3D vtx0p, vtx1p;
- prProjection->PostClip( vtx0, vtx0p);
- prProjection->PostClip( vtx1, vtx1p);
- // draw one line of bounding box
- pDP->DrawLine( (PIX)vtx0p(1), (PIX)vtx0p(2), (PIX)vtx1p(1), (PIX)vtx1p(2),
- C_dGRAY|CT_OPAQUE);
- }
- }
- }
- }
- // if z-buffer clearance is required
- if( bClearZBuffer)
- {
- // erase z-buffer
- pDP->FillZBuffer(ZBUF_BACK);
- }
- FLOAT3D fGridOrigin;
- // project grid origin
- prProjection->ProjectCoordinate( FLOAT3D( 0.0f, 0.0f, 0.0f), fGridOrigin);
- // convert y coordinate form mathematical form info screen space
- fGridOrigin(2) = pDP->GetHeight() - fGridOrigin(2);
- // calculate grid in pixels but there must be bigger than given minimal size
- #define SMALLEST_ALLOWED_GRID_IN_PIXELS 30
- // get zoom factor
- FLOAT fZoom = svViewer.GetZoomFactor();
- // declare decadic grid in meters
- FLOAT afDecadicGridInMeters[] = {0.25f,0.50f,1.0f,2.5f,5.0f,10.0f,25.0f,50.0f,100.0f,
- 250.0f,500.0f,1000.0f,10000.0f,100000.0f};
- FLOAT afBinaryGridInMeters[] = {0.25f,0.50f,1.0f,2.0f,4.0f,8.0f,16.0f,32.0f,64.0f,128.0f,256.0f,
- 512.0f,1024.0f,2048.0f,4096.0f,8192.0f,16384.0f,32768.0f,65536.0f};
- // select max grid value
- if( theApp.m_bDecadicGrid)
- {
- m_fGridInMeters = afDecadicGridInMeters[ sizeof( afDecadicGridInMeters)/sizeof(FLOAT)-1];
- }
- else
- {
- m_fGridInMeters = afBinaryGridInMeters[ sizeof( afBinaryGridInMeters)/sizeof(FLOAT)-1];
- }
- // ptr to curently active grid table
- FLOAT *pafGridInMeters;
- INDEX ctTableMembers;
- // select active table
- if( theApp.m_bDecadicGrid)
- {
- pafGridInMeters = afDecadicGridInMeters;
- ctTableMembers = sizeof( afDecadicGridInMeters)/sizeof(FLOAT);
- }
- else
- {
- pafGridInMeters = afBinaryGridInMeters;
- ctTableMembers = sizeof( afBinaryGridInMeters)/sizeof(FLOAT);
- }
- // for all members in precalculated grid in meters array
- for( INDEX i=0; i<ctTableMembers; i++)
- {
- // calculate grid steep
- m_fpixGridSteep = fZoom * pafGridInMeters[ i];
- // is it bigger than smallest allowed grid size in pixels
- if( m_fpixGridSteep >= SMALLEST_ALLOWED_GRID_IN_PIXELS)
- {
- m_fGridInMeters = pafGridInMeters[ i];
- break;
- }
- }
- // we have calculated wanted grid in pixels, value is stored in pixGridSteep
- // if grid on, draw it
- if( GetChildFrame()->m_bGridOn && !bPerspectiveOn && !bPolygonFillOn)
- {
- // get grid's origin projected point
- FLOAT fGridOriginX = fGridOrigin(1);
- FLOAT fGridOriginY = fGridOrigin(2);
- // calculate starting coordinates of left-up grid line
- FLOAT fGridX = fGridOriginX - (m_fpixGridSteep * (int)(fGridOriginX / m_fpixGridSteep));
- FLOAT fGridY = fGridOriginY - (m_fpixGridSteep * (int)(fGridOriginY / m_fpixGridSteep));
- // remember these start grid values so they can be used for measurement
- m_fGridX = fGridX;
- m_fGridY = fGridY;
- // style of grid line
- ULONG ulLineStyle;
- // loop all vertical grid lines
- #define LINE_EPSILON 0.05f
- FOREVER
- {
- // does this grid lines touch origin point
- if( Abs(fGridX - fGridOriginX) < LINE_EPSILON )
- {
- // if so, draw full line
- ulLineStyle = _FULL_;
- }
- else
- {
- // does not, draw point line
- ulLineStyle = _POINT_;
- }
- // draw one vertical grid line
- pDP->DrawLine( (int) fGridX, 0, (int) fGridX, pDP->GetHeight()-1,
- m_vpViewPrefs.m_GridColor|CT_OPAQUE, ulLineStyle);
- // move to next grid line
- fGridX += m_fpixGridSteep;
- // is coordinate passed draw port's width
- if( fGridX > pDP->GetWidth())
- {
- // if so, vertical grid is drawn, stop endless loop
- break;
- }
- }
- // loop all horizontal grid lines
- FOREVER
- {
- // does this grid lines touch origin point
- if( Abs(fGridY - fGridOriginY) < LINE_EPSILON )
- {
- // if so, draw full line
- ulLineStyle = _FULL_;
- }
- else
- {
- // does not, draw point line
- ulLineStyle = _POINT_;
- }
- // draw one vertical grid line
- pDP->DrawLine( 0, (int) fGridY, pDP->GetWidth()-1, (int) fGridY,
- m_vpViewPrefs.m_GridColor|CT_OPAQUE, ulLineStyle);
- // move to next grid line
- fGridY += m_fpixGridSteep;
- // is coordinate passed draw port's height
- if( fGridY > pDP->GetHeight())
- {
- // if so, vertical grid is drawn, stop endless loop
- break;
- }
- }
- }
- // if we should draw measurement tape
- if( m_vpViewPrefs.m_bMeasurementTape && !bPerspectiveOn)
- {
- // define tape in meters for decadic grid type
- FLOAT afDecadicTapeInMeters[] =
- { 0.01f, 0.1f, 1.0f, 10.0f, 100.0f, 1000.0f, 10000.0f, 100000.0f};
- CTString astrDecadicTapeInMeters[] =
- { "1 mm", "1 cm", "1 m", "10 m", "100 m", "1 km", "10 km", "100 km"};
- // define tape in meters for binary grid type
- FLOAT afBinaryTapeInMeters[] =
- { 1.0f/64, 1.0f/8, 1.0f, 8.0f, 64.0f, 256.0f, 1024.0f, 4096.0f, 16484.0f, 65536.0f};
- CTString astrBinaryTapeInMeters[] =
- { "1/64 m", "1/8 m", "1 m", "8 m", "64 m", "256 m", "1024 m", "4096 m", "16384 m", "65536 m"};
- CTString *pastrTapeInMetersTable;
- FLOAT *pafTapeInMetersTable;
- INDEX ctTableMembers;
- // select active table
- if( theApp.m_bDecadicGrid)
- {
- pafTapeInMetersTable = afDecadicTapeInMeters;
- pastrTapeInMetersTable = astrDecadicTapeInMeters;
- ctTableMembers = sizeof( afDecadicTapeInMeters)/sizeof(FLOAT);
- }
- else
- {
- pafTapeInMetersTable = afBinaryTapeInMeters;
- pastrTapeInMetersTable = astrBinaryTapeInMeters;
- ctTableMembers = sizeof( afBinaryTapeInMeters)/sizeof(FLOAT);
- }
- // here we will calculate our tape lenght in meters
- FLOAT fTapeLenMeters;
- // here we will calculate our tape lenght in pixels
- PIX pixTapeLen;
- // here we will place appropriate text saying tape's lenght in meters
- CTString strTapeLen;
- // for all possible dimensions of measurement tape
- for( INDEX i=ctTableMembers-1; i>=0; i--)
- {
- // get tape len in meters
- fTapeLenMeters = pafTapeInMetersTable[ i];
- // get appropriate descriptive string
- strTapeLen = pastrTapeInMetersTable[ i];
- // calculate tape in pixels
- pixTapeLen = (PIX)(fZoom * fTapeLenMeters);
- // is it smaller than 75% of draw port's width
- if( pixTapeLen <= pDP->GetWidth()*3/4)
- {
- // it is, we found our tape dimension
- break;
- }
- }
- // calculate tape position on screen
- PIX x = (PIX) ( pDP->GetWidth() * 0.05f); // x starts at 5% of draw port's width
- PIX y = (PIX) ( pDP->GetHeight()* 0.95f); // y starts at 95% of draw port's height
- // draw tape's left end, little vertical line
- pDP->DrawLine( x, y-2, x, y+2, C_BLACK|CT_OPAQUE);
- // draw tape's main, horizontal little
- pDP->DrawLine( x, y, x+pixTapeLen, y, C_BLACK|CT_OPAQUE);
- // draw tape's right end, little vertical line
- pDP->DrawLine( x+pixTapeLen, y-2, x+pixTapeLen, y+2, C_BLACK|CT_OPAQUE);
- // type appropriate text, lenght in meters
- pDP->SetFont( theApp.m_pfntSystem);
- pDP->SetTextAspect( 1.0f);
- pDP->SetTextScaling( 1.0f);
- pDP->PutText( strTapeLen, x, y-16);
- }
- // we are not rendering scene over already rendered scene (used for CSG layer)
- pDP->SetOverlappedRendering(FALSE);
- // print grid size (or no grid)
- char strPaneText[ 128];
- sprintf( strPaneText, "Grid: %g m", m_fGridInMeters);
- pMainFrame->m_wndStatusBar.SetPaneText( GRID_PANE, CString(strPaneText), TRUE);
- // create renderer and render world
- CEntity *penOnlySelected = NULL;
- if( pDoc->m_selEntitySelection.Count() == 1)
- {
- pDoc->m_selEntitySelection.Lock();
- penOnlySelected = &pDoc->m_selEntitySelection[0];
- pDoc->m_selEntitySelection.Unlock();
- }
- // request vertex selecting from renderer
- if( m_bRequestVtxClickSelect)
- {
- _bSelectAlternative = m_bOnSelectVertexShiftDown;
- _pselbvxtSelectOnRender = &pDoc->m_selVertexSelection;
- }
- if( m_bRequestVtxLassoSelect)
- {
- _bSelectAlternative = m_bOnSelectVertexAltDown;
- _pselbvxtSelectOnRender = &pDoc->m_selVertexSelection;
- _pavpixSelectLasso = &m_avpixLaso;
- }
- if( m_bRequestEntityLassoSelect)
- {
- _bSelectAlternative = m_bOnSelectEntityAltDown;
- _pselenSelectOnRender = &pDoc->m_selEntitySelection;
- _pavpixSelectLasso = &m_avpixLaso;
- }
- if(pDoc->GetEditingMode()==TERRAIN_MODE &&
- theApp.m_penLastTerrainHit==GetTerrainEntity() &&
- !_pInput->IsInputEnabled())
- {
- RenderAndApplyTerrainEditBrush(theApp.m_vLastTerrainHit);
- }
-
- if( GetChildFrame()->m_bViewFromEntity &&
- (penOnlySelected != NULL) &&
- !(penOnlySelected->GetFlags()&ENF_ANCHORED) &&
- bPerspectiveOn )
- {
- // create a projection for slave viewer
- CAnyProjection3D prProjection;
- svViewer.MakeProjection(prProjection);
- prProjection->ViewerPlacementL() = penOnlySelected->GetPlacement();
- prProjection->Prepare();
- ::RenderView(pDoc->m_woWorld, *penOnlySelected, prProjection, *pDP);
- }
- else
- {
- // create renderer and render world
- ::RenderView(pDoc->m_woWorld, *(CEntity*) NULL, prProjection, *pDP);
- }
-
- // don't allow further laso select tests
- if( m_bRequestVtxLassoSelect || m_bRequestEntityLassoSelect)
- {
- m_avpixLaso.Clear();
- }
- _pselbvxtSelectOnRender = NULL;
- _pselenSelectOnRender = NULL;
- m_bRequestVtxClickSelect = FALSE;
- m_bRequestVtxLassoSelect = FALSE;
- m_bRequestEntityLassoSelect = FALSE;
- _pavpixSelectLasso = NULL;
- INDEX ctLasoPts = m_avpixLaso.Count();
- if(((m_iaInputAction == IA_SELECT_LASSO_BRUSH_VERTEX) ||
- (m_iaInputAction == IA_SELECT_LASSO_ENTITY)) && (ctLasoPts>1) )
- {
- for( INDEX iKnot=0; iKnot<ctLasoPts-1; iKnot++)
- {
- PIX x0 = m_avpixLaso[iKnot](1);
- PIX x1 = m_avpixLaso[iKnot+1](1);
- PIX y0 = m_avpixLaso[iKnot](2);
- PIX y1 = m_avpixLaso[iKnot+1](2);
- pDP->DrawLine(x0, y0, x1, y1, m_vpViewPrefs.m_GridColor|CT_OPAQUE);
- }
- }
- prProjection->DepthBufferNearL() = 0.0f;
- prProjection->DepthBufferFarL() = 0.9f;
- prProjection->Prepare();
- BeginModelRenderingView(prProjection, pDP);
- // if we have entity mode active, at least one entity selected and edititng property of
- // edit range type, and perspective is not on, render entities using rendering range model
- CPropertyID *ppidProperty = pMainFrame->m_PropertyComboBar.GetSelectedProperty();
- if( (pDoc->GetEditingMode() == ENTITY_MODE) &&
- (pDoc->m_selEntitySelection.Count() != 0) &&
- (ppidProperty != NULL) &&
- ( (ppidProperty->pid_eptType == CEntityProperty::EPT_ANGLE3D) ||
- (ppidProperty->pid_eptType == CEntityProperty::EPT_RANGE) ||
- (ppidProperty->pid_eptType == CEntityProperty::EPT_FLOATAABBOX3D && !bPerspectiveOn)) )
- {
- // for all selected entities
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- // obtain property ptr
- CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
- // if this entity is just selected, it may not have range property but that was not
- // noticed (it will be during first on idle), so skip it
- if( penpProperty==NULL)
- {
- continue;
- }
- // if we are in perspective and entity property is marked not to be visible in perspective view
- if( (penpProperty->ep_ulFlags & EPROPF_HIDEINPERSPECTIVE) && bPerspectiveOn)
- {
- continue;
- }
- // this model we will render
- CModelObject *pModelObject;
- // this render model structure will be rendered
- CRenderModel rmRenderModel;
- // if we are editing range property
- if( ppidProperty->pid_eptType == CEntityProperty::EPT_RANGE)
- {
- // get editing range
- FLOAT fRange = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOAT);
- // set collision box's stretch factor
- theApp.m_pRangeSphereModelObject->mo_Stretch = FLOAT3D( fRange, fRange, fRange);
- // set texture rendering mode and phong shading
- //_mrpModelRenderPrefs.SetRenderType( RT_TEXTURE|RT_SHADING_PHONG);
- // copy range model's placement from entity
- rmRenderModel.SetObjectPlacement(iten->GetPlacement());
- // set range sphere model for rendering
- pModelObject = theApp.m_pRangeSphereModelObject;
- }
- // if we are editing angle3D property
- else if( ppidProperty->pid_eptType == CEntityProperty::EPT_ANGLE3D)
- {
- // get editting bounding box
- ANGLE3D aAngle = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ANGLE3D);
- rmRenderModel.SetObjectPlacement(
- CPlacement3D(iten->GetPlacement().pl_PositionVector, aAngle));
- // set angle3d vector's stretch factor
- FLOATaabbox3D box;
- iten->GetSize(box);
- FLOAT fStretch = box.Size().Length();
- theApp.m_pAngle3DModelObject->mo_Stretch = FLOAT3D( fStretch, fStretch, fStretch);
- // set angle3d model for rendering
- pModelObject = theApp.m_pAngle3DModelObject;
- }
- else
- {
- // get editting bounding box
- FLOATaabbox3D bbox = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOATaabbox3D);
- // reset orientation (axes alligned bounding box !!!)
- rmRenderModel.SetObjectPlacement(
- CPlacement3D(iten->GetPlacement().pl_PositionVector + bbox.Min(),
- ANGLE3D( 0, 0, 0)));
- // set collision box's stretch factor
- theApp.m_pBoundingBoxModelObject->mo_Stretch = bbox.Size();
- // render black wire frame allways
- _mrpModelRenderPrefs.SetWire( TRUE);
- _mrpModelRenderPrefs.SetInkColor( C_BLACK);
- // set bounding box model for rendering
- pModelObject = theApp.m_pBoundingBoxModelObject;
- }
- // set light placement
- rmRenderModel.rm_vLightDirection = FLOAT3D(1.0f, -1.0f, 1.0f);
- // set color of light
- rmRenderModel.rm_colLight= C_WHITE;
- rmRenderModel.rm_colAmbient = C_GRAY;
- // render range sphere model
- pModelObject->SetupModelRendering(rmRenderModel);
- pModelObject->RenderModel(rmRenderModel);
- }
- }
- // if we should render volume box model
- if( pDoc->m_bBrowseEntitiesMode)
- {
- // this model we will render
- CModelObject *pModelObject;
- // this render model structure will be rendered
- CRenderModel rmRenderModel;
- // create bbox from requested volume
- FLOATaabbox3D bboxVolume( pDoc->m_vCreateBoxVertice0, pDoc->m_vCreateBoxVertice1);
- // position it inside box
- rmRenderModel.SetObjectPlacement(CPlacement3D(bboxVolume.Min(), ANGLE3D( 0, 0, 0)));
- // set collision box's stretch factor
- theApp.m_pBoundingBoxModelObject->mo_Stretch = bboxVolume.Size();
- // render black wire frame allways
- _mrpModelRenderPrefs.SetWire( TRUE);
- _mrpModelRenderPrefs.SetHiddenLines( TRUE);
- _mrpModelRenderPrefs.SetInkColor( C_BLACK);
- // set bounding box model for rendering
- pModelObject = theApp.m_pBoundingBoxModelObject;
- // set light placement
- rmRenderModel.rm_vLightDirection = FLOAT3D(1.0f, -1.0f, 1.0f);
- // set color of light
- rmRenderModel.rm_colLight= C_WHITE;
- rmRenderModel.rm_colAmbient = C_GRAY;
- // render bounding volume model
- pModelObject->SetupModelRendering(rmRenderModel);
- pModelObject->RenderModel(rmRenderModel);
- }
- EndModelRenderingView();
- // if we should draw orientation icon, do it now because latter we may
- // have problems due to automatic InitRenderer (in that case we would try
- // to render icons on second layer's DrawPort, last locked, but it is allready
- // destructed)
- if( pDoc->m_bOrientationIcons)
- {
- #define XS 10
- #define YS 16
- #define DX 32
- #define DY 32
- PIXaabbox2D boxScreen(PIX2D(XS, YS), PIX2D(XS+DX, YS+DY));
- // choose view's orientation icon index
- INDEX iIcon = 0;
- CTString strView="None";
- CTString strU="?";
- CTString strV="?";
- switch( m_ptProjectionType)
- {
- case CSlaveViewer::PT_PERSPECTIVE: { iIcon = 0; strView="persp"; strU=""; strV=""; break;}
- case CSlaveViewer::PT_ISOMETRIC_FRONT: { iIcon = 5; strView="front"; strU="x"; strV="y"; break;}
- case CSlaveViewer::PT_ISOMETRIC_RIGHT: { iIcon = 3; strView="right"; strU="-z"; strV="y"; break;}
- case CSlaveViewer::PT_ISOMETRIC_TOP: { iIcon = 1; strView="top"; strU="x"; strV="-z"; break;}
- case CSlaveViewer::PT_ISOMETRIC_BACK: { iIcon = 6; strView="back"; strU="-x"; strV="y"; break;}
- case CSlaveViewer::PT_ISOMETRIC_LEFT: { iIcon = 4; strView="left"; strU="z"; strV="y"; break;}
- case CSlaveViewer::PT_ISOMETRIC_BOTTOM: { iIcon = 2; strView="bottom"; strU="x"; strV="z"; break;}
- }
- MEXaabbox2D boxTexture(MEX2D(iIcon*DX, 0), MEX2D((iIcon+1)*DX, DY));
- // render icon
- CTextureObject toIcon;
- toIcon.SetData( theApp.m_pViewIconsTD);
- pDP->PutTexture(&toIcon, boxScreen, boxTexture);
- PIX2D pixCenter=PIX2D( pDP->GetWidth()*0.03f, pDP->GetHeight()*0.97f);
- DrawAxis( pixCenter, 40, C_BLUE|CT_OPAQUE, C_RED|CT_OPAQUE, strU, strV);
- pDP->SetFont( _pfdConsoleFont);
- pDP->SetTextAspect( 1.0f);
- pDP->SetTextScaling( 1.0f);
- pDP->PutTextCXY( strView, XS+DX/2, YS/2, C_RED|CT_OPAQUE);
- }
- pDP->BlendScreen();
- // if second layer's world exists
- if( pDoc->m_pwoSecondLayer != NULL)
- {
- // prepare second layer's projection ...
- // get viewer placement from first layer
- CPlacement3D plVirtualViewer = prProjection->ViewerPlacementR();
- // transform it to the system of the second layer
- plVirtualViewer.AbsoluteToRelative(pDoc->m_plSecondLayer);
- // use it in projection for second layer
- CAnyProjection3D prProjectionSecondLayer;
- prProjectionSecondLayer = prProjection;
- prProjectionSecondLayer->ViewerPlacementL() = plVirtualViewer;
- prProjectionSecondLayer->Prepare();
- // if we will not use any kind of polygon filling
- if( !bPolygonFillOn)
- {
- // render scene directly into primary draw port
- ::RenderView( *pDoc->m_pwoSecondLayer, *(CEntity*) NULL,
- prProjectionSecondLayer, *pDP);
- }
- // if filling, create drawport for second layer and create picture using CopyViaZBuffer
- else
- {
- // disable shadow rendering on world in second layer
- _wrpWorldRenderPrefs.SetShadowsType( CWorldRenderPrefs::SHT_NONE);
- // set that we will rendering scene over allready rendered scene
- pDP->SetOverlappedRendering(TRUE);
- // render second layer's scene over already rendered scene using filled z-buffer
- ::RenderView( *pDoc->m_pwoSecondLayer, *(CEntity*) NULL, prProjectionSecondLayer, *pDP);
- }
- // if we are in triangularisation primitive mode
- if( (pDoc->m_bPrimitiveMode) &&
- (theApp.m_vfpCurrent.vfp_ttTriangularisationType != TT_NONE) )
- {
- theApp.m_vfpCurrent.vfp_o3dPrimitive.ob_aoscSectors.Lock();
- CDynamicArray<CObjectVertex> &aVtx = theApp.m_vfpCurrent.vfp_o3dPrimitive.ob_aoscSectors[0].osc_aovxVertices;
- theApp.m_vfpCurrent.vfp_o3dPrimitive.ob_aoscSectors.Unlock();
- aVtx.Lock();
- // render all selected vertices as boxes
- for( INDEX iVtx=0; iVtx<aVtx.Count(); iVtx++)
- {
- if( aVtx[ iVtx].ovx_ulFlags & OVXF_SELECTED)
- {
- FLOAT3D vProjected;
- // project vertice
- prProjectionSecondLayer->ProjectCoordinate( DOUBLEtoFLOAT(aVtx[ iVtx]), vProjected);
- // convert y coordinate from mathemathical representation into screen one
- vProjected(2) = pDP->GetHeight() - vProjected(2);
- pDP->Fill( (SLONG)vProjected(1)-3, (SLONG)vProjected(2)-3, 6, 6, C_BLACK|CT_OPAQUE);
- }
- }
- aVtx.Unlock();
- }
- }
- // if cut mode on, this isn't perspective view, and cut line modification has been performed on this view
- if( theApp.m_bCutModeOn && !bPerspectiveOn && ( pDoc->m_pCutLineView == this))
- {
- // render cut line
- FLOAT3D v0 = pDoc->m_vCutLineStart;
- FLOAT3D v1 = pDoc->m_vCutLineEnd;
- FLOAT3D vp0;
- FLOAT3D vp1;
- // create a projection for current viewer
- CAnyProjection3D prProjection;
- svViewer.MakeProjection(prProjection);
- prProjection->Prepare();
- prProjection->ProjectCoordinate( v0, vp0);
- prProjection->ProjectCoordinate( v1, vp1);
- // convert y coordinates into view space
- vp0(2) = pDP->GetHeight()-vp0(2);
- vp1(2) = pDP->GetHeight()-vp1(2);
- PIX x1 = (PIX)vp0(1);
- PIX y1 = (PIX)vp0(2);
- PIX x2 = (PIX)vp1(1);
- PIX y2 = (PIX)vp1(2);
- // spread cut line (using parametric line representation) to edges of the draw port
- FLOAT dx = x2-x1;
- FLOAT dy = y2-y1;
- FLOAT fT[4];
- fT[0] = (0-x1)/dx;
- fT[1] = (pDP->GetWidth()-x1)/dx;
- fT[2] = (0-y1)/dy;
- fT[3] = (pDP->GetHeight()-y1)/dy;
- // find smallest T greater than 0 and biggest T less than 0
- FLOAT fMaxNegT = -9999999.0f;
- FLOAT fMinPosT = 9999999.0f;
- for( INDEX iT=0; iT<4; iT++)
- {
- if(fT[iT]>1)
- {
- if(fT[iT]<fMinPosT)
- {
- fMinPosT = fT[iT];
- }
- }
- else if(fT[iT]<0)
- {
- if(fT[iT]>fMaxNegT)
- {
- fMaxNegT = fT[iT];
- }
- }
- }
- // calculate border coordinates for found two T values
- PIX xb1 = (PIX) x1+dx*fMaxNegT;
- PIX xb2 = (PIX) x1+dx*fMinPosT;
- PIX yb1 = (PIX) y1+dy*fMaxNegT;
- PIX yb2 = (PIX) y1+dy*fMinPosT;
- // draw cut line
- COLOR colCutBorderLine = C_RED|CT_OPAQUE;
- pDP->DrawLine( xb1, yb1, xb2, yb2, colCutBorderLine, _TY124_);
-
- // draw control point lines
- COLOR colControl = C_BLACK|CT_OPAQUE;
- pDP->DrawLine( x1-3, y1-3, x1+3, y1+3, colControl);
- pDP->DrawLine( x1+3, y1-3, x1-3, y1+3, colControl);
- pDP->DrawLine( x2-3, y2-3, x2+3, y2+3, colControl);
- pDP->DrawLine( x2+3, y2-3, x2-3, y2+3, colControl);
- }
- // if measure mode on
- if( m_iaInputAction == IA_MEASURING)
- {
- // calculate placement for mouse down
- CPlacement3D plMouseDown;
- // obtain information about where mouse pointed into the world in the moment of mouse down
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouseDown);
- plMouseDown.pl_PositionVector = crRayHit.cr_vHit;
- pDoc->SnapToGrid( plMouseDown, m_fGridInMeters/GRID_DISCRETE_VALUES);
- // calculate placement for current mouse position
- CPlacement3D plCurrentMousePos;
- // obtain information about where mouse points into the world right now
- crRayHit = GetMouseHitInformation( m_ptMouse);
- plCurrentMousePos.pl_PositionVector = crRayHit.cr_vHit;
- // snap to grid curent mouse placement
- pDoc->SnapToGrid( plCurrentMousePos, m_fGridInMeters/GRID_DISCRETE_VALUES);
- // construct bbox containing both points
- FLOATaabbox3D bbox( plMouseDown.pl_PositionVector);
- bbox |= FLOATaabbox3D( plCurrentMousePos.pl_PositionVector);
- FLOAT3D vCenter = plMouseDown.pl_PositionVector;
- FLOAT3D vUp = plMouseDown.pl_PositionVector;
- FLOAT3D vRight = plMouseDown.pl_PositionVector;
- FLOAT3D vForward = plMouseDown.pl_PositionVector;
- vUp(2) = plCurrentMousePos.pl_PositionVector(2);
- vRight(1) = plCurrentMousePos.pl_PositionVector(1);
- vForward(3) = plCurrentMousePos.pl_PositionVector(3);
- // prepare font
- pDP->SetFont( theApp.m_pfntSystem);
- pDP->SetTextAspect( 1.0f);
- pDP->SetTextScaling( 1.0f);
- CTString strText;
- strText.PrintF( "%g", bbox.Size()(1));
- DrawArrowAndTypeText( *prProjection, vCenter, vRight, C_BLUE|CT_OPAQUE, strText);
- strText.PrintF( "%g", bbox.Size()(2));
- DrawArrowAndTypeText( *prProjection, vCenter, vUp, C_BLUE|CT_OPAQUE, strText);
- strText.PrintF( "%g", bbox.Size()(3));
- DrawArrowAndTypeText( *prProjection, vCenter, vForward, C_BLUE|CT_OPAQUE, strText);
-
- // in orto projections, draw diagonal line
- if( m_ptProjectionType != CSlaveViewer::PT_PERSPECTIVE)
- {
- //strText.PrintF( "%g", bbox.Size().Length());
- DrawArrowAndTypeText( *prProjection,
- plMouseDown.pl_PositionVector,
- plCurrentMousePos.pl_PositionVector, C_lGRAY|CT_OPAQUE, "");
- }
- m_strMeasuring.PrintF( "Distance: %g", bbox.Size().Length());
- }
- // test string
- if( m_strTest!="")
- {
- pDP->SetFont( theApp.m_pfntSystem);
- pDP->SetTextScaling( 1.0f);
- pDP->SetTextAspect( 1.0f);
- pDP->PutText( m_strTest, 32, 32);
- }
- }
- static TIME tmSwapBuffers = 0;
- extern BOOL _bInOnDraw = FALSE;
- void CWorldEditorView::OnDraw(CDC* pDC)
- {
- // skip if already drawing
- if( _bInOnDraw) return;
- _bInOnDraw = TRUE;
- // get some view variables
- CWorldEditorDoc* pDoc = GetDocument();
- BOOL bCSGOn = pDoc->m_pwoSecondLayer != NULL;
- BOOL bPerspectiveOn = m_ptProjectionType == CSlaveViewer::PT_PERSPECTIVE;
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- CViewPort *pvpValidViewPort = GetViewPort();
- // if there is a valid drawport, and the drawport can be locked
- if( pdpValidDrawPort!=NULL && pdpValidDrawPort->Lock())
- {
- // variable to recive start time
- CTimerValue tvStart = _pTimer->GetHighPrecisionTimer();
- // render view
- RenderView( pdpValidDrawPort);
- // obtain stop time
- CTimerValue tvStop = _pTimer->GetHighPrecisionTimer();
- // number telling how many miliseconds passed
- TIME tmDelta = (tvStop-tvStart).GetSeconds() +tmSwapBuffers;
- // mark that view has been changed
- m_chViewChanged.MarkChanged();
- // if we can and should print any kind of frame rate descriptive message
- if( !bCSGOn && bPerspectiveOn && GetChildFrame()->m_bSceneRenderingTime)
- {
- // prepare string about things that impact to currently rendered picture
- CTString strFPS, strReport;
- STAT_Report(strReport);
- STAT_Reset();
- // adjust and set font
- pdpValidDrawPort->SetFont( _pfdConsoleFont);
- pdpValidDrawPort->SetTextScaling( 1.0f);
- // put filter
- PIX pixDPHeight = pdpValidDrawPort->GetHeight();
- pdpValidDrawPort->Fill( 0,0, 150,pixDPHeight, C_BLACK|128, C_BLACK|0, C_BLACK|192, C_BLACK|0);
- // printout statistics
- strFPS.PrintF( " %3.0f FPS (%2.0f ms)\n----------------\n", 1.0f/tmDelta, tmDelta*1000.0f);
- pdpValidDrawPort->PutText( strFPS, 0, 5, C_lCYAN|CT_OPAQUE);
- pdpValidDrawPort->PutText( strReport, 4, 30, C_GREEN|CT_OPAQUE);
- }
- // unlock the drawport
- pdpValidDrawPort->Unlock();
- // swap if there is a valid viewport
- if( pvpValidViewPort!=NULL) {
- tvStart = _pTimer->GetHighPrecisionTimer();
- pvpValidViewPort->SwapBuffers();
- tvStop = _pTimer->GetHighPrecisionTimer();
- tmSwapBuffers = (tvStop-tvStart).GetSeconds();
- }
- }
- // all done
- _bInOnDraw = FALSE;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CWorldEditorView diagnostics
- #ifdef _DEBUG
- void CWorldEditorView::AssertValid() const
- {
- CView::AssertValid();
- }
- void CWorldEditorView::Dump(CDumpContext& dc) const
- {
- CView::Dump(dc);
- }
- CWorldEditorDoc* CWorldEditorView::GetDocument() // non-debug version is inline
- {
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWorldEditorDoc)));
- return (CWorldEditorDoc*)m_pDocument;
- }
- #endif //_DEBUG
- /////////////////////////////////////////////////////////////////////////////
- // CWorldEditorView message handlers
- void CWorldEditorView::OnInitialUpdate()
- {
- CView::OnInitialUpdate();
- // allow file drop
- DragAcceptFiles();
- // at this time, m_hWnd is valid, so we do canvas initialization here
- _pGfx->CreateWindowCanvas(m_hWnd, &m_pvpViewPort, &m_pdpDrawPort);
- // get active view
- CWorldEditorView *pWorldEditorView = theApp.GetActiveView();
- if( (pWorldEditorView != NULL) && (pWorldEditorView != this)
- && (theApp.m_Preferences.ap_CopyExistingWindowPrefs) )
- {
- m_IsWinBcgTexture = pWorldEditorView->m_IsWinBcgTexture;
- m_fnWinBcgTexture = pWorldEditorView->m_fnWinBcgTexture;
- m_SelectionColor = pWorldEditorView->m_SelectionColor;
- m_PaperColor = pWorldEditorView->m_PaperColor;
- m_InkColor = pWorldEditorView->m_InkColor;
- CChildFrame *pcfThis = GetChildFrame();
- CChildFrame *pcfOld = pWorldEditorView->GetChildFrame();
- if( pcfThis != pcfOld)
- {
- pcfThis->m_mvViewer = pcfOld->m_mvViewer;
- }
- }
- else
- {
- m_IsWinBcgTexture = FALSE;
- m_SelectionColor = theApp.m_Preferences.ap_DefaultSelectionColor;
- m_PaperColor = theApp.m_Preferences.ap_DefaultPaperColor;
- m_InkColor = theApp.m_Preferences.ap_DefaultInkColor;
- }
- if( theApp.m_Preferences.ap_SetDefaultColors)
- {
- m_SelectionColor = CLRF_CLR( theApp.m_Preferences.ap_DefaultSelectionColor);
- m_PaperColor = CLRF_CLR( theApp.m_Preferences.ap_DefaultPaperColor);
- m_InkColor = CLRF_CLR( theApp.m_Preferences.ap_DefaultInkColor);
- }
- }
- void CWorldEditorView::OnSize(UINT nType, int cx, int cy)
- {
- CView::OnSize(nType, cx, cy);
- // if we are not in game mode and changing of display mode is not on
- if( !theApp.m_bChangeDisplayModeInProgress)
- { // and window canvas is valid
- if( m_pvpViewPort!=NULL)
- { // resize it
- m_pvpViewPort->Resize();
- }
- }
- }
- int CWorldEditorView::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CView::OnCreate(lpCreateStruct) == -1)
- return -1;
- // register drop target
- m_DropTarget.Register(this);
- return 0;
- }
- /*
- * Get the pointer to the main frame object of this application
- */
- CMainFrame *CWorldEditorView::GetMainFrame()
- {
- // get the MDIChildFrame of this window
- CChildFrame *pfrChild = (CChildFrame *)this->GetParentFrame();
- ASSERT(pfrChild!=NULL);
- // get the MDIFrameWnd
- CMainFrame *pfrMain = (CMainFrame *)pfrChild->GetParentFrame();
- ASSERT(pfrMain!=NULL);
- return pfrMain;
- }
- void CWorldEditorView::OnKillFocus(CWnd* pNewWnd)
- {
- m_iaInputAction = IA_NONE;
- // discard laso selection
- m_avpixLaso.Clear();
- CView::OnKillFocus(pNewWnd);
- }
- void CWorldEditorView::OnActivateView(BOOL bActivate,
- CView* pActivateView, CView* pDeactiveView)
- {
- // if new view's document is not same as last activated document and if document is
- // beiing activated
- if( (pActivateView != NULL) &&
- (pActivateView->GetDocument() != theApp.GetLastActivatedDocument()) &&
- (bActivate) &&
- (pActivateView->GetDocument() != NULL) )
- {
- // mark that we are in crossing fase of switching documents if anybody searches for
- // document, he will get NULL
- theApp.m_bDocumentChangeOn = TRUE;
- // force OnIdle so info and combos will adjust to situation when doc = NULL
- theApp.OnIdle( 0);
- // finish crossing fase, continue "normal" behaviour
- theApp.m_bDocumentChangeOn = FALSE;
- }
- // mark that new document will be activated
- theApp.ActivateDocument(GetDocument());
- CView::OnActivateView(bActivate, pActivateView, pDeactiveView);
- }
- BOOL MyChooseColor( COLORREF &clrNewColor, CWnd &wndOwner)
- {
- COLORREF MyCustColors[ 16];
- CHOOSECOLOR ccInit;
- ASSERT( &wndOwner != NULL);
- MyCustColors[ 0] = CLRF_CLR(C_BLACK);
- MyCustColors[ 1] = CLRF_CLR(C_WHITE);
- MyCustColors[ 2] = CLRF_CLR(C_dGRAY);
- MyCustColors[ 3] = CLRF_CLR(C_GRAY);
- MyCustColors[ 4] = CLRF_CLR(C_lGRAY);
- MyCustColors[ 5] = CLRF_CLR(C_dRED);
- MyCustColors[ 6] = CLRF_CLR(C_dGREEN);
- MyCustColors[ 7] = CLRF_CLR(C_dBLUE);
- MyCustColors[ 8] = CLRF_CLR(C_dCYAN);
- MyCustColors[ 9] = CLRF_CLR(C_dMAGENTA);
- MyCustColors[10] = CLRF_CLR(C_dYELLOW);
- MyCustColors[11] = CLRF_CLR(C_dORANGE);
- MyCustColors[12] = CLRF_CLR(C_dBROWN);
- MyCustColors[13] = CLRF_CLR(C_dPINK);
- MyCustColors[14] = CLRF_CLR(C_lORANGE);
- MyCustColors[15] = CLRF_CLR(C_lBROWN);
- memset(&ccInit, 0, sizeof(CHOOSECOLOR));
- ccInit.lStructSize = sizeof(CHOOSECOLOR);
- ccInit.Flags = CC_RGBINIT | CC_FULLOPEN;
- ccInit.rgbResult = clrNewColor;
- ccInit.lpCustColors = &MyCustColors[ 0];
- ccInit.hwndOwner = wndOwner.m_hWnd;
- if( !ChooseColor( &ccInit))
- return FALSE;
- clrNewColor = ccInit.rgbResult;
- return TRUE;
- }
- // Returns eather perspective view's or manual mip factor
- FLOAT CWorldEditorView::GetCurrentlyActiveMipFactor(void)
- {
- // get document
- CWorldEditorDoc* pDoc = GetDocument();
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CEntity *penBrush = pMainFrame->m_CSGDesitnationCombo.GetSelectedBrushEntity();
- // get draw port
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- if((GetChildFrame()->m_bAutoMipBrushingOn) &&
- (penBrush != NULL) &&
- (pdpValidDrawPort != NULL) )
- {
- // get entity's brush
- CBrush3D *pbrBrush = penBrush->GetBrush();
- // create a slave viewer
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, CSlaveViewer::PT_PERSPECTIVE,
- pDoc->m_plGrid, pdpValidDrawPort);
- // create a projection for slave viewer
- CAnyProjection3D prProjection;
- svViewer.MakeProjection(prProjection);
- prProjection->ObjectPlacementL() = penBrush->GetPlacement();
- // prepare the projection
- prProjection->Prepare();
- // return mip factor for entity in perspective projection
- return( -prProjection->pr_TranslationVector(3));
- }
- else
- {
- return (GetChildFrame()->m_fManualMipBrushingFactor);
- }
- }
- void CWorldEditorView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- // find window under mouse pointer
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->SetStatusLineModeInfoMessage();
- POINT point;
- GetCursorPos(&point);
- HWND hwndUnderMouse = ::WindowFromPoint( point);
- // if not this one (use parent because gfx-API child is over the window)
- if (m_hWnd != ::GetParent(hwndUnderMouse)) {
- // ignore the key
- return;
- }
- CView::OnKeyDown( nChar, nRepCnt, nFlags);
- BOOL bShift = (GetKeyState(VK_SHIFT) &0x8000) != 0;
- BOOL bCtrl = (GetKeyState(VK_CONTROL)&0x8000) != 0;
- BOOL bAlt = (GetKeyState(VK_MENU) &0x8000) != 0;
- BOOL bSpace = (GetKeyState( VK_SPACE)&0x8000) != 0;
- BOOL bLMB = (GetKeyState( VK_LBUTTON)&0x8000) != 0;
- if(bLMB && !bAlt && (pDoc->GetEditingMode()==TERRAIN_MODE) && !bSpace)
- {
- if( bCtrl) m_iaInputAction=IA_TERRAIN_EDITING_CTRL_LMB;
- else m_iaInputAction=IA_TERRAIN_EDITING_LMB;
- }
- // tool tips are on when you press I
- if( (GetKeyState('I')&0x80) && !(bShift|bCtrl|bAlt)) {
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- // if info doesn't yet exist
- if( pMainFrame->m_pwndToolTip == NULL)
- { // force it
- theApp.m_cttToolTips.ManualOn( m_ptMouse.x, m_ptMouse.y, &::GetToolTipText, this);
- }
- }
- // call parent's key pressed function
- GetChildFrame()->KeyPressed( nChar, nRepCnt, nFlags);
- }
- void CWorldEditorView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->SetStatusLineModeInfoMessage();
- // if we are in mip mode for setting, set new brush switch factor
- if( m_iaInputAction == IA_MIP_SETTING)
- {
- SetMipBrushFactor();
- }
- BOOL bCtrl = (GetKeyState(VK_CONTROL)&0x8000) != 0;
- BOOL bSpace = (GetKeyState( VK_SPACE)&0x8000) != 0;
- BOOL bLMB = (GetKeyState( VK_LBUTTON)&0x8000) != 0;
- BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0;
- if(bLMB && !bAlt && (pDoc->GetEditingMode()==TERRAIN_MODE) && !bSpace)
- {
- if( bCtrl) m_iaInputAction=IA_TERRAIN_EDITING_CTRL_LMB;
- else m_iaInputAction=IA_TERRAIN_EDITING_LMB;
- _tvLastTerrainBrushingApplied=_pTimer->GetHighPrecisionTimer();
- }
- // shut down tool tips
- theApp.m_cttToolTips.ManualOff();
- CView::OnKeyUp(nChar, nRepCnt, nFlags);
- }
- void CWorldEditorView::SetMipBrushFactor(void)
- {
- // remember current time as time when last mip brushing option has been used
- _fLastMipBrushingOptionUsed = _pTimer->GetRealTimeTick();
- CChildFrame *pChild = GetChildFrame();
- // set auto mip brushing mode on
- pChild->m_bAutoMipBrushingOn = TRUE;
- // get auto mip factor
- FLOAT fCurrentMipFactor = GetCurrentlyActiveMipFactor();
- pChild->m_bAutoMipBrushingOn = pChild->m_bLastAutoMipBrushingOn;
- // set auto mip brushing mode as it was before mip setting started
- ASSERT( m_pbmToSetMipSwitch != NULL);
- // set new mip switch factor
- m_pbmToSetMipSwitch->SetMipDistance( fCurrentMipFactor-0.01f);
- // switch back to auto mip brushing mode
- GetChildFrame()->m_bAutoMipBrushingOn = TRUE;
- // get document
- CWorldEditorDoc* pDoc = GetDocument();
- // document has changed
- pDoc->SetModifiedFlag();
- // update all views
- pDoc->UpdateAllViews( NULL);
- m_iaInputAction = IA_NONE;
- }
- void CWorldEditorView::StartMouseInput( CPoint point)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- BOOL bCSGOn = pDoc->m_pwoSecondLayer != NULL;
- pDoc->UpdateAllViews(NULL);
- // reset offseted placement
- m_plMouseOffset.pl_PositionVector = FLOAT3D(0.0f, 0.0f, 0.0f);
- m_plMouseOffset.pl_OrientationAngle = ANGLE3D(0, 0, 0);
- // if there is CSG operation active
- if( bCSGOn)
- {
- // copy original layer's placement because we need to perform "continous moving"
- m_plMouseMove = pDoc->m_plSecondLayer;
- }
- // otherwise if we are in entity mode and there is at least 1 entity selected
- else if( pDoc->GetEditingMode() == ENTITY_MODE)
- {
- if(pDoc->m_selEntitySelection.Count()==0)
- {
- pDoc->m_aSelectedEntityPlacements.Clear();
- }
- else
- {
- FLOATaabbox3D box;
- CPlacement3D plEntityCenter;
- plEntityCenter = CPlacement3D( FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0));
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- // accumulate positions
- box |= iten->GetPlacement().pl_PositionVector;
- //plEntityCenter.pl_OrientationAngle += iten->GetPlacement().pl_OrientationAngle;
- }}
- plEntityCenter.pl_PositionVector = box.Center();
- plEntityCenter.pl_PositionVector(2) = box.Min()(2);
- // calculate average rotation
- //plEntityCenter.pl_OrientationAngle /= (ANGLE)pDoc->m_selEntitySelection.Count();
- // remember
- pDoc->m_aSelectedEntityPlacements.Clear();
- pDoc->m_aSelectedEntityPlacements.New(pDoc->m_selEntitySelection.Count());
- INDEX ienCurrent = 0;
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- CPlacement3D plRelative = iten->GetPlacement();
- plRelative.AbsoluteToRelativeSmooth(plEntityCenter);
- pDoc->m_aSelectedEntityPlacements[ ienCurrent] = plRelative;
- ienCurrent++;
- }}
- // copy it's placement for continous moving
- m_plMouseMove = plEntityCenter;
- }
- }
- else if( pDoc->GetEditingMode() == VERTEX_MODE)
- {
- pDoc->m_avStartDragVertices.Clear();
- INDEX ctDragVertices = pDoc->m_selVertexSelection.Count();
- if( ctDragVertices != 0)
- {
- // remember coordinates of vertices for dragging
- pDoc->m_avStartDragVertices.New(ctDragVertices);
- INDEX iVtx = 0;
- {FOREACHINDYNAMICCONTAINER( pDoc->m_selVertexSelection, CBrushVertex, itbvx)
- {
- pDoc->m_avStartDragVertices[ iVtx] = FLOATtoDOUBLE( itbvx->bvx_vAbsolute);
- iVtx++;
- }}
- }
- }
- // copy mouse point to both point for calculating relative (from last mouse position) and
- // absolute (from mouse down position) distances
- m_ptMouse = point;
- }
- void CWorldEditorView::StopMouseInput(void)
- {
- // update all views when current view stopped modifying
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->UpdateAllViews( NULL);
- }
- // obtain information about what was hitted with mouse
- CCastRay CWorldEditorView::GetMouseHitInformation( CPoint point,
- BOOL bHitPortals /* = FALSE */,
- BOOL bHitModels /* = TRUE */,
- BOOL bHitFields /* = FALSE */,
- CEntity *penSourceEntity /* = NULL */,
- BOOL bHitBrushes /* = TRUE */)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // get draw port
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- // if it is not valid
- if( pdpValidDrawPort == NULL)
- {
- // return dummy result
- return CCastRay( NULL, CPlacement3D(FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0)) );
- }
- // obtain viewer placement
- CPlacement3D plViewer = GetChildFrame()->m_mvViewer.GetViewerPlacement();
- // create a slave viewer
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pdpValidDrawPort);
- // now we will try to obtain where mouse poonts to in the base world
- // create a projection for current viewer
- CAnyProjection3D prProjection;
- svViewer.MakeProjection(prProjection);
- prProjection->Prepare();
- // make the ray from viewer point through the mouse point, in current projection
- CPlacement3D plRay;
- prProjection->RayThroughPoint(FLOAT3D((float)point.x,
- pdpValidDrawPort->GetHeight()-(float)point.y, 0.0f), plRay);
- // construct cast ray for base world
- CCastRay crBaseWorldCastResult( penSourceEntity, plRay);
- // set portal "transparency" or "hitability" for hit beam
- crBaseWorldCastResult.cr_bHitPortals = bHitPortals;
- // set hitability for models
- if( (m_vpViewPrefs.m_mrpModelRenderPrefs.GetRenderType() & RT_TEXTURE) && bHitModels)
- {
- crBaseWorldCastResult.cr_ttHitModels = CCastRay::TT_FULL;
- }
- else
- {
- crBaseWorldCastResult.cr_ttHitModels = CCastRay::TT_NONE;
- }
- crBaseWorldCastResult.cr_bHitFields = bHitFields;
- crBaseWorldCastResult.cr_bHitBrushes = bHitBrushes;
- // cast ray, go for hit data
- pDoc->m_woWorld.CastRay( crBaseWorldCastResult);
- // if second layer's world exist
- if( pDoc->m_pwoSecondLayer != NULL)
- {
- // prepare second layer's projection ...
- // get viewer placement from first layer
- CPlacement3D plVirtualViewer = prProjection->ViewerPlacementR();
- // transform it to the system of the second layer
- plVirtualViewer.AbsoluteToRelative(pDoc->m_plSecondLayer);
- // use it in projection for second layer
- CAnyProjection3D prProjectionSecondLayer;
- prProjectionSecondLayer = prProjection;
- prProjectionSecondLayer->ViewerPlacementL() = plVirtualViewer;
- prProjectionSecondLayer->Prepare();
- // calculate valid ray for second layer
- CPlacement3D plLayerRay;
- prProjectionSecondLayer->RayThroughPoint(FLOAT3D((float)point.x,
- pdpValidDrawPort->GetHeight()-(float)point.y, 0.0f), plLayerRay);
- // construct cast ray for second layer's world
- CCastRay crLayerWorldCastResult( penSourceEntity, plLayerRay);
- // set portal "transparency" or "hitability" for hit beam
- crLayerWorldCastResult.cr_bHitPortals = bHitPortals;
- // set hitability for models
- if( m_vpViewPrefs.m_mrpModelRenderPrefs.GetRenderType() & RT_TEXTURE)
- {
- crLayerWorldCastResult.cr_ttHitModels = CCastRay::TT_SIMPLE;
- }
- else
- {
- crLayerWorldCastResult.cr_ttHitModels = CCastRay::TT_NONE;
- }
- // cast ray, go for hit data
- pDoc->m_pwoSecondLayer->CastRay( crLayerWorldCastResult);
- // if any kind of entity on second layer was hitted
- if( crLayerWorldCastResult.cr_penHit != NULL)
- {
- // calculate distance beetween viewer and hited point in layer's world
- FLOAT fSecondLayerHitDistance =
- (crLayerWorldCastResult.cr_vHit - plVirtualViewer.pl_PositionVector).Length();
- // transform hited coordinate back to absolute space
- CPlacement3D plHitPlacement = plLayerRay;
- plHitPlacement.pl_PositionVector = crLayerWorldCastResult.cr_vHit;
- plHitPlacement.RelativeToAbsolute( pDoc->m_plSecondLayer);
- // and set it as hited point
- crLayerWorldCastResult.cr_vHit = plHitPlacement.pl_PositionVector;
- // if ray didn't hit anything on base world
- if( crBaseWorldCastResult.cr_penHit == NULL)
- {
- // valid result is one received from second layer ray hit
- return crLayerWorldCastResult;
- }
- // calculate distance beetween viewer and base world's hit point
- FLOAT fBaseWorldHitDistance =
- (crBaseWorldCastResult.cr_vHit - plViewer.pl_PositionVector).Length();
- // if base world's hit point is closer than second layer's hit point
- if( Abs(fBaseWorldHitDistance) < Abs(fSecondLayerHitDistance))
- {
- // base world's hit result is valid result
- return crBaseWorldCastResult;
- }
- // otherwise
- else
- {
- // second layer's world hit result is valid result
- return crLayerWorldCastResult;
- }
- }
- }
- if( crBaseWorldCastResult.cr_penHit == NULL)
- {
- // placement equals ray placement
- CPlacement3D plPlacementInFront = plRay;
- // calculate position somewhere in front of viewer
- plPlacementInFront.Translate_OwnSystem( FLOAT3D( 0.0f, 0.0f, -10.0f));
- // copy result coordinate into cast object
- crBaseWorldCastResult.cr_vHit = plPlacementInFront.pl_PositionVector;
- }
- return crBaseWorldCastResult;
- }
- FLOAT3D CWorldEditorView::GetMouseHitOnPlane( CPoint point, const FLOATplane3D &plPlane)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // get draw port
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- // if it is not valid
- if( pdpValidDrawPort == NULL)
- {
- // return dummy result
- return FLOAT3D(0.0f,0.0f,0.0f);
- }
- // obtain viewer placement
- CPlacement3D plViewer = GetChildFrame()->m_mvViewer.GetViewerPlacement();
- // create a slave viewer
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pdpValidDrawPort);
- // now we will try to obtain where mouse poonts to in the base world
- // create a projection for current viewer
- CAnyProjection3D prProjection;
- svViewer.MakeProjection(prProjection);
- prProjection->Prepare();
- // make the ray from viewer point through the mouse point, in current projection
- CPlacement3D plRay;
- prProjection->RayThroughPoint(FLOAT3D((float)point.x,
- pdpValidDrawPort->GetHeight()-(float)point.y, 0.0f), plRay);
- // get two points on the line
- FLOAT3D v0 = plRay.pl_PositionVector;
- FLOAT3D v1;
- AnglesToDirectionVector(plRay.pl_OrientationAngle, v1);
- v1*=100.0f; // to increase precision on large scales
- v1+=v0;
-
- // find intersection of line and plane
- FLOAT f0 = plPlane.PointDistance(v0);
- FLOAT f1 = plPlane.PointDistance(v1);
- FLOAT fFraction = f0/(f0-f1);
- return v0+(v1-v0)*fFraction;
- }
- void CWorldEditorView::MarkClosestVtxAndEdgeOnPrimitiveBase(CPoint point)
- {
- // get draw port
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- // if it is not valid
- if( pdpValidDrawPort == NULL) return;
- CWorldEditorDoc* pDoc = GetDocument();
- // create a slave viewer
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pdpValidDrawPort);
- // create a projection for current viewer
- CAnyProjection3D prProjection;
- svViewer.MakeProjection(prProjection);
- // prepare the projection
- prProjection->Prepare();
- // make the ray from viewer point through the mouse point, in current projection
- CPlacement3D plRay;
- prProjection->RayThroughPoint(FLOAT3D((float)point.x,
- pdpValidDrawPort->GetHeight()-(float)point.y, 0.0f), plRay);
- // transform ray to the system of the second layer
- plRay.AbsoluteToRelative(pDoc->m_plSecondLayer);
- m_vMouseDownSecondLayer = plRay.pl_PositionVector;
- // prepare second layer's projection ...
- // get viewer placement from first layer
- CPlacement3D plVirtualViewer = prProjection->ViewerPlacementR();
- // transform it to the system of the second layer
- plVirtualViewer.AbsoluteToRelative(pDoc->m_plSecondLayer);
- // use it in projection for second layer
- CAnyProjection3D prProjectionSecondLayer;
- prProjectionSecondLayer = prProjection;
- prProjectionSecondLayer->ViewerPlacementL() = plVirtualViewer;
- prProjectionSecondLayer->Prepare();
- // get number of vertices for base polygon
- INDEX vtxCt = theApp.m_vfpCurrent.vfp_avVerticesOnBaseOfPrimitive.Count();
- // set distance of closest vertice to a hudge distance
- FLOAT fMinVertexDistance = 999999.9f;
- m_iDragVertice = -1;
- FLOAT fMinEdgeDistance = 999999.9f;
- m_iDragEdge = -1;
- // now we will project base vertices onto screen and try
- // to find closest vertice to mouse for moving vertices on the base
- for( INDEX iVtx=0; iVtx<vtxCt; iVtx++)
- {
- INDEX iNext = (iVtx+1)%vtxCt;
- FLOAT3D vProjectedVtx1, vProjectedVtx2;
- // project vertices
- prProjectionSecondLayer->ProjectCoordinate(
- DOUBLEtoFLOAT(theApp.m_vfpCurrent.vfp_avVerticesOnBaseOfPrimitive[ iVtx]), vProjectedVtx1);
- prProjectionSecondLayer->ProjectCoordinate(
- DOUBLEtoFLOAT(theApp.m_vfpCurrent.vfp_avVerticesOnBaseOfPrimitive[ iNext]), vProjectedVtx2);
- // convert y coordinate from mathemathical representation into screen one
- vProjectedVtx1(2) = pdpValidDrawPort->GetHeight() - vProjectedVtx1(2);
- vProjectedVtx2(2) = pdpValidDrawPort->GetHeight() - vProjectedVtx2(2);
- vProjectedVtx1(3) = 0.0f;
- vProjectedVtx2(3) = 0.0f;
- // calculate distance to mouse
- FLOAT fDVtx1 = ( FLOAT3D((FLOAT)point.x, (FLOAT)point.y, 0.0f) - vProjectedVtx1).Length();
- FLOAT fDVtx2 = ( FLOAT3D((FLOAT)point.x, (FLOAT)point.y, 0.0f) - vProjectedVtx2).Length();
- FLOAT fEdgeLen = ( vProjectedVtx1 - vProjectedVtx2).Length();
- FLOAT s = (fDVtx1+fDVtx2+fEdgeLen)/2.0f;
- FLOAT fArea = FLOAT(sqrt( FLOATtoDOUBLE( s*(s-fDVtx1)*(s-fDVtx2)*(s-fEdgeLen))));
- FLOAT fDEdge = 2.0f*fArea/fEdgeLen;
- // if distance of edge is smaller than last remembered and both edges are smaller than
- // edges of triangle
- if( (fDEdge < fMinEdgeDistance) && (fEdgeLen > fDVtx1) && (fEdgeLen > fDVtx2) )
- {
- fMinEdgeDistance = fDEdge;
- m_iDragEdge = iVtx;
- }
- // if distance of first vertex is smaller than last remembered
- if( fDVtx1 < fMinVertexDistance)
- {
- fMinVertexDistance = fDVtx1;
- m_iDragVertice = iVtx;
- }
- }
- // when we found closest vertice, remember its current position
- m_vStartDragVertice = theApp.m_vfpCurrent.vfp_avVerticesOnBaseOfPrimitive[ m_iDragVertice];
- if( m_iDragEdge != -1)
- {
- INDEX iEdgeEnd = (m_iDragEdge+1)%vtxCt;
- m_vStartDragEdge =
- (theApp.m_vfpCurrent.vfp_avVerticesOnBaseOfPrimitive[ m_iDragEdge]+
- theApp.m_vfpCurrent.vfp_avVerticesOnBaseOfPrimitive[ iEdgeEnd])/2.0f;
- }
- }
- void CWorldEditorView::MarkClosestVtxOnPrimitive( BOOL bToggleSelection)
- {
- // get draw port
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- // if it is not valid
- if( pdpValidDrawPort == NULL) return;
- CWorldEditorDoc* pDoc = GetDocument();
- // create a slave viewer
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pdpValidDrawPort);
- // create a projection for current viewer
- CAnyProjection3D prProjection;
- svViewer.MakeProjection(prProjection);
- // prepare the projection
- prProjection->Prepare();
- // prepare second layer's projection ...
- // get viewer placement from first layer
- CPlacement3D plVirtualViewer = prProjection->ViewerPlacementR();
- // transform it to the system of the second layer
- plVirtualViewer.AbsoluteToRelative(pDoc->m_plSecondLayer);
- // use it in projection for second layer
- CAnyProjection3D prProjectionSecondLayer;
- prProjectionSecondLayer = prProjection;
- prProjectionSecondLayer->ViewerPlacementL() = plVirtualViewer;
- prProjectionSecondLayer->Prepare();
- theApp.m_vfpCurrent.vfp_o3dPrimitive.ob_aoscSectors.Lock();
- CDynamicArray<CObjectVertex> &aVtx = theApp.m_vfpCurrent.vfp_o3dPrimitive.ob_aoscSectors[0].osc_aovxVertices;
- theApp.m_vfpCurrent.vfp_o3dPrimitive.ob_aoscSectors.Unlock();
- aVtx.Lock();
- // set distance of closest vertice to a hudge distance
- FLOAT fMinVertexDistance = 999999.9f;
- FLOAT fMinVertexDistanceZ = 999999.9f;
- INDEX iClosest = -1;
- BOOL bHasSelection = FALSE;
- // now we will project base vertices onto screen and try
- // to find closest vertice to mouse for moving vertices on the base
- for( INDEX iVtx=0; iVtx<aVtx.Count(); iVtx++)
- {
- if( (aVtx[ iVtx].ovx_ulFlags & OVXF_SELECTED) && !bHasSelection)
- {
- bHasSelection = TRUE;
- m_vStartDragO3DVertice = aVtx[ iVtx];
- }
- aVtx[ iVtx].ovx_ulFlags &= ~OVXF_CLOSEST;
- FLOAT3D vProjected;
- // project current base vertice
- prProjectionSecondLayer->ProjectCoordinate( DOUBLEtoFLOAT(aVtx[ iVtx]), vProjected);
- // convert y coordinate from mathemathical representation into screen one
- vProjected(2) = pdpValidDrawPort->GetHeight() - vProjected(2);
- // calculate distance to mouse point
- FLOAT fDX = (FLOAT)m_ptMouse.x-vProjected(1);
- FLOAT fDY = (FLOAT)m_ptMouse.y-vProjected(2);
- FLOAT fDistance = (FLOAT)sqrt(fDX*fDX+fDY*fDY);
- FLOAT fDistanceZ = -vProjected(3);
- // if this distance is smaller than last remembered
- if( (fDistance < fMinVertexDistance-0.5) ||
- ((fDistance<fMinVertexDistance+0.5) && fDistanceZ<fMinVertexDistanceZ) )
- {
- // set this one as smallest
- fMinVertexDistance = fDistance;
- fMinVertexDistanceZ = fDistanceZ;
- // remember its index
- iClosest = iVtx;
- }
- }
- aVtx[ iClosest].ovx_ulFlags |= OVXF_CLOSEST;
- if( bToggleSelection)
- {
- aVtx[ iClosest].ovx_ulFlags ^= OVXF_SELECTED;
- }
- if( !bHasSelection)
- {
- m_vStartDragO3DVertice = aVtx[ iClosest];
- }
- aVtx.Unlock();
- }
- POINT CWorldEditorView::Get2DCoordinateFrom3D( FLOAT3D vPoint)
- {
- CDrawPort *pDP = m_pdpDrawPort;
- CWorldEditorDoc* pDoc = GetDocument();
- CAnyProjection3D prProjection;
- // create a slave viewer
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType, pDoc->m_plGrid, pDP);
- svViewer.MakeProjection(prProjection);
- prProjection->Prepare();
- FLOAT3D vResult;
- prProjection->ProjectCoordinate( vPoint, vResult);
- POINT ptResult;
- ptResult.x = (LONG) vResult(1);
- ptResult.y = pDP->GetHeight()-(LONG) vResult(2);
- return ptResult;
- }
- FLOAT3D CWorldEditorView::Get3DCoordinateFrom2D( POINT &pt)
- {
- CDrawPort *pDP = m_pdpDrawPort;
- // convert coordinate
- PIX pixX = pt.x;
- PIX pixY = pt.y;
- CWorldEditorDoc* pDoc = GetDocument();
- CAnyProjection3D prProjection;
- // create a slave viewer
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType, pDoc->m_plGrid, pDP);
- svViewer.MakeProjection(prProjection);
- prProjection->Prepare();
- // make the ray from viewer point through the mouse point, in current projection
- CPlacement3D plRay;
- prProjection->RayThroughPoint(FLOAT3D((float)pixX, pDP->GetHeight()-(float)pixY, 0.0f), plRay);
- // snap to grid entity's placement
- pDoc->SnapToGrid( plRay, m_fGridInMeters/GRID_DISCRETE_VALUES);
- // get viewer's direction vector
- FLOAT3D vDirection;
- AnglesToDirectionVector( plRay.pl_OrientationAngle, vDirection);
- FLOAT3D vResult;
- vResult = plRay.pl_PositionVector + vDirection;
- // snap result
- SnapVector( vResult);
- return vResult;
- }
- void CWorldEditorView::SnapVector(FLOAT3D &vToSnap)
- {
- CWorldEditorDoc* pDoc = GetDocument();
-
- if( pDoc->m_bAutoSnap)
- {
- Snap(vToSnap(1), m_fGridInMeters/GRID_DISCRETE_VALUES);
- Snap(vToSnap(2), m_fGridInMeters/GRID_DISCRETE_VALUES);
- Snap(vToSnap(3), m_fGridInMeters/GRID_DISCRETE_VALUES);
- }
- else
- {
- Snap(vToSnap(1), SNAP_DOUBLE_CM);
- Snap(vToSnap(2), SNAP_DOUBLE_CM);
- Snap(vToSnap(3), SNAP_DOUBLE_CM);
- }
- }
- void CWorldEditorView::SnapVector(DOUBLE3D &vToSnap)
- {
- CWorldEditorDoc* pDoc = GetDocument();
-
- FLOAT3D vTemp = DOUBLEtoFLOAT(vToSnap);
- if( pDoc->m_bAutoSnap)
- {
- Snap(vTemp(1), m_fGridInMeters/GRID_DISCRETE_VALUES);
- Snap(vTemp(2), m_fGridInMeters/GRID_DISCRETE_VALUES);
- Snap(vTemp(3), m_fGridInMeters/GRID_DISCRETE_VALUES);
- }
- else
- {
- Snap(vTemp(1), SNAP_DOUBLE_CM);
- Snap(vTemp(2), SNAP_DOUBLE_CM);
- Snap(vTemp(3), SNAP_DOUBLE_CM);
- }
-
- vToSnap = FLOATtoDOUBLE(vTemp);
- }
- FLOAT GetDistance( POINT &pt1, POINT &pt2)
- {
- FLOAT2D vpt1, vpt2;
-
- vpt1(1) = pt1.x;
- vpt1(2) = pt1.y;
- vpt2(1) = pt2.x;
- vpt2(2) = pt2.y;
- FLOAT2D vDistance = vpt1-vpt2;
- return vDistance.Length();
- }
- void CWorldEditorView::RenderAndApplyTerrainEditBrush(FLOAT3D vHit)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CTerrain *ptrTerrain=GetTerrain();
- if( ptrTerrain!=NULL)
- {
- CTString strBrushFile;
- INDEX iBrush=INDEX(theApp.m_fCurrentTerrainBrush);
- strBrushFile.PrintF("Textures\\Editor\\TerrainBrush%02d.tex", iBrush);
- try
- {
- CTextureData *ptdBrush=_pTextureStock->Obtain_t(strBrushFile);
- ptdBrush->Force(TEX_STATIC);
- FLOAT fStrengthRatio=theApp.m_fTerrainBrushPressure/1024.0f;
- FLOAT fUncompensatedStrength=(pow(1.0f+theApp.m_fTerrainBrushPressure/1024.0f*16.0f,2)-1.0f)/64.0f;
- COLOR colSelection=C_WHITE|CT_OPAQUE;
- ETerrainEdit teTool=TE_NONE;
- SelectionFill sf;
- // heightmap mode
- if( theApp.m_iTerrainEditMode==TEM_HEIGHTMAP)
- {
- colSelection=C_ORANGE|CT_OPAQUE;
- switch(INDEX(theApp.m_iTerrainBrushMode))
- {
- case TBM_PAINT : teTool=TE_BRUSH_ALTITUDE_PAINT ; break;
- case TBM_SMOOTH : teTool=TE_BRUSH_ALTITUDE_SMOOTH ; break;
- case TBM_FILTER : teTool=TE_BRUSH_ALTITUDE_FILTER ; break;
- case TBM_MINIMUM : teTool=TE_BRUSH_ALTITUDE_MINIMUM ; break;
- case TBM_MAXIMUM : teTool=TE_BRUSH_ALTITUDE_MAXIMUM ; break;
- case TBM_FLATTEN : teTool=TE_BRUSH_ALTITUDE_FLATTEN ; break;
- case TBM_POSTERIZE : teTool=TE_BRUSH_ALTITUDE_POSTERIZE; break;
- case TBM_RND_NOISE : teTool=TE_BRUSH_ALTITUDE_RND_NOISE; break;
- case TBM_CONTINOUS_NOISE: teTool=TE_BRUSH_ALTITUDE_CONTINOUS_NOISE; break;
- case TBM_ERASE : teTool=TE_BRUSH_EDGE_ERASE ; break;
- }
- }
- // texture layer mode
- else
- {
- colSelection=C_GREEN|CT_OPAQUE;
- teTool=TE_BRUSH_LAYER_PAINT;
- CTerrainLayer *ptlLayer=GetLayer();
- if(ptlLayer==NULL) return;
- if( ptlLayer->tl_ltType==LT_TILE)
- {
- teTool=TE_TILE_PAINT;
- }
- else
- {
- switch(INDEX(theApp.m_iTerrainBrushMode))
- {
- case TBM_PAINT : teTool=TE_BRUSH_LAYER_PAINT ; break;
- case TBM_SMOOTH : teTool=TE_BRUSH_LAYER_SMOOTH ; break;
- case TBM_FILTER : teTool=TE_BRUSH_LAYER_FILTER ; break;
- case TBM_RND_NOISE : teTool=TE_BRUSH_LAYER_RND_NOISE; break;
- case TBM_CONTINOUS_NOISE: teTool=TE_BRUSH_LAYER_CONTINOUS_NOISE; break;
- case TBM_ERASE : teTool=TE_BRUSH_EDGE_ERASE ; break;
- }
- }
- }
- // no cursor if selection is hidden
- if(!GetChildFrame()->m_bSelectionVisible) colSelection&=0xFFFFFF00;
- if( m_iaInputAction==IA_TERRAIN_EDITING_LMB || m_iaInputAction==IA_TERRAIN_EDITING_CTRL_LMB)
- {
- // if we pressed mouse down (terrain edit start)
- if(m_iaInputAction!=m_iaLastInputAction)
- {
- TerrainEditBegin();
- }
- CTimerValue tvNow=_pTimer->GetHighPrecisionTimer();
- // get difference to time when last mip brushing option has been used
- FLOAT fSecondsPassed=(tvNow-_tvLastTerrainBrushingApplied).GetSeconds();
- _tvLastTerrainBrushingApplied=_pTimer->GetHighPrecisionTimer();
- // apply time passed factor, so terrain editing wouldn't depend upon frame rate
- fSecondsPassed=Clamp(fSecondsPassed,0.0f,1.0f);
- FLOAT fCompensatedStrength=fUncompensatedStrength*fSecondsPassed/(1.0f/50.0f);
- if( m_iaInputAction==IA_TERRAIN_EDITING_CTRL_LMB) fCompensatedStrength=-fCompensatedStrength;
- // apply terrain editing
- EditTerrain(ptdBrush, vHit, fCompensatedStrength, teTool);
- }
- // if we stopped editing
- else if( m_iaLastInputAction==IA_TERRAIN_EDITING_LMB || m_iaLastInputAction==IA_TERRAIN_EDITING_CTRL_LMB)
- {
- TerrainEditEnd();
- }
- m_iaLastInputAction=m_iaInputAction;
- // render terrain editing cursor
- Rect rect;
- Point pt=Calculate2dHitPoint(ptrTerrain, vHit);
- rect.rc_iLeft=pt.pt_iX-ptdBrush->GetPixWidth()/2;
- rect.rc_iRight=pt.pt_iX+(ptdBrush->GetPixWidth()-ptdBrush->GetPixWidth()/2);
- rect.rc_iTop=pt.pt_iY-ptdBrush->GetPixHeight()/2;
- rect.rc_iBottom=pt.pt_iY+(ptdBrush->GetPixHeight()-ptdBrush->GetPixHeight()/2);
- if(GetChildFrame()->m_bSelectionVisible)
- {
- sf=(SelectionFill) theApp.m_Preferences.ap_iTerrainSelectionVisible;
- }
- else
- {
- sf=(SelectionFill) theApp.m_Preferences.ap_iTerrainSelectionHidden;
- }
- if(sf!=3)
- {
- ShowSelection(ptrTerrain, rect, ptdBrush, colSelection, 0.25f+fStrengthRatio*0.75f, sf);
- }
- }
- catch( char *strError)
- {
- (void) strError;
- }
- }
- }
- void CWorldEditorView::OnLButtonDown(UINT nFlags, CPoint point)
- {
- m_iaInputAction = IA_NONE;
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- if( pdpValidDrawPort == NULL) return;
- m_pbpoTranslationPlane = NULL;
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- // key statuses
- BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0;
- BOOL bSpace = (GetKeyState( ' ') & 128) != 0;
- BOOL bCtrl = nFlags & MK_CONTROL;
- BOOL bShift = nFlags & MK_SHIFT;
- BOOL bRMB = nFlags & MK_RBUTTON;
- BOOL bCSGOn = pDoc->m_pwoSecondLayer != NULL;
- BOOL bHitModels = (pDoc->GetEditingMode() == ENTITY_MODE) || bSpace;
- BOOL bHitFields = (pDoc->GetEditingMode() == ENTITY_MODE) || bSpace;
- BOOL bHitBrushes = (pDoc->GetEditingMode() != TERRAIN_MODE) || bSpace;
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( point, FALSE, bHitModels, bHitFields, NULL, bHitBrushes);
- m_vHitOnMouseDown = crRayHit.cr_vHit;
- theApp.m_vLastTerrainHit=crRayHit.cr_vHit;
- m_ptMouseDown = point;
- m_VFPMouseDown = theApp.m_vfpCurrent;
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pdpValidDrawPort);
- CAnyProjection3D prProjection;
- svViewer.MakeProjection(prProjection);
- prProjection->Prepare();
- // space+ctrl+lmb zoomes in 2x
- if( bSpace && bCtrl)
- {
- if( bRMB) return;
- // set new target
- GetChildFrame()->m_mvViewer.SetTargetPlacement( crRayHit.cr_vHit);
- // move mouse to center of screen
- CPoint ptCenter = CPoint( m_pdpDrawPort->GetWidth()/2, m_pdpDrawPort->GetHeight()/2);
- ClientToScreen( &ptCenter);
- SetCursorPos(ptCenter.x, ptCenter.y);
- OnZoomMore();
- pDoc->UpdateAllViews( NULL);
- m_ptMouseDown = ptCenter;
- return;
- }
- // space+lmb is used for viewer and CSG layer movement in floor plane,+rmb rotates
- else if( bSpace)
- {
- if( bRMB) m_iaInputAction = IA_ROTATING_VIEWER;
- else m_iaInputAction = IA_MOVING_VIEWER_IN_FLOOR_PLANE;
- StartMouseInput( point);
- }
- // in measure mode, only viewer moving is enabled
- else if( theApp.m_bMeasureModeOn)
- {
- m_iaInputAction = IA_MEASURING;
- }
- // in cut mode, only viewer moving is enabled
- else if( theApp.m_bCutModeOn)
- {
- // project 3D control points
- POINT ptStart = Get2DCoordinateFrom3D( pDoc->m_vCutLineStart);
- POINT ptEnd = Get2DCoordinateFrom3D( pDoc->m_vCutLineEnd);
-
- // calculate distances
- FLOAT fDStart = GetDistance( ptStart, point);
- FLOAT fDEnd = GetDistance( ptEnd, point);
- FLOAT fAllowedDistance = 32.0f;
-
- // if we clicked near coontrol point
- if( fDStart < fAllowedDistance)
- {
- m_iaInputAction = IA_MOVING_CUT_LINE_START;
- pDoc->m_vControlLineDragStart = pDoc->m_vCutLineStart;
- }
- else if( fDEnd < fAllowedDistance)
- {
- m_iaInputAction = IA_MOVING_CUT_LINE_END;
- pDoc->m_vControlLineDragStart = pDoc->m_vCutLineEnd;
- }
- else
- {
- m_iaInputAction = IA_CUT_MODE;
- pDoc->m_pCutLineView = this;
- pDoc->m_vCutLineStart = Get3DCoordinateFrom2D( point);
- pDoc->m_vCutLineEnd = pDoc->m_vCutLineStart;
- }
- pDoc->UpdateAllViews( this);
- }
- // test for mouse operations used while primitive CSG is on
- else if( bCSGOn)
- {
- if( bCtrl && bAlt)
- {
- SetAsCsgTarget(crRayHit.cr_penHit);
- }
- if( bCtrl && !bShift)
- {
- if( bRMB) m_iaInputAction = IA_ROTATING_SECOND_LAYER;
- else m_iaInputAction = IA_MOVING_SECOND_LAYER_IN_FLOOR_PLANE;
- }
- else if( pDoc->m_bPrimitiveMode)
- {
- // in triangularisation primitive mode
- if( theApp.m_vfpCurrent.vfp_ttTriangularisationType != TT_NONE)
- {
- // select vertices on primitive
- MarkClosestVtxOnPrimitive( bShift);
- // and start dragging them
- if( !bShift) m_iaInputAction = IA_DRAG_VERTEX_ON_PRIMITIVE;
- }
- // shift+lmb inserts vertex on primitive base
- else if( !bCtrl && bShift)
- {
- // find and remember vertex on primitive base for draging
- MarkClosestVtxAndEdgeOnPrimitiveBase( point);
- if(m_iDragEdge != -1)
- {
- pDoc->InsertPrimitiveVertex( m_iDragEdge, m_vMouseDownSecondLayer);
- }
- }
- // lmb is used for dragging vertices on base of primitive
- else
- {
- // ctrl+shift+lmb stretches primitive
- if( bCtrl && bShift) m_iaInputAction = IA_STRETCHING_PRIMITIVE;
- else m_iaInputAction = IA_DRAG_VERTEX_ON_PRIMITIVE_BASE;
- // ------ Find closest vertice on base of primitive and remember its position
- // prepare second layer's projection ...
- // get viewer placement from first layer
- CPlacement3D plVirtualViewer = prProjection->ViewerPlacementR();
- // transform it to the system of the second layer
- plVirtualViewer.AbsoluteToRelative(pDoc->m_plSecondLayer);
- // use it in projection for second layer
- CAnyProjection3D prProjectionSecondLayer;
- prProjectionSecondLayer = prProjection;
- prProjectionSecondLayer->ViewerPlacementL() = plVirtualViewer;
- prProjectionSecondLayer->Prepare();
- // find and remember vertex on primitive base for draging
- MarkClosestVtxAndEdgeOnPrimitiveBase( point);
- m_iSizeControlVertice = -1;
- FLOAT fMinDistance = 9999999.9f;
- // prepare array with vertices used as control points for sizing box arround primitive
- FLOAT3D avtxSizeControlVertices[ 14];
- // table of min x, max x, miny, ...
- FLOAT afCoordinates[ 6];
- afCoordinates[0] = theApp.m_vfpCurrent.vfp_fXMin;
- afCoordinates[1] = theApp.m_vfpCurrent.vfp_fXMax;
- afCoordinates[2] = theApp.m_vfpCurrent.vfp_fYMin;
- afCoordinates[3] = theApp.m_vfpCurrent.vfp_fYMax;
- afCoordinates[4] = theApp.m_vfpCurrent.vfp_fZMin;
- afCoordinates[5] = theApp.m_vfpCurrent.vfp_fZMax;
- // create control points using table with indices into afCoordinates table
- for( INDEX iVtx=0;iVtx<14;iVtx++)
- {
- avtxSizeControlVertices[iVtx](1) =
- (afCoordinates[aiForCreationOfSizingVertices[iVtx][0]]+
- afCoordinates[aiForCreationOfSizingVertices[iVtx][1]])/2;
- avtxSizeControlVertices[iVtx](2) =
- (afCoordinates[aiForCreationOfSizingVertices[iVtx][2]]+
- afCoordinates[aiForCreationOfSizingVertices[iVtx][3]])/2;
- avtxSizeControlVertices[iVtx](3) =
- (afCoordinates[aiForCreationOfSizingVertices[iVtx][4]]+
- afCoordinates[aiForCreationOfSizingVertices[iVtx][5]])/2;
- }
- // now we will project size control vertices and try to find closest one to mouse
- for( INDEX iControlVtx=0; iControlVtx<14; iControlVtx++)
- {
- FLOAT3D vProjectedCoordinate;
- // project current control vertex
- prProjectionSecondLayer->ProjectCoordinate(
- avtxSizeControlVertices[iControlVtx], vProjectedCoordinate);
- // convert y coordinate from mathemathical representation into screen one
- vProjectedCoordinate(2) = pdpValidDrawPort->GetHeight() - vProjectedCoordinate(2);
- FLOAT fDX = vProjectedCoordinate(1)-point.x;
- FLOAT fDY = vProjectedCoordinate(2)-point.y;
- // calculate distance to mouse point
- FLOAT fDistance = fDX*fDX+fDY*fDY;
- // if this distance is smaller than last remembered
- if( fDistance < fMinDistance)
- {
- // set this one as smallest
- fMinDistance = fDistance;
- // and remember its indice as souch
- m_iSizeControlVertice = iControlVtx;
- }
- }
- }
- }
- // reset relative placement (m_plMouseOffset)
- StartMouseInput( point);
- }
- // if only Alt key is pressed, we are not in vertex nor entity mode, we want to save thumbnail
- else if( bAlt && !bCtrl && !bShift && !bSpace &&
- (pDoc->GetEditingMode() != VERTEX_MODE) &&
- (pDoc->GetEditingMode() != ENTITY_MODE))
- {
- // if document is modified
- if( pDoc->IsModified() )
- {
- // report error
- AfxMessageBox(L"You must save your document before you can perform drag.");
- }
- else
- {
- CTFileName fnDocument = CTString(CStringA(pDoc->GetPathName()));
- // save the thumbnail
- pDoc->SaveThumbnail();
- // try to
- try
- {
- // remove application path
- fnDocument.RemoveApplicationPath_t();
- // create drag and drop object
- HGLOBAL hglobal = CreateHDrop( fnDocument);
- m_DataSource.CacheGlobalData( CF_HDROP, hglobal);
- m_DataSource.DoDragDrop( DROPEFFECT_COPY);
- }
- // if failed
- catch (char *strError)
- {
- // report error
- AfxMessageBox(CString(strError));
- }
- }
- }
- // else if we are in entity mode
- else if( pDoc->GetEditingMode() == ENTITY_MODE)
- {
- // if ctrl pressed, we want to move or rotate entity selection
- if( bCtrl && !bShift && !bAlt)
- {
- if( bRMB) m_iaInputAction = IA_ROTATING_ENTITY_SELECTION;
- else m_iaInputAction = IA_MOVING_ENTITY_SELECTION_IN_FLOOR_PLANE;
- StartMouseInput( point);
- }
- // if we are in browsing entities mode (or select by volume)
- else if( (pDoc->m_bBrowseEntitiesMode) &&
- (m_ptProjectionType != CSlaveViewer::PT_PERSPECTIVE) )
- {
- m_iaInputAction = IA_SIZING_SELECT_BY_VOLUME_BOX;
- // ------ Find closest vertice of volume box
- // create a slave viewer
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pdpValidDrawPort);
- // create a projection for current viewer
- CAnyProjection3D prProjection;
- svViewer.MakeProjection(prProjection);
- // prepare the projection
- prProjection->Prepare();
- // set distance of closest vertice to a hudge distance
- FLOAT fMinVertexDistance = 999999.9f;
- pDoc->m_iVolumeBoxDragVertice = 0;
- // now we will project volume box's vertices onto screen and find closest one to mouse
- for( INDEX iVtx=0; iVtx<8; iVtx++)
- {
- FLOAT3D vProjectedCoordinate;
- // project current base vertice
- prProjection->ProjectCoordinate( pDoc->m_avVolumeBoxVertice[iVtx], vProjectedCoordinate);
- // convert y coordinate from mathemathical representation into screen one
- vProjectedCoordinate(2) = pdpValidDrawPort->GetHeight() - vProjectedCoordinate(2);
- // reset on screen "z" coordinate
- vProjectedCoordinate(3) = 0.0f;
- // calculate distance to mouse point
- FLOAT fDistance =
- ( FLOAT3D((FLOAT)point.x, (FLOAT)point.y, 0.0f) - vProjectedCoordinate ).Length();
- // if this distance is smaller than last remembered
- if( fDistance < fMinVertexDistance)
- {
- // set this one as smallest
- fMinVertexDistance = fDistance;
- // and remember its indice as souch
- pDoc->m_iVolumeBoxDragVertice = iVtx;
- }
- }
- // when we found closest vertice, remember its current position
- pDoc->m_vVolumeBoxStartDragVertice = pDoc->m_avVolumeBoxVertice[ pDoc->m_iVolumeBoxDragVertice];
- // reset relative placement (m_plMouseOffset)
- StartMouseInput( point);
- }
- // ctrl+shift+lmb is used to edit range and angle3d properties
- else if( bCtrl && bShift)
- {
- if( pDoc->m_selEntitySelection.Count() != 0)
- {
- // get selected property
- CPropertyID *ppid = pMainFrame->m_PropertyComboBar.GetSelectedProperty();
- // if property is of range or angle3d type
- if( (ppid != NULL) && (ppid->pid_eptType == CEntityProperty::EPT_RANGE) )
- {
- m_iaInputAction = IA_CHANGING_RANGE_PROPERTY;
- }
- if( (ppid != NULL) && (ppid->pid_eptType == CEntityProperty::EPT_ANGLE3D) )
- {
- m_iaInputAction = IA_CHANGING_ANGLE3D_PROPERTY;
- }
- }
- }
- // Alt+Ctrl+LMB requests that clicked entity becomes target to selected entity
- else if( bAlt && bCtrl && (crRayHit.cr_penHit != NULL))
- {
- if( pDoc->m_selEntitySelection.Count() == 0)
- {
- SetAsCsgTarget(crRayHit.cr_penHit);
- }
- else
- {
- // get selected property
- CPropertyID *ppid = pMainFrame->m_PropertyComboBar.GetSelectedProperty();
- if( (ppid == NULL) ||
- !((ppid->pid_eptType == CEntityProperty::EPT_ENTITYPTR) ||
- (ppid->pid_eptType == CEntityProperty::EPT_PARENT)) ) return;
- BOOL bParentProperty = ppid->pid_eptType == CEntityProperty::EPT_PARENT;
- // for each of the selected entities
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- if( bParentProperty)
- {
- iten->SetParent( crRayHit.cr_penHit);
- }
- else if (crRayHit.cr_penHit->IsTargetable())
- {
- // obtain entity class ptr
- CDLLEntityClass *pdecDLLClass = iten->GetClass()->ec_pdecDLLClass;
- // for all classes in hierarchy of this entity
- for(;
- pdecDLLClass!=NULL;
- pdecDLLClass = pdecDLLClass->dec_pdecBase) {
- // for all properties
- for(INDEX iProperty=0; iProperty<pdecDLLClass->dec_ctProperties; iProperty++) {
- CEntityProperty &epProperty = pdecDLLClass->dec_aepProperties[iProperty];
- if( (ppid->pid_strName == epProperty.ep_strName) &&
- (ppid->pid_eptType == epProperty.ep_eptType) )
- {
- // discard old entity settings
- iten->End();
- // set clicked entity as one that selected entity points to
- ENTITYPROPERTY( &*iten, epProperty.ep_slOffset, CEntityPointer) = crRayHit.cr_penHit;
- // apply new entity settings
- iten->Initialize();
- }
- }
- }
- }
- }
- // update edit range control (by updating parent dialog)
- pMainFrame->m_PropertyComboBar.UpdateData( FALSE);
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- }
- }
- // we want to select entities
- else
- {
- m_iaInputAction = IA_SELECTING_ENTITIES;
- m_bOnSelectEntityShiftDown = bShift;
- m_bOnSelectEntityAltDown = bAlt;
- }
- }
- // else if we are in sector mode
- else if( pDoc->GetEditingMode() == SECTOR_MODE)
- {
- m_iaInputAction = IA_SELECTING_SECTORS;
- ToggleHittedSector( crRayHit);
- }
- // if we are in polygon mode
- else if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- // Alt+Ctrl+LMB requests that clicked polygon sizes its texture
- if( bAlt && bCtrl && !bShift)
- {
- MultiplyMappingOnPolygon( 0.5f);
- }
- else if( bAlt && bCtrl && bShift)
- {
- OnRemainSelectedByOrientation(FALSE);
- }
- if( bAlt && bShift)
- {
- OnRemainSelectedByOrientation(TRUE);
- }
- // if we hit polygon
- else if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- // if we want to change polygon mapping
- if( bCtrl && !bShift)
- {
- if( bRMB) m_iaInputAction = IA_ROTATING_POLYGON_MAPPING;
- else m_iaInputAction = IA_MOVING_POLYGON_MAPPING;
- StartMouseInput( point);
- // remember hitted point
- m_f3dRotationOrigin = crRayHit.cr_vHit;
- m_plMouseMove.pl_PositionVector = crRayHit.cr_vHit;
- m_plMouseMove.pl_OrientationAngle = ANGLE3D( 0, 0, 0);
- m_pbpoTranslationPlane = crRayHit.cr_pbpoBrushPolygon;
- m_plTranslationPlane = crRayHit.cr_pbpoBrushPolygon->bpo_pbplPlane->bpl_plAbsolute;
- }
- // select or deselect hitted polygon
- else if( !bCtrl)
- {
- m_iaInputAction = IA_SELECTING_POLYGONS;
- ToggleHittedPolygon( crRayHit);
- }
- }
- }
- // if we are in vertex mode
- else if( pDoc->GetEditingMode() == VERTEX_MODE)
- {
- // Ctrl+Alt is used to add vertex
- if( bCtrl && bAlt)
- {
- CBrushPolygon *pbpo = crRayHit.cr_pbpoBrushPolygon;
- if( (crRayHit.cr_penHit != NULL) && (pbpo != NULL) )
- {
- pDoc->m_selPolygonSelection.Clear();
- pDoc->m_selVertexSelection.Clear();
- pbpo->bpo_pbscSector->TriangularizePolygon( pbpo);
- pDoc->m_chSelections.MarkChanged();
- // cast ray again to hit newly created triangle
- CCastRay crRayHit = GetMouseHitInformation( point, FALSE, bHitModels, bHitFields);
- CBrushPolygon *pbpo = crRayHit.cr_pbpoBrushPolygon;
- if( (crRayHit.cr_penHit != NULL) && (pbpo != NULL) )
- {
- pDoc->m_selPolygonSelection.Select( *pbpo);
- pbpo->bpo_pbscSector->InsertVertexIntoTriangle( pDoc->m_selPolygonSelection, crRayHit.cr_vHit);
- }
- }
- }
- // Ctrl is used for rotating or moving vertices
- else if( bCtrl)
- {
- if( bShift)
- {
- m_iaInputAction = IA_STRETCH_BRUSH_VERTEX;
- }
- else if( bRMB)
- {
- m_iaInputAction = IA_ROTATE_BRUSH_VERTEX;
- }
- else
- {
- m_iaInputAction = IA_DRAG_BRUSH_VERTEX_IN_FLOOR_PLANE;
- }
- // clear polygon selection because some of the old polygons could disappear
- pDoc->m_selPolygonSelection.Clear();
- pDoc->m_woWorld.TriangularizeForVertices( pDoc->m_selVertexSelection);
- StartMouseInput( point);
- }
- else
- {
- m_avpixLaso.Clear();
- m_iaInputAction = IA_SELECT_SINGLE_BRUSH_VERTEX;
- _vpixSelectNearPoint(1) = point.x;
- _vpixSelectNearPoint(2) = point.y;
- m_bOnSelectVertexShiftDown = bShift;
- m_bOnSelectVertexAltDown = bAlt;
- }
- }
- else if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- if(crRayHit.cr_penHit!=NULL && crRayHit.cr_penHit==GetTerrainEntity())
- {
- _bCursorMoved=FALSE;
- if( bAlt && bCtrl)
- {
- OnPickLayer();
- }
- else if( !bAlt && bCtrl)
- {
- m_iaInputAction = IA_TERRAIN_EDITING_CTRL_LMB;
- _tvLastTerrainBrushingApplied=_pTimer->GetHighPrecisionTimer();
- }
- else if( !bAlt)
- {
- m_iaInputAction = IA_TERRAIN_EDITING_LMB;
- _tvLastTerrainBrushingApplied=_pTimer->GetHighPrecisionTimer();
- }
- }
- else
- {
- // if terrain entity hit
- if(crRayHit.cr_penHit!=NULL && crRayHit.cr_penHit->GetRenderType()==CEntity::RT_TERRAIN)
- {
- pDoc->m_ptrSelectedTerrain=crRayHit.cr_penHit->GetTerrain();
- theApp.m_ctTerrainPage.MarkChanged();
- }
- }
- }
- CView::OnLButtonDown(nFlags, point);
- }
- void SelectLayerCommand(INDEX iSelectedLayer)
- {
- SelectLayer(iSelectedLayer);
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- CWorldEditorDoc* pDoc = theApp.GetActiveDocument();
- if(pDoc!=NULL)
- {
- pDoc->m_chSelections.MarkChanged();
- }
- }
- void CWorldEditorView::InvokeSelectLayerCombo(void)
- {
- CPoint pt=m_ptMouse;
- CCastRay crRayHit=GetMouseHitInformation( pt);
- if( (crRayHit.cr_penHit==NULL) || (crRayHit.cr_penHit->GetRenderType()!=CEntity::RT_TERRAIN) ) return;
- CCustomComboWnd *pCombo=new CCustomComboWnd;
- CTerrain *ptrTerrain=crRayHit.cr_penHit->GetTerrain();
- if(ptrTerrain==NULL) return;
- INDEX ctLayers=ptrTerrain->tr_atlLayers.Count();
- for(INDEX iLayer=ctLayers-1; iLayer>=0; iLayer--)
- {
- CTString strLayerName;
- UBYTE ubPower=GetValueFromMask(ptrTerrain, iLayer, crRayHit.cr_vHit);
- strLayerName.PrintF("Layer %d (%d%%)", iLayer+1, INDEX(ubPower/255.0f*100.0f));
- if(ubPower>0)
- {
- INDEX iAddedAs=pCombo->InsertItem( strLayerName);
- pCombo->SetItemValue( iAddedAs, iLayer);
- }
- if(ubPower==255) break;
- }
- GetCursorPos( &pt);
- pCombo->Initialize(NULL, SelectLayerCommand, pt.x-8, pt.y-8, TRUE);
- }
- void CWorldEditorView::OnRButtonDown(UINT nFlags, CPoint point)
- {
- if( m_iaInputAction != IA_MIP_SETTING) m_iaInputAction = IA_NONE;
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- BOOL bShift = nFlags & MK_SHIFT;
- BOOL bCtrl = nFlags & MK_CONTROL;
- BOOL bLMB = nFlags & MK_LBUTTON;
- BOOL bCSGOn = pDoc->m_pwoSecondLayer != NULL;
- BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0;
- BOOL bSpace = (GetKeyState( VK_SPACE)&0x8000) != 0;
- BOOL bCaps = (GetKeyState( VK_CAPITAL)&0x0001) != 0;
- BOOL bHitModels = (pDoc->GetEditingMode() == ENTITY_MODE) || bSpace;
- BOOL bHitFields = (pDoc->GetEditingMode() == ENTITY_MODE) || bSpace;
- StartMouseInput( point);
- // remember point in the view
- m_ptMouseDown = point;
- // remember values for primitive
- m_VFPMouseDown = theApp.m_vfpCurrent;
- // if nothing of below is activated, call popup menu
- if( !bShift && !bAlt && !bCtrl && !bSpace && !bLMB)
- {
- CallPopupMenu( point);
- }
- // space+ctrl+lmb zoomes out 2x
- else if( bSpace && bCtrl)
- {
- if( bLMB) return;
- OnZoomLess();
- return;
- }
- else if( bSpace && bLMB)
- {
- m_iaInputAction = IA_ROTATING_VIEWER;
- }
- // we have viewer movement in view plane
- else if( bSpace && !bShift)
- {
- if( bSpace) m_iaInputAction = IA_MOVING_VIEWER_IN_VIEW_PLANE;
- StartMouseInput( point);
- }
- // second layer movements
- else if( bCSGOn)
- {
- // if ctrl+rmb pressed, we want to move second layer in view plane
- if( bCtrl && !bShift)
- {
- if( bLMB) m_iaInputAction = IA_ROTATING_SECOND_LAYER;
- else m_iaInputAction = IA_MOVING_SECOND_LAYER_IN_VIEW_PLANE;
- StartMouseInput( point);
- }
- // test for mouse operations used while primitive CSG is on
- else if( pDoc->m_bPrimitiveMode)
- {
- // ctrl+shift+rmb sheares primitive
- if( bCtrl && bShift)
- {
- if( m_ptProjectionType != CSlaveViewer::PT_PERSPECTIVE)
- m_iaInputAction = IA_SHEARING_PRIMITIVE;
- }
- // shift+rmb in deletes vertex on base of primitive
- else if( bShift && !bCtrl && !bLMB && !bSpace)
- {
- MarkClosestVtxAndEdgeOnPrimitiveBase( point);
- if( m_iDragVertice != -1) pDoc->DeletePrimitiveVertex( m_iDragVertice);
- }
- }
- }
- else if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- // measure and cut modes disable all functions
- if( theApp.m_bMeasureModeOn || theApp.m_bCutModeOn)
- {
- }
- if( bAlt && bShift)
- {
- OnDeselectByOrientation();
- }
- // alt+ctrl+rmb sizes polygon's texture
- else if( bAlt && bCtrl)
- {
- MultiplyMappingOnPolygon( 2.0f);
- }
- else if( bCtrl && bLMB)
- {
- m_iaInputAction = IA_ROTATING_POLYGON_MAPPING;
- }
- // shift turns on portal testing
- else if( bShift && !bCtrl)
- {
- m_iaInputAction = IA_SELECTING_POLYGONS;
- // cast ray but ask if test for portal hits
- CCastRay crRayHit = GetMouseHitInformation( point, TRUE, FALSE);
- ToggleHittedPolygon( crRayHit);
- }
- }
- else if( pDoc->GetEditingMode() == SECTOR_MODE)
- {
- // shift turns on portal testing
- if( bShift)
- {
- m_iaInputAction = IA_SELECTING_SECTORS;
- // cast ray but ask if test for portal hits
- CCastRay crRayHit = GetMouseHitInformation( point, TRUE, FALSE);
- ToggleHittedSector( crRayHit);
- }
- }
- else if(pDoc->GetEditingMode() == ENTITY_MODE)
- {
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CEntity *penBrush = pMainFrame->m_CSGDesitnationCombo.GetSelectedBrushEntity();
- // if we should start mip setting mode
- if( bShift && bCtrl && !bAlt && (penBrush != NULL) )
- {
- if( m_iaInputAction == IA_MIP_SETTING) return;
- // get entity's brush
- CBrush3D *pbrBrush = penBrush->GetBrush();
- if( pbrBrush != NULL)
- {
- CChildFrame *pChild = GetChildFrame();
- // set auto mip brushing mode as it was before mip setting started
- pChild->m_bLastAutoMipBrushingOn = pChild->m_bAutoMipBrushingOn;
- // get curently active mip factor
- FLOAT fCurrentMipFactor = GetCurrentlyActiveMipFactor();
- // get the mip brush for current factor
- m_pbmToSetMipSwitch = pbrBrush->GetBrushMipByDistance(fCurrentMipFactor);
- // if we are in automatic mip brushing mode
- if( (GetChildFrame()->m_bAutoMipBrushingOn) && (m_pbmToSetMipSwitch != NULL) )
- {
- // set manual mip factor so current mip brush would be visible
- GetChildFrame()->m_fManualMipBrushingFactor = fCurrentMipFactor;
- // set manual mip brushing mode
- GetChildFrame()->m_bAutoMipBrushingOn = FALSE;
- m_iaInputAction = IA_MIP_SETTING;
- }
- else
- {
- m_iaInputAction = IA_NONE;
- }
- }
- else
- {
- m_iaInputAction = IA_NONE;
- }
- }
- // Alt+Ctrl+RMB sets clicked entity as target on first available free target ptr slot
- else if( bAlt && bCtrl && !bShift && (pDoc->m_selEntitySelection.Count() != 0))
- {
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( point, FALSE, bHitModels, bHitFields);
- if(crRayHit.cr_penHit != NULL)
- {
- // get first empty selected property
- pMainFrame->m_PropertyComboBar.SetFirstValidEmptyTargetProperty( crRayHit.cr_penHit);
- }
- }
- // if ctrl+rmb pressed, we want to move entity selection in view plane
- else if( bCtrl && !bShift && !bAlt)
- {
- if( bLMB) m_iaInputAction = IA_ROTATING_ENTITY_SELECTION;
- else m_iaInputAction = IA_MOVING_ENTITY_SELECTION_IN_VIEW_PLANE;
- StartMouseInput( point);
- }
- else if( bShift && bSpace && !GetChildFrame()->m_bAutoMipBrushingOn)
- {
- m_iaInputAction = IA_MANUAL_MIP_SWITCH_FACTOR_CHANGING;
- }
- else if( bShift && bAlt)
- {
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( point, FALSE, bHitModels, bHitFields);
- ShowLinkTree(crRayHit.cr_penHit, TRUE, bCaps);
- }
- else if( bShift)
- {
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( point, FALSE, bHitModels, bHitFields);
- ShowLinkTree(crRayHit.cr_penHit, FALSE, bCaps);
- }
- }
- // if we are in vertex mode
- else if( pDoc->GetEditingMode() == VERTEX_MODE)
- {
- if( bCtrl)
- {
- if( bLMB)
- {
- m_iaInputAction = IA_ROTATE_BRUSH_VERTEX;
- }
- else
- {
- m_iaInputAction = IA_DRAG_BRUSH_VERTEX_IN_VIEW_PLANE;
- }
- // clear polygon selection because some of the old polygons could disappear
- pDoc->m_selPolygonSelection.Clear();
- pDoc->m_woWorld.TriangularizeForVertices( pDoc->m_selVertexSelection);
- StartMouseInput( point);
- }
- if( bShift)
- {
- if(pDoc->m_selVertexSelection.Count()==3)
- {
- pDoc->m_woWorld.CreatePolygon(pDoc->m_selVertexSelection);
- pDoc->ClearSelections();
- }
- }
- }
- // if we are in terrain mode
- else if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- InvokeSelectLayerCombo();
- }
- CView::OnRButtonDown(nFlags, point);
- }
- void CWorldEditorView::OnLButtonUp(UINT nFlags, CPoint point)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- BOOL bShift = nFlags & MK_SHIFT;
- BOOL bSpace = (GetKeyState( VK_SPACE)&0x8000) != 0;
- BOOL bCtrl = (GetKeyState( VK_CONTROL)&0x8000) != 0;
- BOOL bCSGOn = pDoc->m_pwoSecondLayer != NULL;
- StopMouseInput();
- // if measure mode on
- if( theApp.m_bMeasureModeOn)
- {
- Invalidate( FALSE);
- }
- // if we are in browse by volume mode and lmb released, refresh first selected volume
- if( pDoc->m_bBrowseEntitiesMode && !bSpace && !bCtrl)
- {
- pDoc->SelectEntitiesByVolumeBox();
- }
- if( pDoc->GetEditingMode() == ENTITY_MODE)
- {
- if( m_iaInputAction == IA_SELECTING_ENTITIES)
- {
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( point, FALSE, TRUE, TRUE);
- // if we hit some entity
- if( crRayHit.cr_penHit != NULL)
- {
- // if shift is not pressed
- if( !bShift)
- {
- BOOL bWasSelected = crRayHit.cr_penHit->IsSelected( ENF_SELECTED);
- // deselect all selected entities
- INDEX ctSelectedBefore = pDoc->m_selEntitySelection.Count();
- pDoc->m_selEntitySelection.Clear();
- // if entity was not selected before
- if( !((ctSelectedBefore == 1) && bWasSelected))
- {
- // select it
- pDoc->m_selEntitySelection.Select( *crRayHit.cr_penHit);
- }
- }
- else
- {
- // if entity is not yet selected
- if( !crRayHit.cr_penHit->IsSelected( ENF_SELECTED))
- {
- // select it
- pDoc->m_selEntitySelection.Select( *crRayHit.cr_penHit);
- }
- // otherwise deselect it
- else
- {
- pDoc->m_selEntitySelection.Deselect( *crRayHit.cr_penHit);
- }
- }
- }
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- // and refresh property combo manualy calling on idle
- pMainFrame->m_PropertyComboBar.m_PropertyComboBox.OnIdle( 0);
- // update all views
- pDoc->UpdateAllViews( this);
- }
- else if( m_iaInputAction == IA_SELECT_LASSO_ENTITY)
- {
- m_bRequestEntityLassoSelect = TRUE;
- pDoc->m_chSelections.MarkChanged();
- Invalidate( FALSE);
- }
- }
- if( pDoc->GetEditingMode() == VERTEX_MODE)
- {
- if( m_iaInputAction == IA_SELECT_SINGLE_BRUSH_VERTEX)
- {
- m_bRequestVtxClickSelect = TRUE;
- pDoc->m_chSelections.MarkChanged();
- Invalidate( FALSE);
- }
- else if( m_iaInputAction == IA_SELECT_LASSO_BRUSH_VERTEX)
- {
- m_bRequestVtxLassoSelect = TRUE;
- pDoc->m_chSelections.MarkChanged();
- Invalidate( FALSE);
- }
- else if(
- (m_iaInputAction == IA_DRAG_BRUSH_VERTEX_IN_FLOOR_PLANE) ||
- (m_iaInputAction == IA_DRAG_BRUSH_VERTEX_IN_VIEW_PLANE) ||
- (m_iaInputAction == IA_STRETCH_BRUSH_VERTEX) ||
- (m_iaInputAction == IA_ROTATE_BRUSH_VERTEX) )
- {
- pDoc->m_woWorld.UpdateSectorsAfterVertexChange( pDoc->m_selVertexSelection);
- }
- }
- m_iaInputAction = IA_NONE;
- CView::OnLButtonUp(nFlags, point);
- }
- void CWorldEditorView::OnRButtonUp(UINT nFlags, CPoint point)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( m_iaInputAction == IA_MIP_SETTING)
- {
- SetMipBrushFactor();
- }
- else if(
- (m_iaInputAction == IA_DRAG_BRUSH_VERTEX_IN_FLOOR_PLANE) ||
- (m_iaInputAction == IA_DRAG_BRUSH_VERTEX_IN_VIEW_PLANE) ||
- (m_iaInputAction == IA_STRETCH_BRUSH_VERTEX) ||
- (m_iaInputAction == IA_ROTATE_BRUSH_VERTEX) )
- {
- pDoc->m_woWorld.UpdateSectorsAfterVertexChange( pDoc->m_selVertexSelection);
- }
- m_iaInputAction = IA_NONE;
- StopMouseInput();
- CView::OnRButtonUp(nFlags, point);
- }
- // select all descendents of selected entity
- void SelectDescendents( CEntitySelection &selEntity, CEntity &enParent)
- {
- FOREACHINLIST( CEntity, en_lnInParent, enParent.en_lhChildren, itenChild)
- {
- SelectDescendents( selEntity, *itenChild);
- }
- if( !enParent.IsSelected( ENF_SELECTED))
- {
- selEntity.Select( enParent);
- }
- }
- void CWorldEditorView::OnLButtonDblClk(UINT nFlags, CPoint point)
- {
- m_iaInputAction = IA_NONE;
- CWorldEditorDoc* pDoc = GetDocument();
- BOOL bSpace = (GetKeyState( ' ') & 128) != 0;
- BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0;
- BOOL bCtrl = nFlags & MK_CONTROL;
- BOOL bShift = nFlags & MK_SHIFT;
- BOOL bRMB = (GetKeyState( VK_RBUTTON)&0x8000) != 0;
- // space+ctrl+lmb zoomes in 2x
- if( (bSpace) && (bCtrl))
- {
- if( bRMB) return;
- // set new target
- GetChildFrame()->m_mvViewer.SetTargetPlacement( m_vHitOnMouseDown);
- // move mouse to center of screen
- CPoint ptCenter = CPoint( m_pdpDrawPort->GetWidth()/2, m_pdpDrawPort->GetHeight()/2);
- ClientToScreen( &ptCenter);
- SetCursorPos(ptCenter.x, ptCenter.y);
- OnZoomMore();
- pDoc->UpdateAllViews( NULL);
- return;
- }
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( point);
- // space + doubble click center point that mouse points to
- if( bSpace)
- {
- // set new target
- GetChildFrame()->m_mvViewer.SetTargetPlacement( crRayHit.cr_vHit);
- // update all views
- pDoc->UpdateAllViews( NULL);
- }
- // if we are in measure or cut mode, no operation
- else if( theApp.m_bMeasureModeOn || theApp.m_bCutModeOn)
- {
- }
- // if we are in sector mode, no operation
- else if( pDoc->GetEditingMode() == SECTOR_MODE)
- {
- }
- // if we are in polygon mode, select similar polygons
- else if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- // Alt+Ctrl+RMB requests that clicked polygon sizes its texture
- if( bAlt && bCtrl)
- {
- MultiplyMappingOnPolygon( 0.5f);
- }
- // if we hit some brush entity
- else if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL))
- {
- // if shift is not pressed, delelect all polygons
- if( !bShift && !bCtrl)
- {
- pDoc->m_selPolygonSelection.Clear();
- }
- // LMBx2 centers mapping on polygon
- if( bCtrl && !bShift &&(crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- CBrushPolygon &bpo = *crRayHit.cr_pbpoBrushPolygon;
- CEntity *pen = bpo.bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush->br_penEntity;
- CMappingDefinition mdOriginal = bpo.bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping;
- CMappingDefinition mdTranslated = mdOriginal;
- CSimpleProjection3D pr;
- pr.ObjectPlacementL() = _plOrigin;
- pr.ViewerPlacementL() = pen->GetPlacement();
- pr.Prepare();
- FLOAT3D vRelative;
- pr.ProjectCoordinate(crRayHit.cr_vHit, vRelative);
- CMappingDefinition mdRelative = theApp.m_mdMapping;
- mdTranslated.Center(bpo.bpo_pbplPlane->bpl_pwplWorking->wpl_mvRelative, vRelative);
- FLOAT fUOffset = mdTranslated.md_fUOffset-mdOriginal.md_fUOffset;
- FLOAT fVOffset = mdTranslated.md_fVOffset-mdOriginal.md_fVOffset;
- if( !crRayHit.cr_pbpoBrushPolygon->IsSelected(BPOF_SELECTED))
- {
- // add the offsets to its mapping
- crRayHit.cr_pbpoBrushPolygon->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.md_fUOffset+=fUOffset;
- crRayHit.cr_pbpoBrushPolygon->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.md_fVOffset+=fVOffset;
- }
- else
- {
- // for each selected polygon
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- // add the offsets to its mapping
- itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.md_fUOffset+=fUOffset;
- itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.md_fVOffset+=fVOffset;
- }
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- // Ctrl+Shift+LMBx2 slects similar by texture in sector
- else if( bCtrl && bShift)
- {
- OnSelectByTextureInSector();
- }
- else
- {
- // select similar to hitted polygon
- crRayHit.cr_pbpoBrushPolygon->SelectSimilarByColor( pDoc->m_selPolygonSelection);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- }
- }
- else if( pDoc->GetEditingMode() == VERTEX_MODE)
- {
- // if we hit some polygon
- if( (crRayHit.cr_penHit != NULL) && (crRayHit.cr_pbpoBrushPolygon != NULL))
- {
- CBrushPolygon &bpo=*crRayHit.cr_pbpoBrushPolygon;
- // select vertices
- FOREACHINSTATICARRAY(bpo.bpo_apbvxTriangleVertices, CBrushVertex *, itpbvx)
- {
- if( !(*itpbvx)->IsSelected(BVXF_SELECTED)) pDoc->m_selVertexSelection.Select( **itpbvx);
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- }
- // if we are in entity mode
- else if( pDoc->GetEditingMode() == ENTITY_MODE)
- {
- // if nothing pressed
- if( !bCtrl && !bAlt && !bSpace)
- {
- if( crRayHit.cr_penHit != NULL)
- {
- SelectDescendents( pDoc->m_selEntitySelection, *crRayHit.cr_penHit);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- }
- // CTRL + LMB teleports entities
- if( (pDoc->m_selEntitySelection.Count() != 0) && (bCtrl) && (!bAlt) )
- {
- // lock selection's dynamic container
- pDoc->m_selEntitySelection.Lock();
- FLOATaabbox3D box;
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- box |= iten->GetPlacement().pl_PositionVector;
- }}
- FLOAT3D f3dCenter = box.Center();
- f3dCenter(2) = box.Min()(2);
- FLOAT3D f3dOffset = crRayHit.cr_vHit - f3dCenter;
- CEntity *penBrush = NULL;
- // for each of the selected entities
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- if (iten->en_RenderType == CEntity::RT_BRUSH) {
- penBrush = &*iten;
- }
- // if movement of anchored entities is allowed or entity is not anchored
- if( (((iten->GetFlags() & ENF_ANCHORED) == 0) ||
- (GetChildFrame()->m_bAncoredMovingAllowed)) &&
- ((iten->GetParent()==NULL) || !(iten->GetParent()->IsSelected( ENF_SELECTED))) )
- {
- // get placement of current entity
- CPlacement3D plEntityPlacement = iten->GetPlacement();
- plEntityPlacement.pl_PositionVector += f3dOffset;
- // snap to grid entity's placement
- pDoc->SnapToGrid( plEntityPlacement, m_fGridInMeters/GRID_DISCRETE_VALUES);
- // set placement back to entity
- iten->SetPlacement( plEntityPlacement);
- // mark that document is changed
- pDoc->SetModifiedFlag();
- }
- if( penBrush != NULL)
- {
- DiscardShadows( penBrush);
- }
- }
- }
- pDoc->UpdateAllViews( NULL);
- // refresh position page
- pDoc->RefreshCurrentInfoPage();
- }
- // if we are in csg mode, CTRL + LMB teleports second layer's world (primitive)
- else if( (pDoc->GetEditingMode() == CSG_MODE) && bCtrl)
- {
- // set new placement of second layer
- pDoc->m_plSecondLayer.pl_PositionVector = crRayHit.cr_vHit;
- // snap to grid whole second layer's placement
- pDoc->SnapToGrid( pDoc->m_plSecondLayer, m_fGridInMeters/GRID_DISCRETE_VALUES);
- theApp.m_vfpCurrent.vfp_plPrimitive = pDoc->m_plSecondLayer;
- // refresh all views
- pDoc->UpdateAllViews( NULL);
- // refresh position page
- pDoc->RefreshCurrentInfoPage();
- }
- CView::OnLButtonDblClk(nFlags, point);
- }
- void CWorldEditorView::CallPopupMenu(CPoint point)
- {
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- BOOL bHitFields = (pDoc->GetEditingMode() == ENTITY_MODE);
- // obtain information about where mouse pointed into the world in the moment of mouse down
- CCastRay crRayHitOnContext = GetMouseHitInformation( point, FALSE, TRUE, bHitFields);
- // create popup menu
- CMenu menu;
- INDEX iMenuID;
- // choose popup menu
- switch( pDoc->GetEditingMode())
- {
- case POLYGON_MODE:{ iMenuID = IDR_POLYGON_POPUP; break; }
- case SECTOR_MODE:{ iMenuID = IDR_SECTOR_POPUP;break; }
- case VERTEX_MODE:{ iMenuID = IDR_VERTEX_POPUP;break; }
- case ENTITY_MODE:{ iMenuID = IDR_ENTITY_POPUP;break; }
- case TERRAIN_MODE:{ iMenuID = IDR_TERRAIN_POPUP;break; }
- case CSG_MODE:
- {
- if( pDoc->m_bPrimitiveMode) iMenuID = IDR_CSG_PRIMITIVE_POPUP;
- else iMenuID = IDR_CSG_TEMPLATE_POPUP;
- break;
- }
- default: { FatalError("Unknown editing mode."); break;};
- }
- // load popup menu
- if( menu.LoadMenu(iMenuID))
- {
- BOOL bEntityClicked = FALSE;
- BOOL bBrushClicked = FALSE;
- BOOL bSecondLayerHited = FALSE;
- BOOL bPortalClicked = FALSE;
- m_penEntityHitOnContext = NULL;
- if( crRayHitOnContext.cr_penHit != NULL)
- {
- m_penEntityHitOnContext = crRayHitOnContext.cr_penHit;
- bEntityClicked = TRUE;
- // test if we hited second layer
- if( crRayHitOnContext.cr_penHit->GetWorld() != &pDoc->m_woWorld)
- {
- bSecondLayerHited = TRUE;
- }
- m_plEntityHitOnContext = crRayHitOnContext.cr_penHit->GetPlacement();
- m_plEntityHitOnContext.pl_PositionVector = crRayHitOnContext.cr_vHit;
- CEntity::RenderType rt = crRayHitOnContext.cr_penHit->GetRenderType();
- if( rt==CEntity::RT_BRUSH || rt==CEntity::RT_FIELDBRUSH)
- {
- bBrushClicked = TRUE;
- }
- m_pbpoRightClickedPolygon = crRayHitOnContext.cr_pbpoBrushPolygon;
- if( m_pbpoRightClickedPolygon != NULL)
- {
- bPortalClicked = m_pbpoRightClickedPolygon->bpo_ulFlags & BPOF_PORTAL;
- }
- }
- // remember if we hited any entity with cntext menu
- m_bEntityHitedOnContext = bEntityClicked;
- CMenu* pPopup = menu.GetSubMenu(0);
- pPopup->EnableMenuItem( ID_ENTITY_CONTEXT_HELP, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_SET_AS_CSG_TARGET, MF_DISABLED|MF_GRAYED);
- if(bBrushClicked && !bSecondLayerHited) pPopup->EnableMenuItem(ID_SET_AS_CSG_TARGET, MF_ENABLED);
- // disable commands that can't be applied
- switch( pDoc->GetEditingMode())
- {
- case POLYGON_MODE:
- {
- pPopup->EnableMenuItem(ID_POLYGON_MODE, MF_DISABLED|MF_GRAYED);
- if( !bPortalClicked)
- {
- pPopup->EnableMenuItem(ID_SELECT_SECTORS_OTHER_SIDE, MF_DISABLED|MF_GRAYED);
- }
- if( !bBrushClicked)
- {
- pPopup->EnableMenuItem(ID_MENU_COPY_MAPPING, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_COPY_TEXTURE, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_SELECT_BY_TEXTURE_ADJACENT, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_SELECT_BY_TEXTURE_IN_SECTOR, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_SELECT_BY_COLOR_IN_SECTOR, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_FIND_TEXTURE, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_DESELECT_BY_ORIENTATION, MF_DISABLED|MF_GRAYED);
- }
- if( pDoc->m_selPolygonSelection.Count() == 0)
- {
- pPopup->EnableMenuItem(ID_FILTER_SELECTION, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_CHOOSE_COLOR, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_EXPORT_DISPLACE_MAP, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_RANDOM_OFFSET_U, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_RANDOM_OFFSET_V, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_POLYGONS_TO_BRUSH, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_CLONE_POLYGONS, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_DELETE_POLYGONS, MF_DISABLED|MF_GRAYED);
- }
- if( !pDoc->m_woWorld.CanJoinPolygons( pDoc->m_selPolygonSelection))
- {
- pPopup->EnableMenuItem( ID_CSG_JOIN_POLYGONS, MF_DISABLED|MF_GRAYED);
- }
- if( !pDoc->m_woWorld.CanJoinAllPossiblePolygons( pDoc->m_selPolygonSelection))
- {
- pPopup->EnableMenuItem( ID_CSG_JOIN_ALL_POLYGONS, MF_DISABLED|MF_GRAYED);
- }
- BOOL bEnableRetripling = FALSE;
- if( pDoc->m_selPolygonSelection.Count() != 0)
- {
- CBrushPolygon *pbpo = pDoc->m_selPolygonSelection.GetFirstInSelection();
- bEnableRetripling = pbpo->bpo_pbscSector->IsReTripleAvailable( pDoc->m_selPolygonSelection);
- }
- if( !bEnableRetripling)
- {
- pPopup->EnableMenuItem( ID_RE_TRIPLE, MF_DISABLED|MF_GRAYED);
- }
- if( !pDoc->m_woWorld.CanJoinPolygons( pDoc->m_selPolygonSelection))
- {
- pPopup->EnableMenuItem( ID_CSG_JOIN_POLYGONS, MF_DISABLED|MF_GRAYED);
- }
- break;
- }
- case SECTOR_MODE:
- {
- if( !bBrushClicked)
- {
- pPopup->EnableMenuItem(ID_SELECT_LINKS_TO_SECTOR, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_SELECT_SECTORS_WITH_SAME_NAME, MF_DISABLED|MF_GRAYED);
- }
- if( pDoc->m_selSectorSelection.Count() == 0)
- {
- pPopup->EnableMenuItem(ID_HIDE_SELECTED_SECTORS, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_HIDE_UNSELECTED_SECTORS, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_DELETE_SECTORS, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_CHOOSE_COLOR, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_SECTORS_TO_BRUSH, MF_DISABLED|MF_GRAYED);
- }
-
- if( !pDoc->m_woWorld.CanCopySectors(pDoc->m_selSectorSelection))
- {
- pPopup->EnableMenuItem( ID_COPY_SECTORS, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem( ID_EDIT_COPY_ALTERNATIVE, MF_DISABLED|MF_GRAYED);
- }
- if( pDoc->m_woWorld.CanJoinSectors(pDoc->m_selSectorSelection))
- {
- pPopup->EnableMenuItem( ID_CSG_JOIN_SECTORS, MF_DISABLED|MF_GRAYED);
- }
- break;
- }
- case TERRAIN_MODE:
- {
- CTerrain *ptrTerrain=GetTerrain();
- if(ptrTerrain==NULL)
- {
- pPopup->EnableMenuItem( ID_PICK_LAYER, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem( ID_SELECT_LAYER, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem( ID_CHANGE_TERRAIN_SIZE, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem( ID_CHANGE_HEIGHTMAP_SIZE, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem( ID_RECALCULATE_TERRAIN_SHADOWS, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem( ID_OPTIMIZE_TERRAIN, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem( ID_IMPORT_HEIGHTMAP, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem( ID_IMPORT_HEIGHTMAP16, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem( ID_EXPORT_HEIGHTMAP, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem( ID_EXPORT_HEIGHTMAP16, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem( ID_VIEW_HEIGHTMAP, MF_DISABLED|MF_GRAYED);
- CTerrainLayer *ptlLayer=GetLayer();
- if(ptlLayer==NULL)
- {
- pPopup->EnableMenuItem( ID_LAYER_OPTIONS, MF_DISABLED|MF_GRAYED);
- }
- }
- break;
- }
- case ENTITY_MODE:
- {
- if( bEntityClicked)
- {
- pPopup->EnableMenuItem(ID_ENTITY_CONTEXT_HELP, MF_ENABLED);
- }
- BOOL bDisableSelectTarget = FALSE;
- if( pDoc->m_selEntitySelection.Count() == 1)
- {
- CPropertyID *ppidProperty = pMainFrame->m_PropertyComboBar.GetSelectedProperty();
- if( (ppidProperty == NULL) ||
- !((ppidProperty->pid_eptType == CEntityProperty::EPT_PARENT) ||
- (ppidProperty->pid_eptType == CEntityProperty::EPT_ENTITYPTR)))
- {
- bDisableSelectTarget = TRUE;
- }
- }
- else
- {
- bDisableSelectTarget = TRUE;
- }
- if( bDisableSelectTarget)
- {
- pPopup->EnableMenuItem(ID_SELECT_TARGET, MF_DISABLED|MF_GRAYED);
- }
- pPopup->EnableMenuItem(ID_ENTITY_MODE, MF_DISABLED|MF_GRAYED);
- // see if should disable delete
- if( !IsDeleteEntityEnabled())
- {
- pPopup->EnableMenuItem(ID_DELETE_ENTITIES, MF_DISABLED|MF_GRAYED);
- }
- // if clear all target is disabled
- if( !m_bEntityHitedOnContext)
- {
- pPopup->EnableMenuItem(ID_ROTATE_TO_TARGET_ORIGIN, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_ROTATE_TO_TARGET_CENTER, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_COPY_POSITION, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_COPY_ORIENTATION, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_COPY_PLACEMENT, MF_DISABLED|MF_GRAYED);
-
- pPopup->EnableMenuItem(ID_PASTE_POSITION, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_CLEAR_ALL_TARGETS, MF_DISABLED|MF_GRAYED);
- }
- // if clone updating is disabled
- if( !pDoc->IsCloneUpdatingAllowed())
- {
- pPopup->EnableMenuItem(ID_UPDATE_CLONES, MF_DISABLED|MF_GRAYED);
- }
- // if brush updating is disabled
- if( !pDoc->IsBrushUpdatingAllowed())
- {
- pPopup->EnableMenuItem(ID_UPDATE_BRUSHES, MF_DISABLED|MF_GRAYED);
- }
- // if copy is not allowed
- if( pDoc->m_selEntitySelection.Count() == 0)
- {
- pPopup->EnableMenuItem(ID_EDIT_COPY, MF_DISABLED|MF_GRAYED);
- pPopup->EnableMenuItem(ID_SELECT_DESCENDANTS, MF_DISABLED|MF_GRAYED);
- }
- // if clipboard world does not exist
- if( GetFileAttributesA( _fnmApplicationPath + "Temp\\ClipboardWorld.wld") == -1)
- {
- // disable pasting
- pPopup->EnableMenuItem(ID_EDIT_PASTE, MF_DISABLED|MF_GRAYED);
- }
- if( !IsSelectClonesOnContextEnabled())
- {
- // disable select clones
- pPopup->EnableMenuItem(ID_SELECT_CLONES_ON_CONTEXT, MF_DISABLED|MF_GRAYED);
- }
- if( !IsSelectOfSameClassOnContextEnabled())
- {
- // disable select clones
- pPopup->EnableMenuItem(ID_SELECT_OF_SAME_CLASS_ON_CONTEXT, MF_DISABLED|MF_GRAYED);
- }
- break;
- }
- }
- // convert mouse coordinates into screen coordinates
- ClientToScreen( &point);
- // call popup menu
- pPopup->TrackPopupMenu( TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_LEFTALIGN,
- point.x, point.y, this);
- }
- }
- void CWorldEditorView::SetEditingDataPaneInfo( BOOL bImidiateRepainting)
- {
- // obtain current time
- FLOAT fTimeNow = _pTimer->GetRealTimeTick();
- // get difference to time when last mip brushing option has been used
- FLOAT fSecondsPassed = fTimeNow-_fLastMipBrushingOptionUsed;
- // if we used any mip brushing option inside last 30 seconds
- BOOL bUsingMipBrushing;
- if( fSecondsPassed < 120) bUsingMipBrushing = TRUE;
- else bUsingMipBrushing = FALSE;
- // get draw port
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- // if it is not valid
- if( pdpValidDrawPort == NULL)
- {
- return;
- }
- if( !theApp.m_bShowStatusInfo)
- {
- return;
- }
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CWorldEditorDoc* pDoc = GetDocument();
- char strDataPaneText[ 128];
- // obtain button statuses and interesting flags
- BOOL bSpace = (GetKeyState( ' ') & 128) != 0;
- BOOL bCtrl = (GetKeyState( VK_CONTROL)&0x8000) != 0;
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- BOOL bLMB = (GetKeyState( VK_LBUTTON)&0x8000) != 0;
- BOOL bRMB = (GetKeyState( VK_RBUTTON)&0x8000) != 0;
- BOOL bCSGOn = pDoc->m_pwoSecondLayer != NULL;
- BOOL bEntityMode = pDoc->GetEditingMode() == ENTITY_MODE;
- BOOL bPolygonMode = pDoc->GetEditingMode() == POLYGON_MODE;
- BOOL bTerrainMode = pDoc->GetEditingMode() == TERRAIN_MODE;
- BOOL bVertexMode = pDoc->GetEditingMode() == VERTEX_MODE;
- CEntity *penBrush = pMainFrame->m_CSGDesitnationCombo.GetSelectedBrushEntity();
- // create a slave viewer
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pdpValidDrawPort);
- //---------------- Now we will prepare status line' text describing editing data
- if( theApp.m_bMeasureModeOn)
- {
- strcpy( strDataPaneText, m_strMeasuring);
- }
- else if( theApp.m_bCutModeOn)
- {
- sprintf( strDataPaneText, "Cut/Mirror mode");
- }
- else if( (penBrush != NULL) && bUsingMipBrushing)
- {
- CBrush3D *pbrBrush = penBrush->GetBrush();
- ASSERT( pbrBrush != NULL);
- // get currently active mip factor
- FLOAT fCurrentMipFactor = GetCurrentlyActiveMipFactor();
- // get mip brush
- if( pbrBrush != NULL)
- {
- CBrushMip *pbmCurrentMip = pbrBrush->GetBrushMipByDistance( fCurrentMipFactor);
- if( pbmCurrentMip != NULL)
- {
- // get mip switch factor for currently visible brush
- FLOAT fCurrentMipSwitchFactor = pbmCurrentMip->GetMipDistance();
- // so prepare string telling selected brush's mip switch factor
- sprintf( strDataPaneText, "factor=%.2f, mip=%d/%d, switch=%.2f",
- fCurrentMipFactor, pbmCurrentMip->GetMipIndex(),
- pbrBrush->br_lhBrushMips.Count(), fCurrentMipSwitchFactor);
- }
- else
- {
- // so prepare string telling selected brush's mip switch factor
- sprintf( strDataPaneText, "factor=%.2f, after last mip", fCurrentMipFactor);
- }
- }
- else
- {
- // brush wasn't valid, report error
- sprintf( strDataPaneText, "entity has invalid brush");
- }
- }
- // if space pressed, we are interested in viewer placement
- else if( bSpace)
- {
- // get viewer position and orientation data
- CPlacement3D plViewer = GetChildFrame()->m_mvViewer.GetViewerPlacement();
- // if both mouses are pressed, we want to rotate viewer
- if( bLMB && bRMB)
- {
- // so prepare string telling viewer orientation
- sprintf( strDataPaneText, "H=%g P=%g B=%g",
- DegAngle( plViewer.pl_OrientationAngle(1)),
- DegAngle( plViewer.pl_OrientationAngle(2)),
- DegAngle( plViewer.pl_OrientationAngle(3)) );
- }
- // we are interested in viewer's current position
- else
- {
- // so prepare string telling viewer position
- sprintf( strDataPaneText, "X=%g Y=%g Z=%g",
- plViewer.pl_PositionVector(1),
- plViewer.pl_PositionVector(2),
- plViewer.pl_PositionVector(3) );
- }
- }
- else if( (bVertexMode) && ( pDoc->m_selVertexSelection.Count() != 0) )
- {
- // so prepare string telling entity position
- if (pDoc->m_selVertexSelection.Count()==1) {
- const FLOAT3D &v = pDoc->m_selVertexSelection.GetFirst().bvx_vAbsolute;
- sprintf( strDataPaneText, "%f,%f,%f", v(1), v(2), v(3));
- } else {
- sprintf( strDataPaneText, "Dragging %d vertices", pDoc->m_selVertexSelection.Count());
- }
- }
- // if we are in entity mode and there is selected entity
- else if( (bEntityMode) && ( pDoc->m_selEntitySelection.Count() != 0) )
- {
- // lock selection's dynamic container
- pDoc->m_selEntitySelection.Lock();
- // get first entity
- CEntity *penEntityOne = pDoc->m_selEntitySelection.Pointer(0);
- // unlock selection's dynamic container
- pDoc->m_selEntitySelection.Unlock();
- // get placement of first entity
- CPlacement3D plEntityOnePlacement = penEntityOne->GetPlacement();
- // if both mouses are pressed, we want to rotate entity so prepare text telling angles
- if( bLMB && bRMB)
- {
- // so prepare string telling entity orientation
- sprintf( strDataPaneText, "H=%g P=%g B=%g",
- DegAngle( plEntityOnePlacement.pl_OrientationAngle(1)),
- DegAngle( plEntityOnePlacement.pl_OrientationAngle(2)),
- DegAngle( plEntityOnePlacement.pl_OrientationAngle(3)) );
- }
- // we are interested in entity one's current position
- else
- {
- // so prepare string telling entity position
- sprintf( strDataPaneText, "X=%g Y=%g Z=%g",
- plEntityOnePlacement.pl_PositionVector(1),
- plEntityOnePlacement.pl_PositionVector(2),
- plEntityOnePlacement.pl_PositionVector(3) );
- }
- }
- // if we are in polygon mode and only one polygon is selected
- else if( (bPolygonMode) && (pDoc->m_selPolygonSelection.Count() == 1) && bCtrl)
- {
- pDoc->m_selPolygonSelection.Lock();
- CBrushPolygon *pbpoBrushPolygon = pDoc->m_selPolygonSelection.Pointer(0);
- pDoc->m_selPolygonSelection.Unlock();
- CMappingDefinitionUI mdui;
- pbpoBrushPolygon->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.ToUI( mdui);
- // prepare text telling about mapping info
- sprintf( strDataPaneText, "Tex %d: U=%.1f V=%.1f RU=%.1f RV=%.1f",
- pDoc->m_iTexture+1, mdui.mdui_fUOffset, mdui.mdui_fVOffset,
- mdui.mdui_aURotation, mdui.mdui_aVRotation);
- }
- else if( bTerrainMode)
- {
- // pane data text has bee obtained on render's ray cast
- sprintf(strDataPaneText, "%s", m_strTerrainDataPaneText);
- }
- else if( bCSGOn)
- {
- // if primitive mode on and ctrl+shift+RMB pressed
- if( pDoc->m_bPrimitiveMode && bCtrl && bShift && bRMB)
- {
- // prepare pane text telling primitive shear info
- sprintf( strDataPaneText, "Shear X=%g Shear Z=%g",
- theApp.m_vfpCurrent.vfp_fShearX, theApp.m_vfpCurrent.vfp_fShearZ);
- }
- // if primitive mode on and ctrl+shift+LMB pressed
- else if( pDoc->m_bPrimitiveMode && bCtrl && bShift)
- {
- // prepare pane text telling primitive size info
- sprintf( strDataPaneText, "W=%g H=%g L=%g",
- theApp.m_vfpCurrent.vfp_fXMax-theApp.m_vfpCurrent.vfp_fXMin,
- theApp.m_vfpCurrent.vfp_fYMax-theApp.m_vfpCurrent.vfp_fYMin,
- theApp.m_vfpCurrent.vfp_fZMax-theApp.m_vfpCurrent.vfp_fZMin);
- }
- // else if ctrl and both mouses are pressed
- else if( bCtrl && bLMB && bRMB)
- {
- // prepare text telling CSG layer orientation
- sprintf( strDataPaneText, "H=%g P=%g B=%g",
- DegAngle( pDoc->m_plSecondLayer.pl_OrientationAngle(1)),
- DegAngle( pDoc->m_plSecondLayer.pl_OrientationAngle(2)),
- DegAngle( pDoc->m_plSecondLayer.pl_OrientationAngle(3)) );
- }
- // else
- else
- {
- // prepare text telling CSG layer position
- sprintf( strDataPaneText, "X=%g Y=%g Z=%g",
- pDoc->m_plSecondLayer.pl_PositionVector(1),
- pDoc->m_plSecondLayer.pl_PositionVector(2),
- pDoc->m_plSecondLayer.pl_PositionVector(3) );
- }
- }
- else
- {
- // sprintf( strDataPaneText, "Idle time");
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if any kind of entity was hitted
- if( crRayHit.cr_penHit != NULL)
- {
- // get hitted coordinate
- FLOAT3D f3Coordinate = crRayHit.cr_vHit;
- // snap it
- SnapVector( f3Coordinate);
- // prepare text describing hitted coordinate
- sprintf( strDataPaneText, "X=%g Y=%g Z=%g", f3Coordinate(1), f3Coordinate(2), f3Coordinate(3));
- }
- else
- {
- // if the ray hits the empty space
- sprintf( strDataPaneText, "Over nothing");
- }
- }
- // put editing data info into status line
- pMainFrame->m_wndStatusBar.SetPaneText( POSITION_PANE, CString(strDataPaneText), bImidiateRepainting);
- }
- #define SCROLL_CHANGE 0.2f
- #define ZOOM_CHANGE 0.05f
- #define ANGLE_CHANGE 1.0f
- void CWorldEditorView::OnMouseMove(UINT nFlags, CPoint point)
- {
- BOOL bLMB = (GetKeyState( VK_LBUTTON)&0x8000) != 0;
- BOOL bRMB = (GetKeyState( VK_RBUTTON)&0x8000) != 0;
- BOOL bCtrl = (GetKeyState( VK_CONTROL)&0x8000) != 0;
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0;
-
- if(((m_iaInputAction == IA_SELECT_LASSO_ENTITY) ||
- (m_iaInputAction == IA_SELECT_LASSO_BRUSH_VERTEX)) && !bLMB)
- {
- m_iaInputAction = IA_NONE;
- // discard laso selection
- m_avpixLaso.Clear();
- }
- // if neather mouse key is pressed, simulate that action is none
- if( !bLMB && !bRMB) m_iaInputAction = IA_NONE;
-
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CWorldEditorDoc* pDoc = GetDocument();
-
- CWorldEditorView *pWorldEditorView = theApp.GetActiveView();
- if( pWorldEditorView == NULL) return;
- HWND hwndUnderMouse = ::WindowFromPoint( point);
- HWND hwndInfo = NULL;
- if( pMainFrame->m_pInfoFrame != NULL)
- {
- hwndInfo = pMainFrame->m_pInfoFrame->m_hWnd;
- }
-
- HWND hwndFocused = ::GetFocus();
- //HWND hwndForeground = ::GetForegroundWindow();
- //if( hwndForeground==pMainFrame->m_hWnd)
- {
- // if this is the first mouse move over new view and it is not over info window,
- // set focus and loose all previous actions
- if( (m_hWnd != hwndFocused) && ( hwndInfo != hwndUnderMouse) )
- {
- SetActiveWindow();
- SetFocus();
- GetChildFrame()->SetActiveView( this);
- pMainFrame->MDIActivate(GetParentFrame());
- // cancel any possible previous actions
- m_iaInputAction = IA_NONE;
- }
- }
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- if( pdpValidDrawPort == NULL) return;
- CView::OnMouseMove(nFlags, point);
- CPoint ptScreen = point;
- LONG lOffsetX = point.x - m_ptMouse.x;
- LONG lOffsetY = point.y - m_ptMouse.y;
- float fOriginOffsetX = (FLOAT) (point.x - m_ptMouseDown.x);
- float fOriginOffsetY = (FLOAT) (point.y - m_ptMouseDown.y);
- //_RPT2(_CRT_WARN, "%f %f\n", fOriginOffsetX, fOriginOffsetY);
- // create a slave viewer
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pdpValidDrawPort);
- BOOL bHitModels = (pDoc->GetEditingMode() != POLYGON_MODE) &&
- (pDoc->GetEditingMode() != TERRAIN_MODE);
- BOOL bHitFields = pDoc->GetEditingMode() == ENTITY_MODE;
- BOOL bHitBrushes = pDoc->GetEditingMode() != TERRAIN_MODE;
- // set dummy ray hit result
- CCastRay crRayHit( NULL, CPlacement3D(FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0)) );
- BOOL bRayHitNeeded;
- if( (m_iaInputAction == IA_MOVING_VIEWER_IN_FLOOR_PLANE) ||
- (m_iaInputAction == IA_MOVING_VIEWER_IN_VIEW_PLANE) ||
- (m_iaInputAction == IA_ROTATING_VIEWER) ||
- (m_iaInputAction == IA_MOVING_SECOND_LAYER_IN_FLOOR_PLANE) ||
- (m_iaInputAction == IA_MOVING_SECOND_LAYER_IN_VIEW_PLANE) ||
- (m_iaInputAction == IA_ROTATING_SECOND_LAYER) ||
- (m_iaInputAction == IA_MOVING_ENTITY_SELECTION_IN_FLOOR_PLANE) ||
- (m_iaInputAction == IA_MOVING_ENTITY_SELECTION_IN_VIEW_PLANE) ||
- (m_iaInputAction == IA_ROTATING_ENTITY_SELECTION) ||
- (m_iaInputAction == IA_DRAG_BRUSH_VERTEX_IN_FLOOR_PLANE) ||
- (m_iaInputAction == IA_DRAG_BRUSH_VERTEX_IN_VIEW_PLANE) ||
- (m_iaInputAction == IA_SELECT_LASSO_ENTITY) ||
- (m_iaInputAction == IA_SELECT_LASSO_BRUSH_VERTEX) ||
- (m_iaInputAction == IA_STRETCH_BRUSH_VERTEX) ||
- (m_iaInputAction == IA_ROTATE_BRUSH_VERTEX) ) {
- bRayHitNeeded = FALSE;
- } else {
- bRayHitNeeded = TRUE;
- }
-
- BOOL bSelectPortals = FALSE;
- // for right mouse button select portals
- if( bRMB)
- {
- bSelectPortals = TRUE;
- }
- if( bRayHitNeeded)
- {
- crRayHit = GetMouseHitInformation( m_ptMouse, bSelectPortals, bHitModels, bHitFields, NULL, bHitBrushes);
- if(abs(lOffsetX)>=1 || abs(lOffsetY)>=1)
- {
- theApp.m_vLastTerrainHit=crRayHit.cr_vHit;
- theApp.m_penLastTerrainHit=crRayHit.cr_penHit;
- }
- m_strTerrainDataPaneText="Terrain not hit";
- if( pDoc->GetEditingMode() == TERRAIN_MODE && !_pInput->IsInputEnabled())
- {
- if( (crRayHit.cr_penHit!=NULL) && (crRayHit.cr_penHit->GetRenderType() == CEntity::RT_TERRAIN))
- {
- CTerrain *ptrTerrain=crRayHit.cr_penHit->GetTerrain();
- INDEX iLayerBeneath=-1;
- UBYTE ubLayerPower=0;
- INDEX ctLayers=ptrTerrain->tr_atlLayers.Count();
- for(INDEX iLayer=0; iLayer<ctLayers; iLayer++)
- {
- UBYTE ubPower=GetValueFromMask(ptrTerrain, iLayer, crRayHit.cr_vHit);
- if(ubPower>0)
- {
- iLayerBeneath=iLayer;
- ubLayerPower=ubPower;
- }
- }
- if(iLayerBeneath!=-1)
- {
- if(theApp.m_iTerrainEditMode==TEM_HEIGHTMAP)
- {
- if( bCtrl&&bAlt)
- {
- Point pt=Calculate2dHitPoint(ptrTerrain, crRayHit.cr_vHit);
- INDEX iWidth=ptrTerrain->tr_pixHeightMapWidth;
- UWORD uwAltitude=*(ptrTerrain->tr_auwHeightMap+iWidth*pt.pt_iY+pt.pt_iX);
- FLOAT fAltitudeBeneath=FLOAT(uwAltitude)/65535*ptrTerrain->tr_vTerrainSize(2);
- m_strTerrainDataPaneText.PrintF("Altitude: %g", fAltitudeBeneath);
- }
- else
- {
- FLOAT fReferenceAltitude=FLOAT(theApp.m_uwEditAltitude)/65535*ptrTerrain->tr_vTerrainSize(2);
- m_strTerrainDataPaneText.PrintF("Reference altitude: %g", fReferenceAltitude);
- }
- }
- else
- {
- m_strTerrainDataPaneText.PrintF("Layer: %d (%d%%)", iLayerBeneath+1, INDEX(ubLayerPower/255.0f*100.0f));
- }
- }
- else
- {
- m_strTerrainDataPaneText.PrintF("No layers");
- }
- }
- else
- {
- m_strTerrainDataPaneText.PrintF("No terrain hit");
- }
- }
- }
- BOOL bRefreshView = FALSE;// view refresh is not needed for now
- BOOL bObjectMoved = FALSE;// nothing has moved for now
- BOOL bRepaintImmediately = FALSE; // force immediate repainting
- BOOL bRecreatePrimitive = FALSE;// there is no need for recreating primitive
- // act acording to action started in OnLButtonDown() and OnRButtonDown()
- switch( m_iaInputAction)
- {
- case IA_MIP_SETTING:
- {
- // remember current time as time when last mip brushing option has been used
- _fLastMipBrushingOptionUsed = _pTimer->GetRealTimeTick();
- if( lOffsetY > 0) lOffsetY = 0;
- // translate viewer in floor plane
- svViewer.Translate_OwnSystem( 0, 0, -lOffsetY);
- // set new viewer position
- GetChildFrame()->m_mvViewer = svViewer;
- bRefreshView = TRUE;
- break;
- }
- case IA_MANUAL_MIP_SWITCH_FACTOR_CHANGING:
- {
- if( GetChildFrame()->m_fManualMipBrushingFactor - lOffsetY/50.0f > 0.0f)
- {
- // remember current time as time when last mip brushing option has been used
- _fLastMipBrushingOptionUsed = _pTimer->GetRealTimeTick();
- GetChildFrame()->m_fManualMipBrushingFactor -= lOffsetY/50.0f;
- }
- bRefreshView = TRUE;
- break;
- }
- case IA_ROTATING_VIEWER:
- {
- svViewer.Rotate_HPB( lOffsetX, lOffsetY, 0);
- // set new viewer position
- GetChildFrame()->m_mvViewer = svViewer;
- bRefreshView = TRUE;
- break;
- }
- case IA_MOVING_VIEWER_IN_FLOOR_PLANE:
- {
- // translate viewer in floor plane
- svViewer.Translate_OwnSystem( lOffsetX, lOffsetY, 0);
- // set new viewer position
- GetChildFrame()->m_mvViewer = svViewer;
- bRefreshView = TRUE;
- break;
- }
- case IA_MOVING_VIEWER_IN_VIEW_PLANE:
- {
- // translate viewer in view plane
- svViewer.Translate_OwnSystem( lOffsetX, 0, -lOffsetY);
- // set new viewer position
- GetChildFrame()->m_mvViewer = svViewer;
- bRefreshView = TRUE;
- break;
- }
- case IA_SHEARING_PRIMITIVE:
- {
- // get translation vector in view space
- FLOAT fZoom = svViewer.GetZoomFactor();
- CPlacement3D plVector0(FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0));
- CPlacement3D plVector1(
- FLOAT3D( fOriginOffsetX/fZoom, -fOriginOffsetY/fZoom, 0.0f),
- ANGLE3D(0,0,0));
- // project translation vector from view space to absolute space
- CPlacement3D plViewer = svViewer.GetViewerPlacement();
- plVector0.RelativeToAbsolute(plViewer);
- plVector1.RelativeToAbsolute(plViewer);
- // project translation vector from absolute space to second layer space
- plVector0.AbsoluteToRelative(pDoc->m_plSecondLayer);
- plVector1.AbsoluteToRelative(pDoc->m_plSecondLayer);
- // extract translation vector from placements
- FLOAT3D vSizeDelta = plVector1.pl_PositionVector-plVector0.pl_PositionVector;
- // apply mouse movement
- theApp.m_vfpCurrent.vfp_fShearX = m_VFPMouseDown.vfp_fShearX+vSizeDelta(1);
- theApp.m_vfpCurrent.vfp_fShearZ = m_VFPMouseDown.vfp_fShearZ+vSizeDelta(3);
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fShearX, m_fGridInMeters/GRID_DISCRETE_VALUES);
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fShearZ, m_fGridInMeters/GRID_DISCRETE_VALUES);
- bRefreshView = TRUE;
- bRecreatePrimitive = TRUE;
- break;
- }
- case IA_STRETCHING_PRIMITIVE:
- {
- // get translation vector in view space
- FLOAT fZoom = svViewer.GetZoomFactor();
- CPlacement3D plVector0(FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0));
- CPlacement3D plVector1(
- FLOAT3D( fOriginOffsetX/fZoom, -fOriginOffsetY/fZoom,0.0f),
- ANGLE3D(0,0,0));
- // project translation vector from view space to absolute space
- CPlacement3D plViewer = svViewer.GetViewerPlacement();
- plVector0.RelativeToAbsolute(plViewer);
- plVector1.RelativeToAbsolute(plViewer);
- // project translation vector from absolute space to second layer space
- plVector0.AbsoluteToRelative(pDoc->m_plSecondLayer);
- plVector1.AbsoluteToRelative(pDoc->m_plSecondLayer);
- // extract translation vector from placements
- FLOAT3D vSizeDelta = plVector1.pl_PositionVector-plVector0.pl_PositionVector;
- // apply mouse movement
- CValuesForPrimitive vfpTemp = theApp.m_vfpCurrent;
- vfpTemp.vfp_fXMin = m_VFPMouseDown.vfp_fXMin+vSizeDelta(1)*aiForAllowedSizing[m_iSizeControlVertice][0];
- vfpTemp.vfp_fXMax = m_VFPMouseDown.vfp_fXMax+vSizeDelta(1)*aiForAllowedSizing[m_iSizeControlVertice][1];
- vfpTemp.vfp_fYMin = m_VFPMouseDown.vfp_fYMin+vSizeDelta(2)*aiForAllowedSizing[m_iSizeControlVertice][2];
- vfpTemp.vfp_fYMax = m_VFPMouseDown.vfp_fYMax+vSizeDelta(2)*aiForAllowedSizing[m_iSizeControlVertice][3];
- vfpTemp.vfp_fZMin = m_VFPMouseDown.vfp_fZMin+vSizeDelta(3)*aiForAllowedSizing[m_iSizeControlVertice][4];
- vfpTemp.vfp_fZMax = m_VFPMouseDown.vfp_fZMax+vSizeDelta(3)*aiForAllowedSizing[m_iSizeControlVertice][5];
- pDoc->SnapFloat( vfpTemp.vfp_fXMin, m_fGridInMeters/GRID_DISCRETE_VALUES);
- pDoc->SnapFloat( vfpTemp.vfp_fXMax, m_fGridInMeters/GRID_DISCRETE_VALUES);
- pDoc->SnapFloat( vfpTemp.vfp_fYMin, m_fGridInMeters/GRID_DISCRETE_VALUES);
- pDoc->SnapFloat( vfpTemp.vfp_fYMax, m_fGridInMeters/GRID_DISCRETE_VALUES);
- pDoc->SnapFloat( vfpTemp.vfp_fZMin, m_fGridInMeters/GRID_DISCRETE_VALUES);
- pDoc->SnapFloat( vfpTemp.vfp_fZMax, m_fGridInMeters/GRID_DISCRETE_VALUES);
- // if movement produced valid primitive
- if( (vfpTemp.vfp_fXMax>vfpTemp.vfp_fXMin) &&
- (vfpTemp.vfp_fYMax>vfpTemp.vfp_fYMin) &&
- (vfpTemp.vfp_fZMax>vfpTemp.vfp_fZMin) )
- {
- theApp.m_vfpCurrent = vfpTemp;
- bRefreshView = TRUE;
- bRecreatePrimitive = TRUE;
- }
- break;
- }
- case IA_CHANGING_RANGE_PROPERTY:
- case IA_CHANGING_ANGLE3D_PROPERTY:
- {
- CPropertyID *ppid = pMainFrame->m_PropertyComboBar.GetSelectedProperty();
- if( ppid == NULL) return;
- //for all selected entities
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- // obtain property ptr
- CEntityProperty *penpProperty = iten->PropertyForName( ppid->pid_strName);
- if( penpProperty == NULL) return;
- // discard old entity settings
- iten->End();
- if( ppid->pid_eptType == CEntityProperty::EPT_RANGE)
- {
- // get editing range for current entity
- FLOAT fRange = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOAT);
- // add range offset received during L/R mouse move
- fRange += svViewer.PixelsToMeters(lOffsetX);
- // set new range
- ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOAT) = fRange;
- // change dialog's range variable
- pMainFrame->m_PropertyComboBar.m_fEditingFloat = fRange;
- }
- else
- {
- // get angle3d for current entity
- ANGLE3D aAngle = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ANGLE3D);
- // create dummy placement
- CPlacement3D plDummyPlacement;
- plDummyPlacement.pl_PositionVector = FLOAT3D( 0.0f, 0.0f, 0.0f);
- plDummyPlacement.pl_OrientationAngle = aAngle;
- // set new angles using trackball method
- svViewer.RotatePlacement_TrackBall(plDummyPlacement, lOffsetX, lOffsetY, 0);
- aAngle = plDummyPlacement.pl_OrientationAngle;
- // set new angle
- ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ANGLE3D) = aAngle;
- // change dialog's range variable
- pMainFrame->m_PropertyComboBar.m_fEditingHeading = DegAngle(aAngle(1));
- pMainFrame->m_PropertyComboBar.m_fEditingPitch = DegAngle(aAngle(2));
- pMainFrame->m_PropertyComboBar.m_fEditingBanking = DegAngle(aAngle(3));
- }
- // apply new entity settings
- iten->Initialize();
- // update edit range control (by updating parent dialog)
- pMainFrame->m_PropertyComboBar.UpdateData( FALSE);
- bRefreshView = TRUE;
- }
- // mark that document is changed
- pDoc->SetModifiedFlag( TRUE);
- break;
- }
- case IA_ROTATING_ENTITY_SELECTION:
- case IA_ROTATING_SECOND_LAYER:
- {
- // use trackball method for rotation
- svViewer.RotatePlacement_TrackBall(m_plMouseMove, -lOffsetX, -lOffsetY, 0);
- pDoc->m_chSelections.MarkChanged();
- bObjectMoved = TRUE;
- break;
- }
- case IA_MOVING_ENTITY_SELECTION_IN_FLOOR_PLANE:
- case IA_MOVING_SECOND_LAYER_IN_FLOOR_PLANE:
- {
- svViewer.TranslatePlacement_OwnSystem(m_plMouseMove, lOffsetX, lOffsetY, 0);
- pDoc->m_chSelections.MarkChanged();
- bObjectMoved = TRUE;
- break;
- }
- case IA_MOVING_ENTITY_SELECTION_IN_VIEW_PLANE:
- case IA_MOVING_SECOND_LAYER_IN_VIEW_PLANE:
- {
- svViewer.TranslatePlacement_OwnSystem(m_plMouseMove, lOffsetX, 0, lOffsetY);
- pDoc->m_chSelections.MarkChanged();
- bObjectMoved = TRUE;
- break;
- }
- case IA_SIZING_SELECT_BY_VOLUME_BOX:
- {
- // get translation vector in view space
- FLOAT fZoom = svViewer.GetZoomFactor();
- CPlacement3D plVector0(FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0));
- CPlacement3D plVector1(FLOAT3D(fOriginOffsetX/fZoom,-fOriginOffsetY/fZoom,0.0f),
- ANGLE3D(0,0,0));
- // project translation vector from view space to absolute space
- CPlacement3D plViewer = svViewer.GetViewerPlacement();
- plVector0.RelativeToAbsolute(plViewer);
- plVector1.RelativeToAbsolute(plViewer);
- // extract translation vector from placements
- FLOAT3D vDelta = plVector1.pl_PositionVector-plVector0.pl_PositionVector;
- // apply movement
- FLOAT3D vNewVolumeBoxCorner = pDoc->m_vVolumeBoxStartDragVertice+vDelta;
- pDoc->CorrectBox( pDoc->m_iVolumeBoxDragVertice, vNewVolumeBoxCorner);
- bRefreshView = TRUE;
- break;
- }
- case IA_DRAG_VERTEX_ON_PRIMITIVE_BASE:
- {
- if( m_iDragVertice == -1) break;
- // ------ Move closest vertice on base of primitive
- CPlacement3D plVector0(FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0));
- FLOAT fZoom = svViewer.GetZoomFactor();
- CPlacement3D plVector1(FLOAT3D(fOriginOffsetX/fZoom,-fOriginOffsetY/fZoom,0.0f),
- ANGLE3D(0,0,0));
- // project translation vector from view space to absolute space
- CPlacement3D plViewer = svViewer.GetViewerPlacement();
- plVector0.RelativeToAbsolute(plViewer);
- plVector1.RelativeToAbsolute(plViewer);
- // project translation vector from absolute space to second layer space
- plVector0.AbsoluteToRelative(pDoc->m_plSecondLayer);
- plVector1.AbsoluteToRelative(pDoc->m_plSecondLayer);
- // extract translation vector from placements
- DOUBLE3D vDelta = FLOATtoDOUBLE(plVector1.pl_PositionVector)-
- FLOATtoDOUBLE(plVector0.pl_PositionVector);
-
- DOUBLE3D &vDrag = theApp.m_vfpCurrent.vfp_avVerticesOnBaseOfPrimitive[m_iDragVertice];
- // apply movement
- vDrag = m_vStartDragVertice + vDelta;
- // snap resulting vertex coordinate
- SnapVector( vDrag);
- // refresh primitive
- pDoc->CreatePrimitive();
- bRefreshView = TRUE;
- break;
- }
- case IA_DRAG_VERTEX_ON_PRIMITIVE:
- {
- FLOAT fZoom = svViewer.GetZoomFactor();
- DragVerticesOnPrimitive(fOriginOffsetX/fZoom,-fOriginOffsetY/fZoom, 0.0f, FALSE);
- bRefreshView = TRUE;
- break;
- }
- case IA_SELECT_LASSO_BRUSH_VERTEX:
- case IA_SELECT_LASSO_ENTITY:
- {
- INDEX ctLasoPts = m_avpixLaso.Count();
- m_avpixLaso.Push(1);
- m_avpixLaso[ctLasoPts](1) = point.x;
- m_avpixLaso[ctLasoPts](2) = point.y;
- Invalidate( FALSE);
- break;
- }
- case IA_SELECT_SINGLE_BRUSH_VERTEX:
- {
- // if mouse moved more than few pixels arround
- if( (abs( lOffsetX) > 3) || (abs( lOffsetY) > 3) )
- {
- // if shift nor alt were pressed on mouse down
- if( !m_bOnSelectVertexShiftDown && !m_bOnSelectVertexAltDown)
- {
- // clear vertex selection
- pDoc->m_selVertexSelection.Clear();
- }
- // switch to laso select
- m_iaInputAction = IA_SELECT_LASSO_BRUSH_VERTEX;
- // add mouse down and current mouse positions to lasso buffer
- m_avpixLaso.Push(2);
- m_avpixLaso[0](1) = m_ptMouseDown.x;
- m_avpixLaso[0](2) = m_ptMouseDown.y;
- m_avpixLaso[1](1) = point.x;
- m_avpixLaso[1](2) = point.y;
- pDoc->m_chSelections.MarkChanged();
- Invalidate( FALSE);
- }
- break;
- }
- case IA_DRAG_BRUSH_VERTEX_IN_FLOOR_PLANE:
- {
- bRepaintImmediately = TRUE;
- FLOAT fZoom = svViewer.GetZoomFactor();
- DragBrushVertex(fOriginOffsetX/fZoom,-fOriginOffsetY/fZoom, 0.0f);
- pDoc->SetModifiedFlag( TRUE);
- bRefreshView = TRUE;
- break;
- }
- case IA_DRAG_BRUSH_VERTEX_IN_VIEW_PLANE:
- {
- bRepaintImmediately = TRUE;
- FLOAT fZoom = svViewer.GetZoomFactor();
- DragBrushVertex(fOriginOffsetX/fZoom, 0.0f, fOriginOffsetY/fZoom);
- pDoc->SetModifiedFlag( TRUE);
- bRefreshView = TRUE;
- break;
- }
- case IA_ROTATE_BRUSH_VERTEX:
- {
- bRepaintImmediately = TRUE;
- // apply brush vertex rotation
- RotateOrStretchBrushVertex(-fOriginOffsetX, -fOriginOffsetY, TRUE);
- pDoc->SetModifiedFlag( TRUE);
- // calculate BBox of all vertices before rotating started
- bRefreshView = TRUE;
- break;
- }
- case IA_STRETCH_BRUSH_VERTEX:
- {
- bRepaintImmediately = TRUE;
- // apply brush stretch
- FLOAT fZoom = svViewer.GetZoomFactor();
- RotateOrStretchBrushVertex(fOriginOffsetX, fZoom, FALSE);
- pDoc->SetModifiedFlag( TRUE);
- // calculate BBox of all vertices before rotating started
- bRefreshView = TRUE;
- break;
- }
- case IA_SELECTING_POLYGONS:
- {
- // if mouse is not over some polygon, break
- if( (crRayHit.cr_penHit == NULL) ||
- (crRayHit.cr_pbpoBrushPolygon == NULL) ) break;
- // if polygon under mouse is selected and first polygon that we hitted
- // was deselected
- if( crRayHit.cr_pbpoBrushPolygon->IsSelected( BPOF_SELECTED) && m_bWeDeselectedFirstPolygon)
- {
- // deselect polygon under mouse
- pDoc->m_selPolygonSelection.Deselect( *crRayHit.cr_pbpoBrushPolygon);
- }
- // if polygon under mouse is not selected and first polygon that we hitted
- // at the begining of selecting was selected
- if( !crRayHit.cr_pbpoBrushPolygon->IsSelected( BPOF_SELECTED) && !m_bWeDeselectedFirstPolygon)
- {
- // select polygon under mouse
- pDoc->m_selPolygonSelection.Select( *crRayHit.cr_pbpoBrushPolygon);
- }
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- // and refresh property combo manualy calling on idle
- pMainFrame->m_PropertyComboBar.m_PropertyComboBox.OnIdle( 0);
- bRefreshView = TRUE;
- break;
- }
- case IA_SELECTING_SECTORS:
- {
- // if mouse is not over some polygon, break
- if( (crRayHit.cr_penHit == NULL) ||
- (crRayHit.cr_pbpoBrushPolygon == NULL) ) break;
- // if sector under mouse is selected and first sector that we hitted
- // at the begining of selecting was deselected
- if( crRayHit.cr_pbscBrushSector->IsSelected( BSCF_SELECTED) && m_bWeDeselectedFirstSector)
- {
- // deselect sector under mouse
- pDoc->m_selSectorSelection.Deselect( *crRayHit.cr_pbscBrushSector);
- }
- // if sector under mouse is not selected and first sector that we hitted
- // at the begining of selecting was selected
- if( !crRayHit.cr_pbscBrushSector->IsSelected( BSCF_SELECTED) && !m_bWeDeselectedFirstSector)
- {
- // select sector under mouse
- pDoc->m_selSectorSelection.Select( *crRayHit.cr_pbscBrushSector);
- }
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- // and refresh property combo manualy calling on idle
- pMainFrame->m_PropertyComboBar.m_PropertyComboBox.OnIdle( 0);
- bRefreshView = TRUE;
- break;
- }
- case IA_SELECTING_ENTITIES:
- {
- // if mouse moved more than few pixels arround
- if( (abs( lOffsetX) > 3) || (abs( lOffsetY) > 3) )
- {
- // if shift nor alt were pressed on mouse down
- if( !m_bOnSelectEntityShiftDown && !m_bOnSelectEntityAltDown)
- {
- // clear entity selection
- pDoc->m_selEntitySelection.Clear();
- }
- // switch to laso select
- m_iaInputAction = IA_SELECT_LASSO_ENTITY;
- // add mouse down and current mouse positions to lasso buffer
- m_avpixLaso.Push(2);
- m_avpixLaso[0](1) = m_ptMouseDown.x;
- m_avpixLaso[0](2) = m_ptMouseDown.y;
- m_avpixLaso[1](1) = point.x;
- m_avpixLaso[1](2) = point.y;
- Invalidate( FALSE);
- }
- break;
- }
- case IA_MEASURING:
- {
- // just refresh view
- bRefreshView = TRUE;
- break;
- }
- case IA_MOVING_CUT_LINE_START:
- {
- FLOAT fZoom = svViewer.GetZoomFactor();
- FLOAT3D vDelta = ProjectVectorToWorldSpace( fOriginOffsetX/fZoom, -fOriginOffsetY/fZoom, 0.0f);
- // calculate and snap new position
- pDoc->m_vCutLineStart = pDoc->m_vControlLineDragStart+vDelta;
- SnapVector( pDoc->m_vCutLineStart);
- bRefreshView = TRUE;
- break;
- }
- case IA_MOVING_CUT_LINE_END:
- {
- // get 3D delta vector in world, from mouse down point to current mouse position
- FLOAT fZoom = svViewer.GetZoomFactor();
- FLOAT3D vDelta = ProjectVectorToWorldSpace( fOriginOffsetX/fZoom, -fOriginOffsetY/fZoom, 0.0f);
- // calculate and snap new position
- pDoc->m_vCutLineEnd = pDoc->m_vControlLineDragStart+vDelta;
- SnapVector( pDoc->m_vCutLineEnd);
- bRefreshView = TRUE;
- break;
- }
- case IA_CUT_MODE:
- {
- // calculate current cut line end
- pDoc->m_vCutLineEnd = Get3DCoordinateFrom2D( point);
- bRefreshView = TRUE;
- break;
- }
- case IA_ROTATING_POLYGON_MAPPING:
- {
- if(crRayHit.cr_pbpoBrushPolygon==NULL) return;
- svViewer.RotatePlacement_TrackBall(m_plMouseMove, lOffsetX, lOffsetY, 0);
- // get rotation angle
- ANGLE3D angMappingRotation = m_plMouseMove.pl_OrientationAngle;
- CTString strDataPaneText;
- strDataPaneText.PrintF("H=%g,P=%g,B=%g",
- DegAngle( angMappingRotation(1)),
- DegAngle( angMappingRotation(2)),
- DegAngle( angMappingRotation(3)));
- pMainFrame->m_wndStatusBar.SetPaneText( STATUS_LINE_PANE, CString(strDataPaneText), TRUE);
- // for each selected polygon
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- CBrushPolygon *pbpo = itbpo;
- CEntity *pen = pbpo->bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush->br_penEntity;
- CSimpleProjection3D pr;
- pr.ObjectPlacementL() = _plOrigin;
- pr.ViewerPlacementL() = pen->GetPlacement();
- pr.Prepare();
- FLOATplane3D vRelative;
- pr.ProjectCoordinate(m_vHitOnMouseDown, vRelative);
- // rotate it
- itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.Rotate(
- pbpo->bpo_pbplPlane->bpl_pwplWorking->wpl_mvRelative,
- vRelative, angMappingRotation(1));
- }
- // mark that document is changed
- pDoc->SetModifiedFlag();
- bRefreshView = TRUE;
- pDoc->UpdateAllViews( NULL);
- // reset mouse placement
- m_plMouseMove.pl_PositionVector = crRayHit.cr_vHit;
- m_plMouseMove.pl_OrientationAngle = ANGLE3D( 0, 0, 0);
- // refresh position page
- pDoc->RefreshCurrentInfoPage();
- break;
- }
- case IA_MOVING_POLYGON_MAPPING:
- {
- // find translation vector in 3d
- crRayHit.cr_vHit = GetMouseHitOnPlane(point, m_plTranslationPlane);
- FLOAT3D f3dMappingTranslation = crRayHit.cr_vHit-m_plMouseMove.pl_PositionVector;
- // find how much that offsets hit polygon
- if( m_pbpoTranslationPlane == NULL) return;
- CBrushPolygon &bpo = *m_pbpoTranslationPlane;
- CEntity *pen = bpo.bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush->br_penEntity;
- CSimpleProjection3D pr;
- pr.ObjectPlacementL() = _plOrigin;
- pr.ViewerPlacementL() = pen->GetPlacement();
- pr.Prepare();
- FLOATplane3D vRelative;
- pr.ProjectDirection(f3dMappingTranslation, vRelative);
- CMappingDefinition mdOriginal = bpo.bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping;
- CMappingDefinition mdTranslated = mdOriginal;
- mdTranslated.Translate(
- bpo.bpo_pbplPlane->bpl_pwplWorking->wpl_mvRelative, vRelative);
- FLOAT fUOffset = mdTranslated.md_fUOffset-mdOriginal.md_fUOffset;
- FLOAT fVOffset = mdTranslated.md_fVOffset-mdOriginal.md_fVOffset;
- // for each selected polygon
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- // add the offsets to its mapping
- itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.md_fUOffset+=fUOffset;
- itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.md_fVOffset+=fVOffset;
- }
- // mark that document is changed
- pDoc->SetModifiedFlag();
- bRefreshView = TRUE;
- pDoc->UpdateAllViews( NULL);
- // reset mouse placement
- m_plMouseMove.pl_PositionVector = crRayHit.cr_vHit;
- m_plMouseMove.pl_OrientationAngle = ANGLE3D( 0, 0, 0);
- // refresh position page
- pDoc->RefreshCurrentInfoPage();
- break;
- }
- }
- // if recreating of primitive requested
- if( bRecreatePrimitive)
- {
- pDoc->RefreshPrimitivePage();
- pDoc->CreatePrimitive();
- }
- // if something has moved
- if( bObjectMoved)
- {
- if( (m_iaInputAction == IA_MOVING_SECOND_LAYER_IN_FLOOR_PLANE) ||
- (m_iaInputAction == IA_MOVING_SECOND_LAYER_IN_VIEW_PLANE) ||
- (m_iaInputAction == IA_ROTATING_SECOND_LAYER) )
- {
- // copy new placement to second layer
- pDoc->m_plSecondLayer = m_plMouseMove;
- pDoc->SnapToGrid( pDoc->m_plSecondLayer, m_fGridInMeters/GRID_DISCRETE_VALUES);
- theApp.m_vfpCurrent.vfp_plPrimitive = pDoc->m_plSecondLayer;
- }
- else if( (m_iaInputAction == IA_MOVING_ENTITY_SELECTION_IN_FLOOR_PLANE) ||
- (m_iaInputAction == IA_MOVING_ENTITY_SELECTION_IN_VIEW_PLANE) ||
- (m_iaInputAction == IA_ROTATING_ENTITY_SELECTION) )
- {
- ASSERT( pDoc->m_aSelectedEntityPlacements.Count()==pDoc->m_selEntitySelection.Count());
- if( pDoc->m_aSelectedEntityPlacements.Count()!=pDoc->m_selEntitySelection.Count()) return;
- // if there is no anchored entity in selection or if moving of
- // anchored entities is allowed
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- if( ((iten->GetFlags() & ENF_ANCHORED) != 0) &&
- (!GetChildFrame()->m_bAncoredMovingAllowed) ) return;
- }}
- INDEX ienCurrent = 0;
- CEntity *penBrush = NULL;
- // for each of the selected entities
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- if (iten->en_RenderType == CEntity::RT_BRUSH) {
- penBrush = &*iten;
- }
- if( (iten->GetParent()==NULL) || !(iten->GetParent()->IsSelected( ENF_SELECTED)) )
- {
- // set new entity placement
- CPlacement3D plEntityPlacement = pDoc->m_aSelectedEntityPlacements[ienCurrent];
- plEntityPlacement.RelativeToAbsoluteSmooth(m_plMouseMove);
- pDoc->SnapToGrid( plEntityPlacement, m_fGridInMeters/GRID_DISCRETE_VALUES);
- iten->SetPlacement(plEntityPlacement);
- pDoc->SetModifiedFlag();
- }
- ienCurrent++;
- }}
- if( penBrush != NULL)
- {
- DiscardShadows( penBrush);
- }
- if(m_iaInputAction == IA_ROTATING_ENTITY_SELECTION)
- {
- // check for terrain updating
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- CLightSource *pls = iten->GetLightSource();
- if (pls!=NULL)
- {
- // if light is directional
- if(pls->ls_ulFlags &LSF_DIRECTIONAL)
- {
- CTerrain *ptrTerrain=GetTerrain();
- if(ptrTerrain!=NULL) ptrTerrain->UpdateShadowMap();
- }
- }
- }}
- }
- }
- }
- // if rotating/moving viewer (bRefreshView) or moving CSG layer, entities or polygon's
- // mapping (bObjectMoved) or editing primitive (bRecreatePrimitive)
- if( bRefreshView || bObjectMoved || bRecreatePrimitive)
- {
- // see in preferences if all views should be updated
- if( theApp.m_Preferences.ap_UpdateAllways || bRepaintImmediately ||
- (bCtrl && bLMB && pDoc->GetEditingMode()==POLYGON_MODE) )
- {
- // force immediatly repainting
- RedrawWindow( NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
- // update other views
- pDoc->UpdateAllViews( this);
- }
- else
- {
- // just invalidate
- Invalidate( FALSE);
- }
- }
- // set text describing data that is edited
- SetEditingDataPaneInfo( TRUE);
- // remember current mouse position as last pressed
- m_ptMouse = point;
- }
- /*
- * Called by document at the end of CSG
- */
- void CWorldEditorView::AtStopCSG(void)
- {
- }
- /*
- * Called by MFC from CWorldEditorDoc::UpdateAllViews().
- */
- void CWorldEditorView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
- {
- // just invalidate the whole window area
- Invalidate(FALSE);
- }
- void CWorldEditorView::OnDropFiles(HDROP hDropInfo)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- BOOL bCSGOn = pDoc->m_pwoSecondLayer != NULL;
- // You can't drag anything while CSG is on
- if( bCSGOn)
- {
- return;
- }
- // get number of dropped files
- INDEX iNoOfFiles = DragQueryFile( hDropInfo, 0xFFFFFFFF, NULL, 0);
- // there can be only one file dropped
- if( iNoOfFiles != 1)
- {
- AfxMessageBox( L"You can drop only one file at a time.");
- return;
- }
- // buffer for dropped file name
- char chrFile[ 256];
- // place dropped file name into buffer
- DragQueryFileA( hDropInfo, 0, chrFile, 256);
- // create file name from buffer
- CTFileName fnDropped = CTString(chrFile);
- // don't allow document self-drop
- /*if( CTFileName(pDoc->GetPathName()) == fnDropped)
- {
- return;
- }*/
- // object to hold coordinates
- CPoint point;
- // get dropped coordinates
- DragQueryPoint( hDropInfo, &point);
- // try to
- try
- {
- // remove application path
- fnDropped.RemoveApplicationPath_t();
- }
- catch( char* err_str)
- {
- AfxMessageBox( CString(err_str));
- return;
- }
- CPlacement3D plDrop;
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( point);
- // place the dropped object at hitted point
- plDrop.pl_PositionVector = crRayHit.cr_vHit;
- // reset angles
- plDrop.pl_OrientationAngle = ANGLE3D(0,0,0);
- // if the hit entity was a brush
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) ) {
- // get the hit normal in absolute space
- CSimpleProjection3D prBrushToAbsolute;
- prBrushToAbsolute.ObjectPlacementL() = crRayHit.cr_penHit->GetPlacement();
- prBrushToAbsolute.ViewerPlacementL() = CPlacement3D(
- FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0));
- prBrushToAbsolute.Prepare();
- FLOAT3D vHitNormal;
- prBrushToAbsolute.ProjectDirection(crRayHit.cr_pbpoBrushPolygon->bpo_pbplPlane->bpl_plAbsolute,
- vHitNormal);
- // if the normal is more horizontal
- if (Abs(vHitNormal(2))<0.5f) {
- // calculate angles to align -z axis towards the plane
- DirectionVectorToAngles(-vHitNormal, plDrop.pl_OrientationAngle);
- }
- }
- pDoc->SnapToGrid( plDrop, m_fGridInMeters/GRID_DISCRETE_VALUES);
- // if the dragged object is an entity class
- if (fnDropped.FileExt()==".ecl")
- {
- // create dragged entity
- CPlacement3D plEntity;
- CEntity *pen = NULL;
- try
- {
- extern BOOL _bInOnDraw;
- _bInOnDraw = TRUE;
- pen = pDoc->m_woWorld.CreateEntity_t(plDrop, fnDropped);
- // prepare the entity
- pen->Initialize();
- _bInOnDraw = FALSE;
- // the drop was successful
- pDoc->SetModifiedFlag();
- // mark that document changeable was changed
- pDoc->m_chDocument.MarkChanged();
- }
- catch(char *err_str)
- {
- _bInOnDraw = FALSE;
- AfxMessageBox(CString(err_str));
- if (pen!=NULL) {
- pen->Destroy();
- }
- // the drop was no successful
- return;
- }
- // deselect all entities
- pDoc->m_selEntitySelection.Clear();
- // if succeseful, switch to entity mode and only-select dropped entity
- pDoc->m_selEntitySelection.Select( *pen);
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- // switch to entity mode
- OnEntityMode();
- // and refresh property combo manualy calling on idle
- pMainFrame->m_PropertyComboBar.m_PropertyComboBox.OnIdle( 0);
- if( (pen->GetRenderType() == CEntity::RT_BRUSH) ||
- (pen->GetRenderType() == CEntity::RT_FIELDBRUSH) )
- {
- pMainFrame->m_CSGDesitnationCombo.OnIdle(0);
- pMainFrame->m_CSGDesitnationCombo.SelectBrushEntity(pen);
- }
- pDoc->SetModifiedFlag( TRUE);
- pDoc->m_chDocument.MarkChanged();
- // update all views
- pDoc->UpdateAllViews( this);
- }
- // if the dragged object is a world
- else if (fnDropped.FileExt()==".wld")
- {
- pDoc->StartTemplateCSG( plDrop, fnDropped, FALSE /*don't reset angles*/);
- // the drop was successful
- return;
- }
- else if (fnDropped.FileExt()==".tex")
- {
- // if we hit some entity and hitted entity is brush
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- // try to apply dropped texture to current selection
- try
- {
- // if polygon that is hit with mouse is selected
- if( crRayHit.cr_pbpoBrushPolygon->IsSelected( BPOF_SELECTED))
- {
- // paste dropped texture over polygon selection
- pDoc->PasteTextureOverSelection_t( fnDropped);
- }
- // otherwise
- else
- {
- // paste it only for drop-hitted polygon
- crRayHit.cr_pbpoBrushPolygon->bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.SetData_t( fnDropped);
- // mark that document has been modified
- pDoc->SetModifiedFlag( TRUE);
- // mark that selections have been changed to update entity intersection properties
- pDoc->m_chSelections.MarkChanged();
- // update all views
- pDoc->UpdateAllViews( NULL);
- }
- }
- // if failed
- catch( char *err_str)
- {
- // report error
- AfxMessageBox( CString(err_str));
- return;
- }
- }
- else
- {
- // inform user that drop can be achived only over polygons
- AfxMessageBox( L"You can drop textures only by hitting some polygon, but You hit some entity.");
- return;
- }
- }
- else
- {
- // the drop was not successful, report error
- AfxMessageBox( L"You can drop only textures, classes and worlds.");
- return;
- }
- }
- /*
- * Get pointer to the child frame of this view.
- */
- CChildFrame *CWorldEditorView::GetChildFrame(void)
- {
- return (CChildFrame *)GetParentFrame();
- }
- void CWorldEditorView::OnIsometricFront()
- {
- m_ptProjectionType = CSlaveViewer::PT_ISOMETRIC_FRONT;
- Invalidate( FALSE);
- }
- void CWorldEditorView::OnIsometricBack()
- {
- m_ptProjectionType = CSlaveViewer::PT_ISOMETRIC_BACK;
- Invalidate( FALSE);
- }
- void CWorldEditorView::OnIsometricBottom()
- {
- m_ptProjectionType = CSlaveViewer::PT_ISOMETRIC_BOTTOM;
- Invalidate( FALSE);
- }
- void CWorldEditorView::OnIsometricLeft()
- {
- m_ptProjectionType = CSlaveViewer::PT_ISOMETRIC_LEFT;
- Invalidate( FALSE);
- }
- void CWorldEditorView::OnIsometricRight()
- {
- m_ptProjectionType = CSlaveViewer::PT_ISOMETRIC_RIGHT;
- Invalidate( FALSE);
- }
- void CWorldEditorView::OnIsometricTop()
- {
- m_ptProjectionType = CSlaveViewer::PT_ISOMETRIC_TOP;
- Invalidate( FALSE);
- }
- void CWorldEditorView::OnPerspective()
- {
- m_ptProjectionType = CSlaveViewer::PT_PERSPECTIVE;
- Invalidate( FALSE);
- }
- void CWorldEditorView::OnZoomLess()
- {
- // get draw port
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- // if it is not valid
- if( pdpValidDrawPort == NULL)
- {
- return;
- }
- CWorldEditorDoc* pDoc = GetDocument();
- // create a slave viewer
- CSlaveViewer svViewer(GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pdpValidDrawPort);
- // scale target distance by 2 - zoom out x2
- svViewer.ScaleTargetDistance( 2.0f);
- // copy slave viewer back to master
- GetChildFrame()->m_mvViewer = svViewer;
- // redraw all viewes
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnZoomMore()
- {
- // get draw port
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- // if it is not valid
- if( pdpValidDrawPort == NULL)
- {
- return;
- }
- CWorldEditorDoc* pDoc = GetDocument();
- // create a slave viewer
- CSlaveViewer svViewer(GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pdpValidDrawPort);
- // scale target distance by -1/2 - zoom in x2
- svViewer.ScaleTargetDistance( -0.5f);
- // copy slave viewer back to master
- GetChildFrame()->m_mvViewer = svViewer;
- // redraw all viewes
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::RotateOrStretchBrushVertex(FLOAT fDX, FLOAT fDY, BOOL bRotate)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // project translation vector from view space to absolute space
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- if( pdpValidDrawPort == NULL) return;
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pdpValidDrawPort);
- // both selection and coordinate arrays must be sinchronized
- if( pDoc->m_avStartDragVertices.Count()!=pDoc->m_selVertexSelection.Count()) {
- ASSERT(FALSE);
- return;
- }
- // -------- Calculate BBox of all selected brush vertices
- FLOATaabbox3D boxVtx;
- // for each vertex
- {for( INDEX iVtx=0; iVtx<pDoc->m_avStartDragVertices.Count(); iVtx++)
- {
- // get new position
- boxVtx |= DOUBLEtoFLOAT(pDoc->m_avStartDragVertices[ iVtx]);
- }}
-
- // create dummy placement
- CPlacement3D plDummy;
- plDummy.pl_PositionVector = boxVtx.Center();
- DOUBLE3D vCenter = FLOATtoDOUBLE(plDummy.pl_PositionVector);
- plDummy.pl_OrientationAngle = ANGLE3D(0.0f, 0.0f, 0.0f);
- // use trackball method for rotation
- if( bRotate)
- {
- svViewer.RotatePlacement_TrackBall( plDummy, -fDX, -fDY, 0);
- }
- // get rotation matrix
- FLOATmatrix3D t3dRotation;
- MakeRotationMatrixFast( t3dRotation, plDummy.pl_OrientationAngle);
- DOUBLEmatrix3D t3ddRotation;
- t3ddRotation = FLOATtoDOUBLE(t3dRotation);
- FLOAT fFactor=1.0f;
- if( !bRotate)
- {
- FLOAT fDiag=boxVtx.Size().Length();
- // fDY is actually current view's zoom factor
- fFactor=(fDiag+fDX/fDY)/fDiag;
- }
- // for each vertex
- INDEX iVtx = 0;
- {FOREACHINDYNAMICCONTAINER( pDoc->m_selVertexSelection, CBrushVertex, itbvx)
- {
- DOUBLE3D vRelative = pDoc->m_avStartDragVertices[ iVtx]-vCenter;
- // rotate vertex around bbox center to get new position
- DOUBLE3D vNew = vRelative*fFactor*t3ddRotation;
- // snap resulting vertex coordinate
- SnapVector(vNew);
- // set its new position
- itbvx->SetAbsolutePosition(vNew+vCenter);
- iVtx++;
- }}
- // update sectors
- pDoc->m_woWorld.UpdateSectorsDuringVertexChange( pDoc->m_selVertexSelection);
- }
- FLOAT3D CWorldEditorView::ProjectVectorToWorldSpace(FLOAT fDX,FLOAT fDY,FLOAT fDZ)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CPlacement3D plVector0(FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0));
- CPlacement3D plVector1(FLOAT3D(fDX,fDY,fDZ), ANGLE3D(0,0,0));
- CDrawPort *pdp = GetDrawPort();
- if( pdp == NULL)
- {
- ASSERTALWAYS("Invalid draw port found!");
- return FLOAT3D( 0.0f, 0.0f, 0.0f);
- }
- // project translation vector from view space to absolute space
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType, pDoc->m_plGrid, pdp);
- CPlacement3D plViewer = svViewer.GetViewerPlacement();
- plVector0.RelativeToAbsolute(plViewer);
- plVector1.RelativeToAbsolute(plViewer);
- // obtain translation vector from placements
- FLOAT3D vDelta = (plVector1.pl_PositionVector-plVector0.pl_PositionVector);
- return vDelta;
- }
- void CWorldEditorView::DragBrushVertex(FLOAT fDX,FLOAT fDY,FLOAT fDZ)
- {
- CWorldEditorDoc* pDoc = GetDocument();
-
- // obtain 3d translation vector
- DOUBLE3D vDelta = FLOATtoDOUBLE( ProjectVectorToWorldSpace( fDX, fDY, fDZ));
- // both selection and coordinate arrays must be sinchronized
- if( pDoc->m_avStartDragVertices.Count()!=pDoc->m_selVertexSelection.Count()) {
- ASSERT(FALSE);
- return;
- }
- // ---- apply movement
- // for each vertex
- INDEX iVtx = 0;
- {FOREACHINDYNAMICCONTAINER( pDoc->m_selVertexSelection, CBrushVertex, itbvx)
- {
- // get new position
- DOUBLE3D vNew = pDoc->m_avStartDragVertices[ iVtx] + vDelta;
- SnapVector( vNew);
- // set its new position
- itbvx->SetAbsolutePosition(vNew);
- iVtx++;
- }}
- // update sectors
- pDoc->m_woWorld.UpdateSectorsDuringVertexChange( pDoc->m_selVertexSelection);
- }
- void CWorldEditorView::DragVerticesOnPrimitive(FLOAT fDX,FLOAT fDY,FLOAT fDZ, BOOL bAbsolute,
- BOOL bSnap/*=TRUE*/)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CPlacement3D plVector0(FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0));
- CPlacement3D plVector1(FLOAT3D(fDX,fDY,fDZ), ANGLE3D(0,0,0));
- // project translation vector from view space to absolute space
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- if( pdpValidDrawPort == NULL) return;
- CSlaveViewer svViewer( GetChildFrame()->m_mvViewer, m_ptProjectionType,
- pDoc->m_plGrid, pdpValidDrawPort);
- CPlacement3D plViewer = svViewer.GetViewerPlacement();
- plVector0.RelativeToAbsolute(plViewer);
- plVector1.RelativeToAbsolute(plViewer);
- // project translation vector from absolute space to second layer space
- plVector0.AbsoluteToRelative(pDoc->m_plSecondLayer);
- plVector1.AbsoluteToRelative(pDoc->m_plSecondLayer);
- // extract translation vector from placements
- DOUBLE3D vDelta = FLOATtoDOUBLE(plVector1.pl_PositionVector)-
- FLOATtoDOUBLE(plVector0.pl_PositionVector);
- theApp.m_vfpCurrent.vfp_o3dPrimitive.ob_aoscSectors.Lock();
- CDynamicArray<CObjectVertex> &aVtx = theApp.m_vfpCurrent.vfp_o3dPrimitive.ob_aoscSectors[0].osc_aovxVertices;
- theApp.m_vfpCurrent.vfp_o3dPrimitive.ob_aoscSectors.Unlock();
- aVtx.Lock();
- DOUBLE3D vClosest;
- DOUBLE3D vFirstInSelection;
- BOOL bHasSelection = FALSE;
- // see if any of the vertices is selected
- INDEX iVtx=0;
- for( ; iVtx<aVtx.Count(); iVtx++)
- {
- if( aVtx[ iVtx].ovx_ulFlags & OVXF_CLOSEST) vClosest = aVtx[ iVtx];
- if( (aVtx[ iVtx].ovx_ulFlags & OVXF_SELECTED) && !bHasSelection)
- {
- vFirstInSelection = aVtx[ iVtx];
- bHasSelection = TRUE;
- }
- }
- DOUBLE3D vVectorForAdding;
- // if given delta vector should be applied absolutly
- if( bAbsolute)
- {
- vVectorForAdding = vDelta;
- }
- else
- {
- if( bHasSelection)
- {
- vVectorForAdding = m_vStartDragO3DVertice+vDelta-vFirstInSelection;
- }
- else
- {
- vVectorForAdding = m_vStartDragO3DVertice+vDelta-vClosest;
- }
- }
- // apply movement
- for( iVtx=0; iVtx<aVtx.Count(); iVtx++)
- {
- if( ((aVtx[ iVtx].ovx_ulFlags & OVXF_CLOSEST) && !bHasSelection) ||
- ((aVtx[ iVtx].ovx_ulFlags & OVXF_SELECTED) && bHasSelection) )
- {
- aVtx[ iVtx] += vVectorForAdding;
-
- if( pDoc->m_bAutoSnap && bSnap)
- {
- // snap resulting vertex coordinate
- Snap(aVtx[iVtx](1), m_fGridInMeters/GRID_DISCRETE_VALUES);
- Snap(aVtx[iVtx](2), m_fGridInMeters/GRID_DISCRETE_VALUES);
- Snap(aVtx[iVtx](3), m_fGridInMeters/GRID_DISCRETE_VALUES);
- }
- else
- {
- Snap(aVtx[iVtx](1), SNAP_DOUBLE_CM);
- Snap(aVtx[iVtx](2), SNAP_DOUBLE_CM);
- Snap(aVtx[iVtx](3), SNAP_DOUBLE_CM);
- }
- }
- }
- aVtx.Unlock();
- pDoc->ConvertObject3DToBrush(theApp.m_vfpCurrent.vfp_o3dPrimitive, TRUE);
- // redraw all viewes
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnMoveUp()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( (pDoc->m_pwoSecondLayer != NULL) &&
- (pDoc->m_bPrimitiveMode) &&
- (theApp.m_vfpCurrent.vfp_ttTriangularisationType != TT_NONE) &&
- ((!theApp.m_vfpCurrent.vfp_bAutoCreateMipBrushes)||
- (theApp.m_vfpCurrent.vfp_ptPrimitiveType != PT_TERRAIN)) )
- {
- MarkClosestVtxOnPrimitive( FALSE);
- DragVerticesOnPrimitive( 0.0, 0.0, m_fGridInMeters/GRID_DISCRETE_VALUES, TRUE, FALSE);
- }
- // redraw all viewes
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnMoveDown()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( (pDoc->m_pwoSecondLayer != NULL) &&
- (pDoc->m_bPrimitiveMode) &&
- (theApp.m_vfpCurrent.vfp_ttTriangularisationType != TT_NONE) &&
- ((!theApp.m_vfpCurrent.vfp_bAutoCreateMipBrushes)||
- (theApp.m_vfpCurrent.vfp_ptPrimitiveType != PT_TERRAIN)) )
- {
- MarkClosestVtxOnPrimitive( FALSE);
- DragVerticesOnPrimitive( 0.0, 0.0, -m_fGridInMeters/GRID_DISCRETE_VALUES, TRUE, FALSE);
- }
- // redraw all viewes
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnMeasurementTape()
- {
- m_vpViewPrefs.m_bMeasurementTape = !m_vpViewPrefs.m_bMeasurementTape;
- Invalidate( FALSE);
- }
- void CWorldEditorView::OnUpdateMeasurementTape(CCmdUI* pCmdUI)
- {
- if( m_ptProjectionType == CSlaveViewer::PT_PERSPECTIVE)
- {
- pCmdUI->Enable( FALSE);
- pCmdUI->SetCheck( FALSE);
- }
- else
- {
- pCmdUI->Enable( TRUE);
- pCmdUI->SetCheck( m_vpViewPrefs.m_bMeasurementTape);
- }
- }
- void CWorldEditorView::OnKeyBuffer(UINT nID)
- {
- // get difference of key "1", which means buffer index
- INDEX iPreferencesBuffer = nID-ID_BUFFER01;
- // copy selected preferences to view's rendering preferences
- m_vpViewPrefs = theApp.m_vpViewPrefs[ iPreferencesBuffer];
- // see the change
- Invalidate( FALSE);
- }
- void CWorldEditorView::OnKeyEditBuffer(UINT nID)
- {
- // get difference of key "1", which means buffer index
- INDEX iPreferencesBuffer = nID-ID_EDIT_BUFFER01;
- CDlgRenderingPreferences dlg( iPreferencesBuffer);
- // if dialog ended with cancel or esc, dont switch to changed preferences
- if( dlg.DoModal() != IDOK)
- {
- // don't set new preferences
- return;
- }
- // copy selected preferences to view's rendering preferences
- m_vpViewPrefs = theApp.m_vpViewPrefs[ iPreferencesBuffer];
- // see the change
- Invalidate( FALSE);
- }
- void CWorldEditorView::OnCircleModes()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- switch( pDoc->GetEditingMode())
- {
- case ENTITY_MODE: { pDoc->SetEditingMode( SECTOR_MODE); break;};
- case SECTOR_MODE: { pDoc->SetEditingMode( POLYGON_MODE); break;};
- case POLYGON_MODE: { pDoc->SetEditingMode( VERTEX_MODE); break;};
- case VERTEX_MODE: { pDoc->SetEditingMode( TERRAIN_MODE); break;};
- case TERRAIN_MODE: { pDoc->SetEditingMode( ENTITY_MODE); break;};
- default: { FatalError("Unknown editing mode."); break;};
- }
- }
- void CWorldEditorView::OnUpdateCircleModes(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pCmdUI->Enable( pDoc->GetEditingMode() != CSG_MODE);
- }
- void CWorldEditorView::OnDeselectAll()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pDoc->DeselectAll();
- BOOL bCSGOn = pDoc->m_pwoSecondLayer != NULL;
- // if we are in triangularisation primitive mode
- if( (theApp.m_vfpCurrent.vfp_ttTriangularisationType != TT_NONE) &&
- (bCSGOn && pDoc->m_bPrimitiveMode) )
- {
- theApp.m_vfpCurrent.vfp_o3dPrimitive.ob_aoscSectors.Lock();
- CDynamicArray<CObjectVertex> &aVtx = theApp.m_vfpCurrent.vfp_o3dPrimitive.ob_aoscSectors[0].osc_aovxVertices;
- theApp.m_vfpCurrent.vfp_o3dPrimitive.ob_aoscSectors.Unlock();
- aVtx.Lock();
- // reset selected flags for all vertices
- for( INDEX iVtx=0; iVtx<aVtx.Count(); iVtx++)
- {
- aVtx[ iVtx].ovx_ulFlags &= ~OVXF_SELECTED;
- }
- aVtx.Unlock();
- // update all views
- pDoc->UpdateAllViews(NULL);
- }
- }
- void CWorldEditorView::RemoveFromLinkedChain(CEntity *pen)
- {
- CTFileName fnDropClass;
- CTString strTargetProperty;
- CEntityProperty *penpProperty;
- CEntity &enOnly = *pen;
- // obtain drop class and target property name
- if( !enOnly.DropsMarker( fnDropClass, strTargetProperty)) return;
- penpProperty = enOnly.PropertyForName( strTargetProperty);
- CEntity *penHisTarget = ENTITYPROPERTY( &enOnly, penpProperty->ep_slOffset, CEntityPointer);
- // or ptr is NULL
- if( penHisTarget == NULL) return;
- CEntity *penCurrent = pen;
- INDEX iInfiniteLoopProtector = 0;
- // loop forever
- FOREVER
- {
- if( !penCurrent->DropsMarker( fnDropClass, strTargetProperty)) return;
- penpProperty = penCurrent->PropertyForName( strTargetProperty);
- CEntity *penNext = ENTITYPROPERTY( penCurrent, penpProperty->ep_slOffset, CEntityPointer);
- if( penNext == NULL) return;
- if( penNext == pen) break;
- // jump to next in chain
- penCurrent = penNext;
- iInfiniteLoopProtector ++;
- if( iInfiniteLoopProtector >= 256) return;
- }
- if( !penCurrent->DropsMarker( fnDropClass, strTargetProperty)) return;
- penpProperty = penCurrent->PropertyForName( strTargetProperty);
- ENTITYPROPERTY( penCurrent, penpProperty->ep_slOffset, CEntityPointer) = penHisTarget;
- }
- void CWorldEditorView::OnDeleteEntities()
- {
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == CSG_MODE) return;
- if( pDoc->GetEditingMode() == SECTOR_MODE)
- {
- if( pDoc->m_selSectorSelection.Count() != 0)
- {
- if( theApp.m_Preferences.ap_bSaveUndoForDelete)
- {
- pDoc->RememberUndo();
- }
- pDoc->ClearSelections( ST_SECTOR);
- pDoc->m_woWorld.DeleteSectors( pDoc->m_selSectorSelection, TRUE);
- }
- }
- else
- {
- // if any of selected entities is anchored, anchored operation flag must be allowed or deleting is disabled
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- if( (iten->GetFlags() & ENF_ANCHORED) && !GetChildFrame()->m_bAncoredMovingAllowed) return;
- }}
- }
- if( pDoc->m_selEntitySelection.Count() != 0)
- {
- if( theApp.m_Preferences.ap_bSaveUndoForDelete)
- {
- pDoc->RememberUndo();
- }
- }
- // check for deleting terrain
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- CEntity &en=*iten;
- // if it is terrain
- if(en.GetRenderType()==CEntity::RT_TERRAIN)
- {
- // if it is selected terrain
- if(pDoc->m_ptrSelectedTerrain==en.GetTerrain())
- {
- pDoc->m_ptrSelectedTerrain=NULL;
- theApp.m_ctTerrainPage.MarkChanged();
- break;
- }
- }
- }}
- // for each of the selected entities
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- if( pDoc->m_cenEntitiesSelectedByVolume.IsMember(iten))
- pDoc->m_cenEntitiesSelectedByVolume.Remove(iten);
- }}
- // for each of the selected entities
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- RemoveFromLinkedChain(iten);
- }}
- // clear selections
- pDoc->m_selVertexSelection.Clear();
- pDoc->m_selSectorSelection.Clear();
- pDoc->m_selPolygonSelection.Clear();
- // delete all selected entities
- pDoc->m_woWorld.DestroyEntities( pDoc->m_selEntitySelection);
- }
- // mark that document was changed (for saving)
- pDoc->SetModifiedFlag();
- // mark that document changeable was changed to update CSG target combo box
- pDoc->m_chDocument.MarkChanged();
- // mark that selections have been changed to update entity intersection properties
- pDoc->m_chSelections.MarkChanged();
- // update all views
- pDoc->UpdateAllViews(NULL);
- }
- void CWorldEditorView::OnUpdateDeleteEntities(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == ENTITY_MODE)
- {
- pCmdUI->Enable( IsDeleteEntityEnabled());
- }
- else if( pDoc->GetEditingMode() == SECTOR_MODE)
- {
- pCmdUI->Enable( pDoc->m_woWorld.CanCopySectors( pDoc->m_selSectorSelection));
- }
- else
- {
- pCmdUI->Enable( FALSE);
- }
- }
- BOOL CWorldEditorView::IsDeleteEntityEnabled(void)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // enable button if we are in entity mode and there is at least 1 brush entity unselected
- BOOL bEnable = FALSE;
- if( (pDoc->GetEditingMode() == ENTITY_MODE) &&
- (pDoc->m_selEntitySelection.Count() != 0) )
- {
- // for all of the world's entities
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- // if the entity is brush
- if (iten->GetRenderType() == CEntity::RT_BRUSH)
- {
- // if this is brush entity and is not selected
- if( !iten->IsSelected( ENF_SELECTED))
- {
- // enable delete entity button
- bEnable = TRUE;
- break;
- }
- }
- }
- }
- return bEnable;
- }
- void CWorldEditorView::UpdateCursor(void)
- {
- BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0;
- BOOL bCtrl = (GetKeyState( VK_CONTROL)&0x8000) != 0;
- CWorldEditorDoc* pDoc = GetDocument();
- CTerrainLayer *ptlLayer=GetLayer();
- if( theApp.m_bMeasureModeOn)
- {
- SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
- }
- else if( theApp.m_bCutModeOn)
- {
- if( pDoc->GetEditingMode() == ENTITY_MODE)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_MIRROR));
- }
- else
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_CUT_LINE));
- }
- }
- else if( pDoc->GetEditingMode()==TERRAIN_MODE && GetTerrain()!=NULL && ptlLayer!=NULL)
- {
- if(bCtrl&&bAlt)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_PICK));
- }
- else if(theApp.m_iTerrainEditMode==TEM_LAYER && ptlLayer->tl_ltType==LT_TILE)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_TILE_PAINTING));
- }
- else if(theApp.m_iTerrainBrushMode==TBM_ERASE)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_ERASE));
- }
- else if(theApp.m_iTerrainBrushMode==TBM_SMOOTH)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_SMOOTH));
- }
- else if(theApp.m_iTerrainBrushMode==TBM_FILTER)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_FILTER));
- }
- else if(theApp.m_iTerrainBrushMode==TBM_MINIMUM)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_MIN));
- }
- else if(theApp.m_iTerrainBrushMode==TBM_MAXIMUM)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_MAX));
- }
- else if(theApp.m_iTerrainBrushMode==TBM_FLATTEN)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_FLATTEN));
- }
- else if(theApp.m_iTerrainBrushMode==TBM_POSTERIZE)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_POSTERIZE));
- }
- else if(theApp.m_iTerrainBrushMode==TBM_RND_NOISE)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_RND_NOISE));
- }
- else if(theApp.m_iTerrainBrushMode==TBM_CONTINOUS_NOISE)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_CONTINOUS_NOISE));
- }
- else if(theApp.m_iTerrainBrushMode==TBM_PAINT)
- {
- if(theApp.m_iTerrainEditMode==TEM_HEIGHTMAP)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_HEIGHTMAP));
- }
- else if(theApp.m_iTerrainEditMode==TEM_LAYER)
- {
- SetCursor( AfxGetApp()->LoadCursor(IDC_TE_LAYER_PAINT));
- }
- }
- }
- else
- {
- SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
- }
- }
- BOOL CWorldEditorView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
- {
- return TRUE;
- }
- void CWorldEditorView::OnTakeSs()
- {
- // get draw port
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- // if it is not valid
- if( pdpValidDrawPort == NULL)
- {
- return;
- }
- CImageInfo iiImageInfo;
- /* First remember current screen-shot in memory. */
- if( pdpValidDrawPort->Lock())
- {
- RenderView( pdpValidDrawPort);
- pdpValidDrawPort->Unlock();
- }
- // grab screen creating image info
- pdpValidDrawPort->GrabScreen( iiImageInfo, 1);
- // ask for save screen shot name
- CTFileName fnDocName = CTString( CStringA(GetDocument()->GetPathName()));
- CTFileName fnScreenShoot = _EngineGUI.FileRequester(
- "Choose file name for screen shoot", FILTER_TGA FILTER_ALL FILTER_END, KEY_NAME_SCREEN_SHOT_DIR,
- "ScreenShots\\", fnDocName.FileName()+"xx"+".tga", NULL, FALSE);
- if( fnScreenShoot == "") return;
- // try to
- try {
- // save screen shot as TGA
- iiImageInfo.SaveTGA_t( fnScreenShoot);
- } // if failed
- catch (char *strError) {
- // report error
- AfxMessageBox(CString(strError));
- }
- }
- void CWorldEditorView::OnEntityMode()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pDoc->SetEditingMode( ENTITY_MODE);
- }
- void CWorldEditorView::OnUpdateEntityMode(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pCmdUI->Enable( pDoc->GetEditingMode() != CSG_MODE);
- }
- void CWorldEditorView::OnTerrainMode()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pDoc->SetEditingMode( TERRAIN_MODE);
- }
- void CWorldEditorView::OnUpdateTerrainMode(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pCmdUI->Enable( pDoc->GetEditingMode() != CSG_MODE);
- }
- void CWorldEditorView::OnSectorMode()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pDoc->SetEditingMode( SECTOR_MODE);
- }
- void CWorldEditorView::OnUpdateSectorMode(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pCmdUI->Enable( pDoc->GetEditingMode() != CSG_MODE);
- }
- void CWorldEditorView::OnPolygonMode()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pDoc->SetEditingMode( POLYGON_MODE);
- }
- void CWorldEditorView::OnUpdatePolygonMode(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pCmdUI->Enable( pDoc->GetEditingMode() != CSG_MODE);
- }
- void CWorldEditorView::OnEditCopy()
- {
- EditCopy( FALSE);
- }
- void CWorldEditorView::OnVertexMode()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pDoc->OnCsgCancel();
- }
- void CWorldEditorView::EditCopy( BOOL bAlternative)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- BOOL bCopyWorld = FALSE;
- // if we are in entity mode
- if( pDoc->GetEditingMode() == ENTITY_MODE)
- {
- // if we have some entities selected
- if( pDoc->m_selEntitySelection.Count() != 0)
- {
- if( bAlternative)
- {
- CDynamicContainer<CEntity> selClones;
- CPlacement3D plPaste = GetMouseInWorldPlacement();
- // for all selected entities
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- CEntity *pClone = pDoc->m_woWorld.CopyEntityInWorld( *iten, plPaste);
- selClones.Add( pClone);
- }}
- // clear old selection and select clones
- pDoc->m_selEntitySelection.Clear();
- {FOREACHINDYNAMICCONTAINER( selClones, CEntity, itenClone)
- {
- pDoc->m_selEntitySelection.Select( *itenClone);
- }}
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag();
- pDoc->UpdateAllViews( NULL);
- }
- else
- {
- // calculate bounding boxes of all selected entities
- FLOATaabbox3D boxEntities;
- // for all selected entities
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- FLOATaabbox3D boxCurrentEntity;
- iten->GetSize( boxCurrentEntity);
- boxCurrentEntity += iten->GetPlacement().pl_PositionVector;
- boxEntities |= boxCurrentEntity;
- }}
- // average for all vectors of entities
- FLOAT3D vCenter = boxEntities.Center();
- vCenter(2) = boxEntities.Min()(2);
- CPlacement3D plCenter = CPlacement3D( -vCenter, ANGLE3D(0,0,0) );
- FLOAT3D vSize = boxEntities.Size();
- FLOAT fMaxEdge = Max( Max(vSize(1), vSize(2)), vSize(3));
- FLOAT fSnapValue;
- if( theApp.m_bDecadicGrid)
- {
- INDEX iLog = (INDEX) (Log2( fMaxEdge/GRID_DISCRETE_VALUES)/Log2(10.0f));
- fSnapValue = FLOAT(pow(10.0f, iLog));
- }
- else
- {
- INDEX iLog = (INDEX) Log2( fMaxEdge/GRID_DISCRETE_VALUES);
- fSnapValue = FLOAT(pow(2.0f, iLog));
- }
- pDoc->SnapToGrid( plCenter, fSnapValue);
- // create world to receive selected entities
- CWorld woEntityClipboard;
- woEntityClipboard.SetBackgroundColor( C_WHITE);
- woEntityClipboard.SetDescription( "No description");
- theApp.m_ctLastCopyType = CT_ENTITY;
- // copy entities in selection
- CEntitySelection senDummy;
- woEntityClipboard.CopyEntities(pDoc->m_woWorld, pDoc->m_selEntitySelection,
- senDummy, plCenter);
- senDummy.Clear();
- // try to
- try
- {
- // save entity clipboard world
- woEntityClipboard.Save_t(CTString("Temp\\ClipboardEntityWorld.wld"));
- }
- catch( char *strError)
- {
- AfxMessageBox( CString(strError));
- return;
- }
- }
- }
- else
- {
- // we will copy whole world
- bCopyWorld = TRUE;
- }
- }
- // if we are in polygon mode
- else if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- // obtain point in the world where mouse pointed last time it was moved
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse, FALSE, FALSE, FALSE);
- // if mouse is over polygon
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- // remember selected polygon's parameters to application
- theApp.m_pbpoClipboardPolygon->CopyProperties( *crRayHit.cr_pbpoBrushPolygon);
- if( bAlternative)
- {
- theApp.m_ctLastCopyType = CT_POLYGON_PROPERTIES_ALTERNATIVE;
- CopyMapping(crRayHit.cr_pbpoBrushPolygon);
- }
- else
- {
- theApp.m_ctLastCopyType = CT_POLYGON_PROPERTIES;
- }
- }
- else
- {
- // we will copy whole world
- bCopyWorld = TRUE;
- }
- }
- // if we are in sector mode
- else if( pDoc->GetEditingMode() == SECTOR_MODE)
- {
- // if there are no sectors selected
- if( pDoc->m_selSectorSelection.Count() == 0)
- {
- // we will copy whole world
- bCopyWorld = TRUE;
- }
- // copy selected sectors
- else
- {
- if( !pDoc->m_woWorld.CanCopySectors( pDoc->m_selSectorSelection))
- {
- WarningMessage( "Error: Can't copy selected sectors. "
- "All sectors must be in same brush and same mip factor.");
- return;
- }
- // create world to receive selected sectors
- CWorld woClipboard;
- woClipboard.SetBackgroundColor( C_WHITE);
- woClipboard.SetDescription( "No description");
- // now create world base entity
- CEntity *penWorldBase;
- CPlacement3D plWorld = CPlacement3D( FLOAT3D(0.0f,0.0f,0.0f), ANGLE3D(0,0,0));
- // try to
- try
- {
- penWorldBase = woClipboard.CreateEntity_t(plWorld, CTFILENAME("Classes\\WorldBase.ecl"));
- }
- // catch and
- catch( char *err_str)
- {
- // report errors
- WarningMessage( err_str);
- return;
- }
- // prepare the entity
- penWorldBase->Initialize();
- EFirstWorldBase eFirstWorldBase;
- penWorldBase->SendEvent( eFirstWorldBase);
- CEntity::HandleSentEvents();
- pDoc->m_woWorld.CopySectors( pDoc->m_selSectorSelection, penWorldBase, !bAlternative);
- try
- {
- // save world to clipboard
- woClipboard.Save_t(CTString("Temp\\ClipboardSectorWorld.wld"));
- }
- catch( char *strError)
- {
- AfxMessageBox( CString(strError));
- return;
- }
- theApp.m_ctLastCopyType = CT_SECTOR;
- }
- }
- // if we should copy the whole world
- if( bCopyWorld)
- {
- try
- {
- // save world into clipboard file
- pDoc->m_woWorld.Save_t( (CTString)"Temp\\ClipboardWorld.wld");
- }
- catch( char *strError)
- {
- AfxMessageBox( CString(strError));
- }
- theApp.m_ctLastCopyType = CT_WORLD;
- }
- }
- // obtain point in the world where mouse pointed last time it was moved
- CPlacement3D CWorldEditorView::GetMouseInWorldPlacement(void)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // get hitted point
- CPlacement3D plMouse;
- // if any kind of entity was hitted with mouse
- if( crRayHit.cr_penHit != NULL)
- {
- // hitted entity exist
- plMouse.pl_PositionVector = crRayHit.cr_vHit;
- }
- // if none of entities (brushes) was hitted with mouse
- else
- {
- // set position in front of viewer, at the placement of viewing point (target)
- plMouse = GetChildFrame()->m_mvViewer.GetTargetPlacement();
- }
- // reset angles
- plMouse.pl_OrientationAngle = ANGLE3D(0,0,0);
- // snap placement
- pDoc->SnapToGrid( plMouse, m_fGridInMeters/GRID_DISCRETE_VALUES);
- return plMouse;
- }
- void CWorldEditorView::OnEditPaste()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- BOOL bCSGOn = pDoc->m_pwoSecondLayer != NULL;
- // You can't paste anything while CSG is on
- if( bCSGOn)
- {
- return;
- }
- BOOL bHitModels = FALSE;
- if( theApp.m_ctLastCopyType == CT_ENTITY) bHitModels = TRUE;
- CPlacement3D plPaste = GetMouseInWorldPlacement();
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse, FALSE, bHitModels, FALSE);
- // if last copy operation was with entities
- if( theApp.m_ctLastCopyType == CT_ENTITY)
- {
- // switch to entity mode
- pDoc->SetEditingMode( ENTITY_MODE);
- // create world to receive pasted entities
- CWorld woEntityClipboard;
- // try to
- try
- {
- // load clipboard entity World
- woEntityClipboard.Load_t( (CTString)"Temp\\ClipboardEntityWorld.wld");
- }
- catch( char *err_str)
- {
- AfxMessageBox( CString(err_str));
- return;
- }
- // deselect all entities
- pDoc->m_selEntitySelection.Clear();
- // make container of entities to copy
- CDynamicContainer<CEntity> cenToCopy;
- cenToCopy = woEntityClipboard.wo_cenEntities;
- // remove empty brushes from it
- {FOREACHINDYNAMICCONTAINER(woEntityClipboard.wo_cenEntities, CEntity, iten)
- {
- if( iten->IsEmptyBrush() && (iten->GetFlags()&ENF_ZONING))
- {
- cenToCopy.Remove(iten);
- }
- }}
- // copy entities in clipboard
- pDoc->m_woWorld.CopyEntities(woEntityClipboard, cenToCopy,
- pDoc->m_selEntitySelection, plPaste);
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag();
- pDoc->UpdateAllViews( NULL);
- }
- // if last copy operation was with polygon properties
- else if( theApp.m_ctLastCopyType == CT_POLYGON_PROPERTIES)
- {
- // if mouse is over polygon
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- if( crRayHit.cr_pbpoBrushPolygon->IsSelected( BPOF_SELECTED))
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- // apply remembered polygon's parameters to selection
- itbpo->CopyTextures( *theApp.m_pbpoClipboardPolygon);
- }
- }
- else
- {
- // apply remembered polygon's parameters to polygon under mouse
- crRayHit.cr_pbpoBrushPolygon->CopyTextures( *theApp.m_pbpoClipboardPolygon);
- }
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag();
- pDoc->UpdateAllViews( NULL);
- }
- // if last copy operation was with whole world
- else if( theApp.m_ctLastCopyType == CT_WORLD)
- {
- // load world from clipboard file and start template CSG
- pDoc->StartTemplateCSG( plPaste, (CTString)"Temp\\ClipboardWorld.wld");
- }
- // if last copy operation was with selected sectors
- else if( theApp.m_ctLastCopyType == CT_SECTOR)
- {
- // load world from sectors clipboard file and start template CSG
- pDoc->StartTemplateCSG( plPaste, (CTString)"Temp\\ClipboardSectorWorld.wld");
- }
- }
- void ProcesWEDConsoleShortcuts( MSG *pMsg)
- {
- if( pMsg->message==WM_KEYDOWN)
- {
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- if( !bShift && pMsg->wParam == VK_F2) _pShell->Execute( "include \"Scripts\\WorldEditorKeys\\F2.ini\"");
- if( !bShift && pMsg->wParam == VK_F3) _pShell->Execute( "include \"Scripts\\WorldEditorKeys\\F3.ini\"");
- if( !bShift && pMsg->wParam == VK_F4) _pShell->Execute( "include \"Scripts\\WorldEditorKeys\\F4.ini\"");
- if( bShift && (pMsg->wParam == VK_F2)) _pShell->Execute( "include \"Scripts\\WorldEditorKeys\\Shift_F2.ini\"");
- if( bShift && (pMsg->wParam == VK_F3)) _pShell->Execute( "include \"Scripts\\WorldEditorKeys\\Shift_F3.ini\"");
- if( bShift && (pMsg->wParam == VK_F4)) _pShell->Execute( "include \"Scripts\\WorldEditorKeys\\Shift_F4.ini\"");
- }
- if( pMsg->message==WM_MBUTTONDOWN || pMsg->message==WM_MBUTTONDBLCLK )
- {
- _pShell->Execute( "include \"Scripts\\WorldEditorKeys\\MiddleMouse.ini\"");
- }
- }
- BOOL CWorldEditorView::PreTranslateMessage(MSG* pMsg)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- // get csg and primitive flags
- BOOL bCSGOn = pDoc->m_pwoSecondLayer != NULL;
- BOOL bPrimitive = pDoc->m_bPrimitiveMode;
- // get editting mode flags
- BOOL bEntityMode = pDoc->GetEditingMode() == ENTITY_MODE;
- BOOL bSectorMode = pDoc->GetEditingMode() == SECTOR_MODE;
- BOOL bPolygonMode = pDoc->GetEditingMode() == POLYGON_MODE;
- BOOL bTerrainMode = pDoc->GetEditingMode() == TERRAIN_MODE;
- // get key statuses
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0;
- BOOL bCtrl = (GetKeyState( VK_CONTROL)&0x8000) != 0;
- BOOL bSpace = (GetKeyState( VK_SPACE)&0x8000) != 0;
- // get mouse button statuses
- BOOL bLMB = (GetKeyState( VK_LBUTTON)&0x8000) != 0;
- BOOL bRMB = (GetKeyState( VK_RBUTTON)&0x8000) != 0;
- // process scripts that are invoked on shortcuts from within WED
- ProcesWEDConsoleShortcuts( pMsg);
- // Ctrl +'A':
- // - entity -> select all in volume
- // - sector -> select all entities
- // - polygon -> select all polygons in sector(s)
- // Alt+'A'
- // - sector -> show all sectors
- // - entity -> show all entities
- // - polygon-> auto fit mapping
- // - vertex-> auto fit mapping
- // 'A':
- // - select by volume -> allign volume
- // - entity -> allign entity selection or world
- // - primitive -> allign primitive to screen
- // - sector -> allign visible sectors to screen
- if( ((pMsg->message==WM_KEYDOWN) || (pMsg->message==WM_SYSKEYDOWN)) &&
- ((int)pMsg->wParam=='A') )
- {
- // setup mouse - ray hit information
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- m_penEntityHitOnContext = crRayHit.cr_penHit;
- if( (crRayHit.cr_penHit != NULL) && (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- m_pbpoRightClickedPolygon = crRayHit.cr_pbpoBrushPolygon;
- }
- if( bCSGOn && !bShift)
- {
- if( bCtrl && bPrimitive)
- {
- OnAlignPrimitive();
- }
- else
- {
- FLOATaabbox3D boxSecondLayer;
- FOREACHINDYNAMICCONTAINER(pDoc->m_pwoSecondLayer->wo_cenEntities, CEntity, iten)
- {
- FLOATaabbox3D box;
- iten->GetSize( box);
-
- FLOAT fMinX = box.Min()(1);
- FLOAT fMinY = box.Min()(2);
- FLOAT fMinZ = box.Min()(3);
- FLOAT fMaxX = box.Max()(1);
- FLOAT fMaxY = box.Max()(2);
- FLOAT fMaxZ = box.Max()(3);
- FLOAT3D avCorners[8];
- avCorners[0] = FLOAT3D(fMinX,fMinY,fMinZ);
- avCorners[1] = FLOAT3D(fMaxX,fMinY,fMinZ);
- avCorners[2] = FLOAT3D(fMaxX,fMinY,fMaxZ);
- avCorners[3] = FLOAT3D(fMinX,fMinY,fMaxZ);
- avCorners[4] = FLOAT3D(fMinX,fMaxY,fMinZ);
- avCorners[5] = FLOAT3D(fMaxX,fMaxY,fMinZ);
- avCorners[6] = FLOAT3D(fMaxX,fMaxY,fMaxZ);
- avCorners[7] = FLOAT3D(fMinX,fMaxY,fMaxZ);
-
- for( INDEX iVtx=0; iVtx<8; iVtx++)
- {
- CPlacement3D plToProject = CPlacement3D( avCorners[iVtx], ANGLE3D(0,0,0));
- plToProject.RelativeToAbsolute( pDoc->m_plSecondLayer);
- boxSecondLayer |= FLOATaabbox3D(plToProject.pl_PositionVector);
- }
- }
- AllignBox( boxSecondLayer);
- }
- }
- else if( pDoc->GetEditingMode() == ENTITY_MODE && !bShift)
- {
- if( bCtrl && bAlt)
- {
- OnSelectAllSectors();
- }
- else if( bCtrl)
- {
- pDoc->OnSelectAllInVolume();
- }
- else if( bAlt)
- {
- pDoc->OnShowAllEntities();
- }
- else if( pDoc->m_bBrowseEntitiesMode)
- {
- OnAlignVolume();
- }
- else
- {
- CenterSelected();
- }
- }
- else if(pDoc->GetEditingMode() == SECTOR_MODE && !bShift)
- {
- if( bCtrl && bAlt)
- {
- OnSelectAllPolygons();
- }
- else if( bCtrl)
- {
- OnSelectAllEntitiesInSectors();
- }
- else if( bAlt)
- {
- pDoc->OnShowAllSectors();
- }
- else
- {
- CenterSelected();
- }
- }
- else if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- if( bCtrl && bAlt && !bShift)
- {
- OnSelectAllVertices();
- }
- else if( bCtrl && !bShift && !bAlt)
- {
- if( (crRayHit.cr_penHit != NULL) && (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- // select all polygons in hitted sector
- CBrushSector *pbscSector = crRayHit.cr_pbpoBrushPolygon->bpo_pbscSector;
- FOREACHINSTATICARRAY(pbscSector->bsc_abpoPolygons, CBrushPolygon, itpo)
- {
- if( !itpo->IsSelected(BPOF_SELECTED)) pDoc->m_selPolygonSelection.Select( *itpo);
- }
- pDoc->m_chSelections.MarkChanged();
- }
- }
- else if( bAlt && bShift && bCtrl)
- {
- if( crRayHit.cr_penHit != NULL)
- {
- AutoFitMapping( crRayHit.cr_pbpoBrushPolygon, TRUE, TRUE);
- }
- }
- else if( bAlt && bShift)
- {
- if( crRayHit.cr_penHit != NULL)
- {
- AutoFitMapping( crRayHit.cr_pbpoBrushPolygon, TRUE);
- }
- }
- else if( bAlt)
- {
- if( crRayHit.cr_penHit != NULL)
- {
- AutoFitMapping( crRayHit.cr_pbpoBrushPolygon);
- }
- }
- else if(!bCtrl&&!bShift&&!bAlt)
- {
- CenterSelected();
- }
- }
- else if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- if(!bCtrl&&!bShift&&!bAlt)
- {
- CenterSelected();
- }
- }
- else if(pDoc->GetEditingMode() == VERTEX_MODE && !bShift)
- {
- if( bCtrl && bAlt)
- {
- if( (crRayHit.cr_penHit != NULL) && (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- // select all vertices on hitted polygon
- FOREACHINSTATICARRAY(crRayHit.cr_pbpoBrushPolygon->bpo_apbvxTriangleVertices, CBrushVertex *, itpbvx)
- {
- if( !(*itpbvx)->IsSelected(BVXF_SELECTED)) pDoc->m_selVertexSelection.Select( **itpbvx);
- }
- }
- pDoc->m_chSelections.MarkChanged();
- }
- else if( bCtrl||bAlt)
- {
- CDlgAllignVertices dlg;
- dlg.DoModal();
- return TRUE;
- }
- else
- {
- CenterSelected();
- }
- }
- }
- // if return is pressed in primitive CSG mode
- if( (pMsg->message==WM_KEYDOWN) && ((int)pMsg->wParam==VK_RETURN) && bCSGOn && bPrimitive)
- {
- pMainFrame->ShowInfoWindow();
- CInfoSheet *pSheet = pMainFrame->m_pInfoFrame->m_pInfoSheet;
- CWnd *pwndWidthEditCtrl = pSheet->m_PgPrimitive.GetDlgItem( IDC_WIDTH);
- if( pwndWidthEditCtrl != NULL)
- {
- pSheet->SetActivePage( &pSheet->m_PgPrimitive);
- pwndWidthEditCtrl->SetFocus();
- }
- }
- FLOAT tmNow = _pTimer->GetHighPrecisionTimer().GetSeconds();
- // if we caught key or button down message and not status line info pause requested
- if( (theApp.m_tmStartStatusLineInfo<tmNow) &&
- ( (pMsg->message==WM_SYSKEYDOWN) ||
- (pMsg->message==WM_KEYDOWN) ||
- (pMsg->message==WM_KEYUP) ||
- (pMsg->message==WM_LBUTTONDOWN) ||
- (pMsg->message==WM_RBUTTONDOWN) ||
- (pMsg->message==WM_LBUTTONUP) ||
- (pMsg->message==WM_RBUTTONUP) ||
- (pMsg->message==WM_MOUSEMOVE) ||
- (pMsg->message==WM_CHANGE_EDITING_MODE) ||
- (bShift || bAlt || bCtrl || bSpace || bLMB || bRMB)) )
- {
- // space without mouse buttons but ctrl pressed
- if( bSpace && !bLMB && !bRMB && bCtrl)
- {
- STATUS_LINE_MESASGE( L"LMB zoomes in 2x, RMB zoomes out 2x");
- }
- // space without mouse buttons
- else if( bSpace && !bLMB && !bRMB && !bShift)
- {
- STATUS_LINE_MESASGE( L"Rotate or move viewer. Try: LMB,RMB,LMB+RMB,Space+Ctrl");
- }
- // space with left mouse button
- else if( bSpace && bLMB && !bRMB)
- {
- STATUS_LINE_MESASGE( L"Move viewer in view plane");
- }
- // space with right mouse button
- else if( bSpace && !bLMB && bRMB)
- {
- STATUS_LINE_MESASGE( L"Move viewer in floor plane");
- }
- // space with both mouse buttons
- else if( bSpace && bLMB && bRMB)
- {
- STATUS_LINE_MESASGE( L"Rotate viewer");
- }
- // Alt pressed
- else if( bAlt && !bCtrl && !bShift)
- {
- STATUS_LINE_MESASGE( L"You can drag any view and drop it into browser");
- }
- // for measure mode
- else if( theApp.m_bMeasureModeOn)
- {
- STATUS_LINE_MESASGE( L"Use LMB to measure distances");
- }
- // for cut mode
- else if( theApp.m_bCutModeOn)
- {
- STATUS_LINE_MESASGE( L"Use LMB to move cut/mirror line, enter to apply");
- }
- // for CSG mode
- else if( bCSGOn)
- {
- // for primitive mode
- if( bPrimitive)
- {
- // primitive mode, only <Ctrl> pressed
- if( bCtrl && !bLMB && !bRMB && !bShift)
- {
- STATUS_LINE_MESASGE( L"Use LMBx2 to teleport primitive. Try: LMB,RMB,LMB+RMB,Shift");
- }
- //-------- <Ctrl+Shift> commands for primitive
- // primitive mode, <Ctrl+Shift> pressed
- else if( bCtrl && !bLMB && !bRMB && bShift)
- {
- STATUS_LINE_MESASGE( L"Size and shear primitive. Try: LMB,RMB");
- }
- // primitive mode, <Ctrl+Shift+LMB> pressed
- else if( bCtrl && bLMB && !bRMB && bShift)
- {
- STATUS_LINE_MESASGE( L"Resize primitive");
- }
- // primitive mode, <Ctrl+Shift+RMB> pressed
- else if( bCtrl && !bLMB && bRMB && bShift)
- {
- STATUS_LINE_MESASGE( L"Shear primitive");
- }
- // primitive mode, <Ctrl+LMB> pressed
- else if( bCtrl && bLMB && !bRMB && !bShift)
- {
- STATUS_LINE_MESASGE( L"Move primitive in view plane");
- }
- // primitive mode, <Ctrl+RMB> pressed
- else if( bCtrl && !bLMB && bRMB && !bShift)
- {
- STATUS_LINE_MESASGE( L"Move primitive in floor plane");
- }
- // primitive mode, <Ctrl+LMB+RMB> pressed
- else if( bCtrl && bLMB && bRMB && !bShift)
- {
- STATUS_LINE_MESASGE( L"Rotate primitive in view plane");
- }
- // <Shift> pressed
- else if( !bCtrl && !bLMB && !bRMB && bShift)
- {
- STATUS_LINE_MESASGE( L"LMB inserts vertex, RMB deletes vertex. Try: Ctrl");
- }
- // primitive mode, nothing pressed
- else
- {
- STATUS_LINE_MESASGE( L"Primitive mode. Try: Alt,Ctrl,Shift");
- }
- }
- // for template mode
- else
- {
- //-------- <Ctrl> commands for template (moving and rotating)
- // template mode, only <Ctrl> pressed
- if( bCtrl && !bLMB && !bRMB && !bShift)
- {
- STATUS_LINE_MESASGE( L"Use LMB dbl. click to teleport template. Try: LMB,RMB,LMB+RMB");
- }
- // template mode, <Ctrl+LMB> pressed
- else if( bCtrl && bLMB && !bRMB && !bShift)
- {
- STATUS_LINE_MESASGE( L"Move template in view plane");
- }
- // template mode, <Ctrl+RMB> pressed
- else if( bCtrl && !bLMB && bRMB && !bShift)
- {
- STATUS_LINE_MESASGE( L"Move template in floor plane");
- }
- // template mode, <Ctrl+LMB+RMB> pressed
- else if( bCtrl && bLMB && bRMB && !bShift)
- {
- STATUS_LINE_MESASGE( L"Rotate template");
- }
- // template mode, nothing pressed
- else
- {
- STATUS_LINE_MESASGE( L"Template primitive mode. Try: Ctrl");
- }
- }
- }
- // for entity mode
- else if( bEntityMode)
- {
- // get property ID
- CPropertyID *ppidProperty = pMainFrame->m_PropertyComboBar.GetSelectedProperty();
- // if we have at least one entity selected and edititng property of edit range type
- // and Ctrl+Shift pressed
- BOOL bEditingProperties = ( (pDoc->m_selEntitySelection.Count() != 0) &&
- ( (ppidProperty != NULL) &&
- ( (ppidProperty->pid_eptType == CEntityProperty::EPT_ANGLE3D) ||
- (ppidProperty->pid_eptType == CEntityProperty::EPT_RANGE))) );
- // entity mode, <Ctrl+Shift> pressed
- if( bEditingProperties && bCtrl && bShift )
- {
- STATUS_LINE_MESASGE( L"Use LMB to change range or direction");
- }
- // <Alt + Ctrl> pressed
- else if( bAlt && bCtrl)
- {
- STATUS_LINE_MESASGE( L"Use LMB to set entity ptr. (Entity ptr property must be selected)");
- }
- else if( bCtrl && bShift)
- {
- STATUS_LINE_MESASGE( L"Use RMB to set mip switch distance (in auto mode)");
- }
- else if( bSpace && bShift)
- {
- STATUS_LINE_MESASGE( L"Use RMB to change virtual mip distance");
- }
- // entity mode, <Shift> pressed
- else if( !bCtrl && bShift)
- {
- STATUS_LINE_MESASGE( L"Use LMB to toggle selection of one entity . Try: Ctrl,Space");
- }
- // entity mode, <Ctrl> pressed
- else if( bCtrl && !bLMB && !bRMB && !bShift)
- {
- if( bEditingProperties)
- {
- STATUS_LINE_MESASGE( L"Use LMBx2 click to teleport entity. Try: LMB,RMB,LMB+RMB,Shift");
- }
- else
- {
- STATUS_LINE_MESASGE( L"Use LMBx2 click to teleport entity. Try: Alt,LMB,RMB,LMB+RMB");
- }
- }
- // entity mode, <Ctrl+LMB> pressed
- else if( bCtrl && bLMB && !bRMB && !bShift)
- {
- STATUS_LINE_MESASGE( L"Move entities in view plane");
- }
- // entity mode, <Ctrl+RMB> pressed
- else if( bCtrl && !bLMB && bRMB && !bShift)
- {
- STATUS_LINE_MESASGE( L"Move entities in floor plane");
- }
- // entity mode, <Ctrl+LMB+RMB> pressed
- else if( bCtrl && bLMB && bRMB && !bShift)
- {
- STATUS_LINE_MESASGE( L"Rotate entities");
- }
- // entity mode, nothing pressed
- else
- {
- if( bEditingProperties)
- {
- STATUS_LINE_MESASGE( L"Use LMB to select entities. Try: Ctrl,Shift");
- }
- else
- {
- STATUS_LINE_MESASGE( L"Use LMB to select entities. Try: Ctrl,Shift,Ctrl+Alt");
- }
- }
- }
- // for polygon mode
- else if( bPolygonMode)
- {
- // polygon mode, <Ctrl> pressed
- if( bCtrl && !bLMB && !bRMB && !bShift && !bAlt)
- {
- STATUS_LINE_MESASGE( L"LMBx2 centers texture. RMBx2 selects similar by texture. Try: LMB,LMB+RMB");
- }
- // polygon mode, <Shift> pressed
- else if( !bCtrl && !bLMB && !bRMB && bShift && !bAlt)
- {
- STATUS_LINE_MESASGE( L"Toggle polygon using LMB or RMB. Add simillar with LMB dbl. click");
- }
- // polygon mode, <Ctrl+LMB> pressed
- else if( bCtrl && bLMB && !bRMB && !bShift && !bAlt)
- {
- STATUS_LINE_MESASGE( L"Scroll polygon's mapping texture");
- }
- // polygon mode, <Ctrl+LMB+RMB> pressed
- else if( bCtrl && bLMB && bRMB && !bShift && !bAlt)
- {
- STATUS_LINE_MESASGE( L"Rotate polygon's mapping texture");
- }
- else if( bCtrl && bAlt)
- {
- STATUS_LINE_MESASGE( L"Zoom in texture 2x using LMB, zoom out texture 2x using RMB");
- }
- // polygon mode, <Ctrl+Shift> pressed
- else if( bCtrl && bShift)
- {
- STATUS_LINE_MESASGE( L"Select polygons similar by texture in sector with LMBx2, similar by color with RMBx2");
- }
- // polygon mode, nothing pressed
- else if( !bCtrl && !bLMB && !bRMB && !bShift && !bAlt)
- {
- STATUS_LINE_MESASGE( L"Select polygons using LMB or RMB, by color using LMBx2. Try: Alt,Ctrl,Shift,Ctrl+Alt");
- }
- }
- // for sector mode
- else
- {
- // sector mode, <Shift> pressed
- if( !bCtrl && !bLMB && !bRMB && bShift)
- {
- STATUS_LINE_MESASGE( L"Add to selection or deselect sector using LMB or LMB dbl. click");
- }
- // sector mode, nothing pressed
- else
- {
- STATUS_LINE_MESASGE( L"Select or deselect sector using LMB or LMB dbl. click. Try: Alt,Shift");
- }
- }
- // for these events
- if( (pMsg->message==WM_KEYDOWN) ||
- (pMsg->message==WM_KEYUP) ||
- (pMsg->message==WM_LBUTTONDOWN) ||
- (pMsg->message==WM_RBUTTONDOWN) ||
- (pMsg->message==WM_LBUTTONUP) ||
- (pMsg->message==WM_RBUTTONUP) )
- {
- // set text describing data that is edited
- SetEditingDataPaneInfo( TRUE);
- }
- }
- return CView::PreTranslateMessage(pMsg);
- }
- void CWorldEditorView::OnKeyO()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode()==TERRAIN_MODE)
- {
- theApp.m_iTerrainBrushMode=TBM_SMOOTH;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- pDoc->SetStatusLineModeInfoMessage();
- }
- else
- {
- OnCloneCSG();
- }
- }
- void CWorldEditorView::OnUpdateKeyO(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode()==TERRAIN_MODE)
- {
- pCmdUI->Enable( TRUE);
- }
- else
- {
- OnUpdateCloneCsg(pCmdUI);
- }
- }
- void CWorldEditorView::OnCloneCSG()
- {
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CWorldEditorDoc* pDoc = GetDocument();
- CDlgProgress dlgProgressDialog( pMainFrame);
- // disable CSG report
- theApp.m_bCSGReportEnabled = FALSE;
- // and clear its values
- _pfWorldEditingProfile.Reset();
- // remember automatic info flag
- BOOL bAutomaticInfo = theApp.m_Preferences.ap_AutomaticInfo;
- // get shift pressed flag
- BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0;
- // we will have 1 clone (by default)
- INDEX ctClones = 1;
- // if shift is pressed, we want "array of clones" (numeric option)
- if( bAlt)
- {
- CDlgAutoDeltaCSG dlgAutoDeltaCSG;
- // if dialog wasn't succeseful
- if( dlgAutoDeltaCSG.DoModal() != IDOK)
- {
- return;
- }
- // temporary disable automatic info
- theApp.m_Preferences.ap_AutomaticInfo = FALSE;
- // get wanted count of clones
- ctClones = dlgAutoDeltaCSG.m_ctNumberOfClones;
- // write it to .ini file for the next time
- theApp.WriteProfileInt(L"World editor", L"Number of CSG clones", ctClones);
- }
- // set wait cursor
- CWaitCursor StartWaitCursor;
- // if there is more than 1 clone in progress
- if( ctClones > 1)
- {
- // create progress dialog
- dlgProgressDialog.Create( IDD_PROGRESS_DIALOG);
- dlgProgressDialog.SetWindowText(L"Repeat CSG");
- // show progress window
- dlgProgressDialog.ShowWindow( SW_SHOW);
- // center window
- dlgProgressDialog.CenterWindow();
- // set progress range
- dlgProgressDialog.m_ctrlProgres.SetRange( 0, (short) ctClones);
- }
- // if primitive CSG was last used CSG operation
- if( pDoc->m_bLastUsedPrimitiveMode)
- {
- // for all clones
- for( INDEX iClone=0; iClone<ctClones; iClone++)
- {
- // if there is more than 1 clone in progress
- if( ctClones > 1)
- {
- char achrProgressMessage[ 256];
- sprintf( achrProgressMessage, "Cloning CSG operation ... (processing %d/%d)",
- iClone+1, ctClones);
- // set message and progress position
- dlgProgressDialog.SetProgressMessageAndPosition( achrProgressMessage, iClone+1);
- }
- // create new placement from delta placement
- CPlacement3D plNewPlacement = pDoc->m_plDeltaPlacement;
- // convert it into absolute space of last used placement (delta applyed)
- plNewPlacement.RelativeToAbsolute( pDoc->m_plLastPlacement);
- // copy last used values for primitive as initial values for this new primitive
- theApp.m_vfpPreLast = theApp.m_vfpLast;
- theApp.m_vfpCurrent = theApp.m_vfpLast;
- // apply width, sheer, stretch, ... delta
- theApp.m_vfpCurrent += theApp.m_vfpDelta;
- // after substraction we colud get some invalid values (like negative width!!!)
- // so we have to correct them
- theApp.m_vfpCurrent.CorrectInvalidValues();
- // we will snap primitive placement
- pDoc->SnapToGrid( plNewPlacement, SNAP_FLOAT_25);
- // create primitive but don't reset orientation angles
- pDoc->StartPrimitiveCSG( plNewPlacement, FALSE);
- // for last clone enable undo remembering
- if( iClone > 0)
- {
- // disable undo remembering
- theApp.m_bRememberUndo = FALSE;
- }
- // if shift was helded while starting clone CSG
- if( bAlt)
- {
- // apply same CSG operation as was used last time
- pDoc->ApplyCSG( pDoc->m_csgtLastUsedCSGOperation);
- }
- }
- // if there is more than 1 clone in progress
- if( ctClones > 1)
- {
- // destroy progress dialog
- dlgProgressDialog.DestroyWindow();
- }
- }
- // for templates
- else
- {
- // for all clones
- for( INDEX iClone=0; iClone<ctClones; iClone++)
- {
- // if there is more than 1 clone in progress
- if( ctClones > 1)
- {
- char achrProgressMessage[ 256];
- sprintf( achrProgressMessage, "Repeating last operation... (processing %d/%d)",
- iClone+1, ctClones);
- // set message and progress position
- dlgProgressDialog.SetProgressMessageAndPosition( achrProgressMessage, iClone+1);
- }
- // create new placement from delta placement
- CPlacement3D plNewPlacement = pDoc->m_plDeltaPlacement;
- // convert it into absolute space of last used placement (delta applyed)
- plNewPlacement.RelativeToAbsolute( pDoc->m_plLastPlacement);
- // we will snap template placement
- pDoc->SnapToGrid( plNewPlacement, SNAP_FLOAT_25);
- // for last clone enable undo remembering
- if( iClone > 0)
- {
- // disable undo remembering
- theApp.m_bRememberUndo = FALSE;
- }
- // start template CSG but don't reset orientation angles
- pDoc->StartTemplateCSG( plNewPlacement, pDoc->m_fnLastDroppedTemplate, FALSE);
- // if shift was helded while starting clone CSG, we want to apply CSG
- // if template was automaticly joined after droping, we are not in CSG_MODE any more
- if( bAlt && (pDoc->GetEditingMode() == CSG_MODE) )
- {
- // apply same CSG operation as was used last time
- pDoc->ApplyCSG( pDoc->m_csgtLastUsedCSGOperation);
- }
- }
- // if there is more than 1 clone in progress
- if( ctClones > 1)
- {
- // destroy progress dialog
- dlgProgressDialog.DestroyWindow();
- }
- }
- // enable undo remembering
- theApp.m_bRememberUndo = TRUE;
- // restore automatic info flag
- theApp.m_Preferences.ap_AutomaticInfo = bAutomaticInfo;
- // enable CSG report
- theApp.m_bCSGReportEnabled = TRUE;
- // and report calculated CSG report values
- _pfWorldEditingProfile.Report( theApp.m_strCSGAndShadowStatistics);
- theApp.m_strCSGAndShadowStatistics.SaveVar(CTString("Temp\\Profile_CSGWizard.txt"));
- }
- void CWorldEditorView::OnUpdateCloneCsg(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // there can't be any kind of CSG going on if we want to clone last CSG operation
- BOOL bCSGOn = pDoc->m_pwoSecondLayer != NULL;
- // there must be at least one CSG operation done
- BOOL bCanBeCloned = ( (pDoc->m_csgtLastUsedCSGOperation == CSG_ADD) ||
- (pDoc->m_csgtLastUsedCSGOperation == CSG_ADD_REVERSE) ||
- (pDoc->m_csgtLastUsedCSGOperation == CSG_REMOVE) ||
- (pDoc->m_csgtLastUsedCSGOperation == CSG_REMOVE_REVERSE) ||
- (pDoc->m_csgtLastUsedCSGOperation == CSG_SPLIT_SECTORS) ||
- (pDoc->m_csgtLastUsedCSGOperation == CSG_SPLIT_POLYGONS) ||
- (pDoc->m_csgtLastUsedCSGOperation == CSG_JOIN_LAYERS) );
- // last and current primitive CSG operation must have same primitive types
- pCmdUI->Enable( bCanBeCloned && !bCSGOn &&
- (pDoc->m_csgtPreLastUsedCSGOperation==pDoc->m_csgtLastUsedCSGOperation) &&
- (pDoc->m_bPreLastUsedPrimitiveMode==pDoc->m_bLastUsedPrimitiveMode) &&
- (!pDoc->m_bLastUsedPrimitiveMode ||
- (pDoc->m_bLastUsedPrimitiveMode &&
- (theApp.m_vfpPreLast.vfp_ptPrimitiveType == theApp.m_vfpLast.vfp_ptPrimitiveType))) );
- }
- void CWorldEditorView::OnPopupConus()
- {
- // start conus primitive
- theApp.m_vfpCurrent = theApp.m_vfpConus;
- CreatePrimitiveCalledFromPopup();
- }
- void CWorldEditorView::OnPopupTorus()
- {
- // start conus primitive
- theApp.m_vfpCurrent = theApp.m_vfpTorus;
- CreatePrimitiveCalledFromPopup();
- }
- void CWorldEditorView::OnPopupSphere()
- {
- // start conus primitive
- theApp.m_vfpCurrent = theApp.m_vfpSphere;
- CreatePrimitiveCalledFromPopup();
- }
- void CWorldEditorView::OnPopupStairs()
- {
- // start conus primitive
- theApp.m_vfpCurrent = theApp.m_vfpStaircases;
- CreatePrimitiveCalledFromPopup();
- }
- void CWorldEditorView::OnPopupTerrain()
- {
- // start conus primitive
- theApp.m_vfpCurrent = theApp.m_vfpTerrain;
- CreatePrimitiveCalledFromPopup();
- }
- void CWorldEditorView::CreatePrimitiveCalledFromPopup()
- {
- if( !m_bEntityHitedOnContext)
- {
- OnConusPrimitive();
- }
- CWorldEditorDoc* pDoc = GetDocument();
- // create placement for primitive's position
- CPlacement3D plDrop = m_plEntityHitOnContext;
- // snap placement
- pDoc->SnapToGrid( plDrop, m_fGridInMeters/GRID_DISCRETE_VALUES);
- // create primitive for the first time, don't reset angles
- pDoc->StartPrimitiveCSG( plDrop, FALSE);
- }
- void CWorldEditorView::OnMeasureOn()
- {
- theApp.m_bMeasureModeOn = !theApp.m_bMeasureModeOn;
- theApp.m_bCutModeOn = FALSE;
- }
- void CWorldEditorView::OnUpdateMeasureOn(CCmdUI* pCmdUI)
- {
- pCmdUI->SetCheck( theApp.m_bMeasureModeOn);
- }
- void CWorldEditorView::OnResetViewer()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- // set new target
- GetChildFrame()->m_mvViewer.SetTargetPlacement( FLOAT3D(0.0f, 0.0f, 0.0f));
- _fFlyModeSpeedMultiplier=theApp.m_Preferences.ap_fDefaultFlyModeSpeed;
- pMainFrame->ResetInfoWindowPos();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnCenterBcgViewer()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // for all of the world's entities
- CEntity *penBackgroundViewer = pDoc->m_woWorld.GetBackgroundViewer();
- if( penBackgroundViewer != NULL)
- {
- // set new target
- GetChildFrame()->m_mvViewer.SetTargetPlacement(
- penBackgroundViewer->GetPlacement().pl_PositionVector);
- pDoc->UpdateAllViews( NULL);
- }
- }
- void CWorldEditorView::OnCopyTexture()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- OnPickLayer();
- return;
- }
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- if( pDoc->GetEditingMode() == SECTOR_MODE)
- {
- CBrushSector *pbscSector = crRayHit.cr_pbpoBrushPolygon->bpo_pbscSector;
- CopySectorAmbient( pbscSector);
- }
- else
- {
- // get polygon's texture
- CTextureData *pTD = (CTextureData *)crRayHit.cr_pbpoBrushPolygon->bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.GetData();
- if( pTD != NULL)
- {
- // get name from serial object
- CTFileName fnTextureName = pTD->GetName();
- // set it as new active texture
- theApp.SetNewActiveTexture( _fnmApplicationPath + fnTextureName);
- }
- }
- }
- }
- void CWorldEditorView::OnPasteTexture()
- {
- CWorldEditorDoc* pDoc = GetDocument();
-
- if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- theApp.m_iTerrainBrushMode=TBM_RND_NOISE;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- pDoc->SetStatusLineModeInfoMessage();
- return;
- }
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL))
- {
- if( pDoc->GetEditingMode() == SECTOR_MODE)
- {
- CBrushSector *pbscSector = crRayHit.cr_pbpoBrushPolygon->bpo_pbscSector;
- PasteSectorAmbient( pbscSector);
- }
- else if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- PasteTexture( crRayHit.cr_pbpoBrushPolygon);
- }
- }
- }
- void CWorldEditorView::OnSelectByTextureAdjacent()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- // select similar by texture to hitted polygon
- crRayHit.cr_pbpoBrushPolygon->SelectSimilarByTexture( pDoc->m_selPolygonSelection, pDoc->m_iTexture);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- }
- void CWorldEditorView::OnSelectByTextureInSector()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- // select similar by texture to hitted polygon
- crRayHit.cr_pbpoBrushPolygon->SelectByTextureInSector( pDoc->m_selPolygonSelection, pDoc->m_iTexture);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- }
- void CWorldEditorView::OnSelectByColorInSector()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- // select similar by color to hitted polygon
- crRayHit.cr_pbpoBrushPolygon->SelectByColorInSector( pDoc->m_selPolygonSelection);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- }
- void CWorldEditorView::OnFunction()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->m_iMode == ENTITY_MODE)
- {
- pDoc->m_cenEntitiesSelectedByVolume.Clear();
- // for each of the entities selected by volume
- FOREACHINDYNAMICCONTAINER( pDoc->m_selEntitySelection, CEntity, iten)
- {
- // add entity into volume selection
- if( !pDoc->m_cenEntitiesSelectedByVolume.IsMember(iten))
- {
- pDoc->m_cenEntitiesSelectedByVolume.Add( iten);
- }
- }
- // go out of browse by volume mode
- if( pDoc->m_bBrowseEntitiesMode) pDoc->OnBrowseEntitiesMode();
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- // obtain main frame ptr
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- // and refresh property combo manualy calling on idle
- pMainFrame->m_PropertyComboBar.m_PropertyComboBox.OnIdle( 0);
- // update all views
- pDoc->UpdateAllViews( NULL);
- }
- else if( pDoc->m_iMode == POLYGON_MODE)
- {
- pDoc->OnFilterSelection();
- }
- else if( pDoc->m_iMode == VERTEX_MODE)
- {
- SnapSelectedVerticesToPlane();
- }
- else if( pDoc->m_iMode == TERRAIN_MODE)
- {
- theApp.m_iTerrainBrushMode=TBM_FILTER;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- pDoc->SetStatusLineModeInfoMessage();
- }
- }
- void CWorldEditorView::SnapSelectedVerticesToPlane(void)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->RememberUndo();
- pDoc->m_woWorld.TriangularizeForVertices( pDoc->m_selVertexSelection);
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- CBrushPolygon *pbpo = crRayHit.cr_pbpoBrushPolygon;
- CEntity *pen = pbpo->bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush->br_penEntity;
- CSimpleProjection3D_DOUBLE pr;
- pr.ObjectPlacementL() = pen->GetPlacement();
- pr.ViewerPlacementL() = _plOrigin;
- pr.Prepare();
- DOUBLEplane3D plAbsPrecise;
- pr.Project(pbpo->bpo_pbplPlane->bpl_pldPreciseRelative, plAbsPrecise);
- // snap vertices to plane
- {FOREACHINDYNAMICCONTAINER( pDoc->m_selVertexSelection, CBrushVertex, itbvx)
- {
- CEntity *pen = itbvx->bvx_pbscSector->bsc_pbmBrushMip->bm_pbrBrush->br_penEntity;
- CSimpleProjection3D_DOUBLE pr;
- pr.ObjectPlacementL() = pen->GetPlacement();
- pr.ViewerPlacementL() = _plOrigin;
- pr.Prepare();
- DOUBLE3D vAbsPrecise;
- pr.ProjectCoordinate(itbvx->bvx_vdPreciseRelative, vAbsPrecise);
- DOUBLE3D vOnPlaneAbsPrecise=plAbsPrecise.ProjectPoint(vAbsPrecise);
- itbvx->SetAbsolutePosition(vOnPlaneAbsPrecise);
- }}
- }
- pDoc->m_woWorld.UpdateSectorsDuringVertexChange( pDoc->m_selVertexSelection);
- pDoc->m_woWorld.UpdateSectorsAfterVertexChange( pDoc->m_selVertexSelection);
- pDoc->UpdateAllViews( NULL);
- pDoc->SetModifiedFlag();
- }
- void CWorldEditorView::OnCrossroadForCtrlF()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if(pDoc->GetEditingMode() == POLYGON_MODE)
- {
- OnFindTexture();
- }
- else if(pDoc->GetEditingMode() == VERTEX_MODE)
- {
- CDlgFilterVertexSelection dlg;
- dlg.DoModal();
- }
- else if(pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- theApp.m_iFilter=(theApp.m_iFilter+1)%FLT_COUNT;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- }
- void CWorldEditorView::OnFindTexture()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- // get polygon's texture
- CTextureData *pTD = (CTextureData *)crRayHit.cr_pbpoBrushPolygon->bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.GetData();
- if( pTD != NULL)
- {
- // get name from serial object
- CTFileName fnTextureName = pTD->GetName();
- // set it as new active texture
- theApp.FindItemInBrowser( fnTextureName);
- }
- }
- }
- void CWorldEditorView::OnCenterEntity()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if(pDoc->GetEditingMode() == CSG_MODE)
- {
- GetChildFrame()->m_mvViewer.SetTargetPlacement( pDoc->m_plSecondLayer.pl_PositionVector);
- }
- if(pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- CTerrain *ptrTerrain=GetTerrain();
- if(ptrTerrain!=NULL)
- {
- FLOATaabbox3D boxBoundingBox;
- ptrTerrain->GetAllTerrainBBox(boxBoundingBox);
- FLOAT3D vTerrainCenter=boxBoundingBox.Center();
- GetChildFrame()->m_mvViewer.SetTargetPlacement( vTerrainCenter);
- }
- }
- else
- {
- if( pDoc->m_selEntitySelection.Count() == 0) return;
- // reset position
- FLOAT3D vEntityPlacementAverage = FLOAT3D( 0.0f, 0.0f, 0.0f);
- //for all selected entities
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- // get placement of current entity
- CPlacement3D plEntityPlacement = iten->GetPlacement();
- // add movement offset to placement
- vEntityPlacementAverage += plEntityPlacement.pl_PositionVector;
- }
- // calculate average position
- vEntityPlacementAverage /= (FLOAT) pDoc->m_selEntitySelection.Count();
- // set centered entity position as new viewer's target
- GetChildFrame()->m_mvViewer.SetTargetPlacement( vEntityPlacementAverage);
- }
- // update all views
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnUpdateCenterEntity(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // if we are in entity mode and we have at least 1 entity selected
- pCmdUI->Enable( (pDoc->GetEditingMode() == CSG_MODE) ||
- ((pDoc->GetEditingMode() == TERRAIN_MODE) &&
- (GetTerrain()!=NULL)) ||
- ((pDoc->GetEditingMode() == ENTITY_MODE) &&
- (pDoc->m_selEntitySelection.Count() != 0)) );
- }
- void CWorldEditorView::OnDropMarker()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CTFileName fnDropClass;
- CTString strTargetProperty;
- if(pDoc->m_selEntitySelection.Count() == 1)
- {
- CEntity &enOnly = pDoc->m_selEntitySelection.GetFirst();
- if(enOnly.DropsMarker( fnDropClass, strTargetProperty))
- {
- OnDropMarker(enOnly.GetPlacement());
- }
- }
- }
- void CWorldEditorView::OnDropMarker(CPlacement3D plMarker)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CTFileName fnDropClass, fnDummy;
- CTString strTargetProperty;
- CEntityProperty *penpProperty;
- CEntity &enOnly = pDoc->m_selEntitySelection.GetFirst();
- // obtain drop class and target property name
- if( !enOnly.DropsMarker( fnDropClass, strTargetProperty)) return;
- penpProperty = enOnly.PropertyForName( strTargetProperty);
- CEntity *penFirstInChain;
- if (enOnly.IsMarker())
- {
- penFirstInChain = &enOnly;
- }
- else
- {
- penFirstInChain = ENTITYPROPERTY( &enOnly, penpProperty->ep_slOffset, CEntityPointer);
- }
- CEntity *penSecondInChain = NULL;
- // if first in chain exists, try getting his target
- if( penFirstInChain != NULL)
- {
- if( !penFirstInChain->DropsMarker( fnDropClass, strTargetProperty)) return;
- penpProperty = penFirstInChain->PropertyForName( strTargetProperty);
- penSecondInChain = ENTITYPROPERTY( penFirstInChain, penpProperty->ep_slOffset, CEntityPointer);
- }
- // spawn entity
- CEntity *penSpawned;
- if( !enOnly.DropsMarker( fnDropClass, strTargetProperty)) return;
- penpProperty = enOnly.PropertyForName( strTargetProperty);
- try
- {
- // spawn one entity of class selected in browser
- penSpawned = pDoc->m_woWorld.CreateEntity_t( plMarker, fnDropClass);
- penSpawned->Initialize();
- }
- catch( char *strError)
- {
- AfxMessageBox( CString(strError));
- return;
- }
- // if first in chain entity exists, set spawned entity to be his target
- if( penFirstInChain != NULL)
- {
- if( !penFirstInChain->DropsMarker( fnDropClass, strTargetProperty)) return;
- penpProperty = penFirstInChain->PropertyForName( strTargetProperty);
- ENTITYPROPERTY( penFirstInChain, penpProperty->ep_slOffset, CEntityPointer) = penSpawned;
- }
- if( !penSpawned->DropsMarker( fnDropClass, strTargetProperty)) return;
- penpProperty = penSpawned->PropertyForName( strTargetProperty);
- if( penSecondInChain != NULL)
- {
- ENTITYPROPERTY( penSpawned, penpProperty->ep_slOffset, CEntityPointer) = penSecondInChain;
- }
- else
- {
- ENTITYPROPERTY( penSpawned, penpProperty->ep_slOffset, CEntityPointer) = penFirstInChain;
- }
- // set our only selected entity to point to spawned entity
- if( !enOnly.DropsMarker( fnDropClass, strTargetProperty)) return;
- penpProperty = enOnly.PropertyForName( strTargetProperty);
- ENTITYPROPERTY( &enOnly, penpProperty->ep_slOffset, CEntityPointer) = penSpawned;
- pDoc->SetModifiedFlag();
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnUpdateDropMarker(CCmdUI* pCmdUI)
- {
- CTFileName fnDropClass;
- CTString strTargetProperty;
- CWorldEditorDoc* pDoc = GetDocument();
- // if we are in entity mode, we have 1 entity selected and entity can drop marker
- if( (pDoc->GetEditingMode() == ENTITY_MODE) &&
- (pDoc->m_selEntitySelection.Count() == 1) &&
- (pDoc->m_selEntitySelection.GetFirst().DropsMarker( fnDropClass, strTargetProperty)) )
- {
- pCmdUI->Enable( TRUE);
- }
- else
- {
- pCmdUI->Enable( FALSE);
- }
- }
- void CWorldEditorView::OnTestConnections()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CEntityProperty *penpProperty;
- CEntity &enOnly = pDoc->m_selEntitySelection.GetFirst();
- CTString strTargetProperty;
- // get target pointer for curently selected entity
- enOnly.MovesByTargetedRoute( strTargetProperty);
- penpProperty = enOnly.PropertyForName( strTargetProperty);
- CEntity *penCurrent = ENTITYPROPERTY( &enOnly, penpProperty->ep_slOffset, CEntityPointer);
- // if no target
- if( penCurrent == NULL) {
- // do nothing
- return;
- }
- // get target pointer for its target (get next)
- penCurrent->MovesByTargetedRoute( strTargetProperty);
- penpProperty = penCurrent->PropertyForName( strTargetProperty);
- CEntity *penNext = ENTITYPROPERTY( penCurrent, penpProperty->ep_slOffset, CEntityPointer);
- // if no target
- if( penNext == NULL) {
- // do nothing
- return;
- }
- // teleport to next
- enOnly.SetPlacement( penNext->GetPlacement());
- if (enOnly.en_RenderType == CEntity::RT_BRUSH)
- {
- DiscardShadows( &enOnly);
- }
- // set target pointer to next next
- enOnly.MovesByTargetedRoute( strTargetProperty);
- penpProperty = enOnly.PropertyForName( strTargetProperty);
- ENTITYPROPERTY( &enOnly, penpProperty->ep_slOffset, CEntityPointer) = penNext;
- // mark that document and selections are changed
- pDoc->SetModifiedFlag();
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnTestConnectionsBack()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CEntityProperty *penpProperty;
- CEntity &enOnly = pDoc->m_selEntitySelection.GetFirst();
- CTString strTargetProperty;
- // get target pointer for curently selected entity
- enOnly.MovesByTargetedRoute( strTargetProperty);
- penpProperty = enOnly.PropertyForName( strTargetProperty);
- CEntity *penCurrent = ENTITYPROPERTY( &enOnly, penpProperty->ep_slOffset, CEntityPointer);
- // if no target
- if( penCurrent == NULL) {
- // do nothing
- return;
- }
- // start from current
- CEntity *penNext=penCurrent;
- // repeat
- FOREVER {
- // get next target pointer
- penNext->MovesByTargetedRoute( strTargetProperty);
- penpProperty = penCurrent->PropertyForName( strTargetProperty);
- CEntity *penNextNext = ENTITYPROPERTY( penNext, penpProperty->ep_slOffset, CEntityPointer);
- // if no target
- if( penNextNext == NULL) {
- // do nothing
- return;
- }
- // if the next one is same as where the entity started
- if( penNextNext==penCurrent) {
- // stop searching
- break;
- }
- // go to that target
- penNext = penNextNext;
- }
-
- // teleport to next
- enOnly.SetPlacement( penNext->GetPlacement());
- if (enOnly.en_RenderType == CEntity::RT_BRUSH)
- {
- DiscardShadows( &enOnly);
- }
- // set target pointer to next next
- enOnly.MovesByTargetedRoute( strTargetProperty);
- penpProperty = enOnly.PropertyForName( strTargetProperty);
- ENTITYPROPERTY( &enOnly, penpProperty->ep_slOffset, CEntityPointer) = penNext;
- // mark that document and selections are changed
- pDoc->SetModifiedFlag();
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnUpdateTestConnections(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- BOOL bModeAndCount = (pDoc->GetEditingMode() == ENTITY_MODE) &&
- ( pDoc->m_selEntitySelection.Count() == 1);
- BOOL bEnableCommand = FALSE;
- // if we have only one entity selected and we are in entity mode
- if( bModeAndCount)
- {
- CEntity &enOnly = pDoc->m_selEntitySelection.GetFirst();
- CTString strTargetProperty;
- // if we can perform test path function on this entity
- if( enOnly.MovesByTargetedRoute( strTargetProperty))
- bEnableCommand = TRUE;
- }
- pCmdUI->Enable( bEnableCommand);
- }
- void CWorldEditorView::OnUpdateTestConnectionsBack(CCmdUI* pCmdUI)
- {
- // update same as it is forward
- OnUpdateTestConnections( pCmdUI);
- }
- #define PAPER (4.0f/5.0f)
- void CWorldEditorView::OnAlignVolume()
- {
- // get draw port
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- // if it is not valid
- if( pdpValidDrawPort == NULL)
- {
- return;
- }
- CWorldEditorDoc* pDoc = GetDocument();
- // create a slave viewer
- CSlaveViewer svViewer(GetChildFrame()->m_mvViewer, m_ptProjectionType, pDoc->m_plGrid,
- pdpValidDrawPort);
- // get zoom factor
- FLOAT fZoom = svViewer.GetZoomFactor();
- PIX pixWidth = pdpValidDrawPort->GetWidth();
- PIX pixHeight = pdpValidDrawPort->GetHeight();
- FLOAT fWidth = pixWidth/fZoom;
- FLOAT fHeight = pixHeight/fZoom;
- // get point in space that user is looking
- FLOAT3D vTargetPoint = GetChildFrame()->m_mvViewer.GetTargetPlacement().pl_PositionVector;
- pDoc->m_vCreateBoxVertice0 = FLOAT3D(
- vTargetPoint(1)-fWidth*PAPER/2,
- vTargetPoint(2)-fHeight*PAPER/2,
- vTargetPoint(3)-fHeight*PAPER/2);
- pDoc->m_vCreateBoxVertice1 = FLOAT3D(
- vTargetPoint(1)+fWidth*PAPER/2,
- vTargetPoint(2)+fHeight*PAPER/2,
- vTargetPoint(3)+fHeight*PAPER/2);
- pDoc->SelectEntitiesByVolumeBox();
- // try to select first entity in volume
- pDoc->SelectGivenEntity( 0);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnAlignPrimitive()
- {
- // get draw port
- CDrawPort *pdpValidDrawPort = GetDrawPort();
- // if it is not valid
- if( pdpValidDrawPort == NULL)
- {
- return;
- }
- CWorldEditorDoc* pDoc = GetDocument();
- // create a slave viewer
- CSlaveViewer svViewer(GetChildFrame()->m_mvViewer, m_ptProjectionType, pDoc->m_plGrid,
- pdpValidDrawPort);
- // get zoom factor
- FLOAT fZoom = svViewer.GetZoomFactor();
- PIX pixWidth = pdpValidDrawPort->GetWidth()*8/10;
- PIX pixHeight = pdpValidDrawPort->GetHeight()*8/10;
- FLOAT fWidth = pixWidth/fZoom;
- FLOAT fHeight = pixHeight/fZoom;
- // get point in space that user is looking
- FLOAT3D vTargetPoint = GetChildFrame()->m_mvViewer.GetTargetPlacement().pl_PositionVector;
- pDoc->m_plSecondLayer.pl_PositionVector = vTargetPoint;
- fWidth = FLOAT( pow( 2.0f, floor(Log2(fWidth))));
- fHeight = FLOAT( pow( 2.0f, floor(Log2(fHeight))));
- theApp.m_vfpCurrent.vfp_fXMin = -fWidth/2.0f;
- theApp.m_vfpCurrent.vfp_fXMax = fWidth/2.0f;
- theApp.m_vfpCurrent.vfp_fYMin = -fHeight/2.0f;
- theApp.m_vfpCurrent.vfp_fYMax = fHeight/2.0f;
- theApp.m_vfpCurrent.vfp_fZMin = -fHeight/2.0f;
- theApp.m_vfpCurrent.vfp_fZMax = fHeight/2.0f;
- pDoc->SnapToGrid( pDoc->m_plSecondLayer, m_fGridInMeters/GRID_DISCRETE_VALUES);
- if( pDoc->m_bAutoSnap)
- {
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fXMin, m_fGridInMeters/GRID_DISCRETE_VALUES);
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fXMax, m_fGridInMeters/GRID_DISCRETE_VALUES);
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fYMin, m_fGridInMeters/GRID_DISCRETE_VALUES);
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fYMax, m_fGridInMeters/GRID_DISCRETE_VALUES);
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fZMin, m_fGridInMeters/GRID_DISCRETE_VALUES);
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fZMax, m_fGridInMeters/GRID_DISCRETE_VALUES);
- }
- else
- {
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fXMin, SNAP_FLOAT_CM);
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fXMax, SNAP_FLOAT_CM);
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fYMin, SNAP_FLOAT_CM);
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fYMax, SNAP_FLOAT_CM);
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fZMin, SNAP_FLOAT_CM);
- pDoc->SnapFloat( theApp.m_vfpCurrent.vfp_fZMax, SNAP_FLOAT_CM);
- }
- pDoc->RefreshPrimitivePage();
- pDoc->CreatePrimitive();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnUpdateAlignVolume(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pCmdUI->Enable( pDoc->m_bBrowseEntitiesMode);
- }
- void CWorldEditorView::OnCurrentViewProperties()
- {
- // copy selected preferences from view rendering preferences to temporary buffer
- theApp.m_vpViewPrefs[ VIEW_PREFERENCES_CT] = m_vpViewPrefs;
- // call edit view preferences with temporary view preferences buffer (last one)
- CDlgRenderingPreferences dlg( VIEW_PREFERENCES_CT);
- // if dialog ended with cancel or esc, dont switch to changed preferences
- if( dlg.DoModal() != IDOK)
- {
- // don't set new preferences
- return;
- }
- // copy selected preferences to view's rendering preferences
- m_vpViewPrefs = theApp.m_vpViewPrefs[ VIEW_PREFERENCES_CT];
- // see the change
- Invalidate( FALSE);
- }
- void CWorldEditorView::OnChooseColor()
- {
- /*
- // find toll bar's rectangle
- RECT rectToolBar;
- m_wndSelectionTools.GetWindowRect( &rectToolBar);
- // Then we find tool button's index
- INDEX iToolButton = m_wndSelectionTools.CommandToIndex( ID_CHOOSE_COLOR);
- // Using given index, we obtain button's rectangle
- RECT rectButton;
- m_wndSelectionTools.GetItemRect( iToolButton, &rectButton);
- // set screen coordinates of LU point of clicked tool button
- CustomColorPicker( rectToolBar.left + rectButton.left, rectToolBar.top + rectButton.bottom);
- */
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- POINT ptCursor;
- GetCursorPos( &ptCursor);
- if( ptCursor.y < 100)
- {
- pMainFrame->CustomColorPicker( ptCursor.x-50, ptCursor.y);
- }
- else
- {
- pMainFrame->CustomColorPicker( ptCursor.x-50, ptCursor.y-100);
- }
- }
- void CWorldEditorView::OnUpdateChooseColor(CCmdUI* pCmdUI)
- {
- // don't enable initially
- BOOL bEnable = FALSE;
- // obtain document
- CWorldEditorDoc *pDoc = GetDocument();
- // if sector mode is on and there is at least 1 selected sector
- if( (pDoc->m_iMode == SECTOR_MODE) && (pDoc->m_selSectorSelection.Count() != 0) )
- {
- bEnable = TRUE;
- }
- // if polygon mode is on and there is at least 1 selected polygon
- if( (pDoc->m_iMode == POLYGON_MODE) && (pDoc->m_selPolygonSelection.Count() != 0) )
- {
- bEnable = TRUE;
- }
- pCmdUI->Enable( bEnable);
- }
- void CWorldEditorView::OnCrossroadForC()
- {
- PostMessage( WM_COMMAND, ID_CHOOSE_COLOR, 0);
- PostMessage( WM_COMMAND, ID_CENTER_ENTITY, 0);
- }
- void CWorldEditorView::SetAsCsgTarget(CEntity *pen)
- {
- if( (pen != NULL) &&
- ( (pen->GetRenderType() == CEntity::RT_BRUSH) ||
- (pen->GetRenderType() == CEntity::RT_FIELDBRUSH)) )
- {
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- pMainFrame->m_CSGDesitnationCombo.SelectBrushEntity(pen);
- }
- }
- void CWorldEditorView::OnSetAsCsgTarget()
- {
- SetAsCsgTarget(m_penEntityHitOnContext);
- }
- void CWorldEditorView::OnCsgSelectSector()
- {
- if( (m_penEntityHitOnContext != NULL) &&
- ((m_penEntityHitOnContext->GetRenderType() == CEntity::RT_BRUSH) ||
- (m_penEntityHitOnContext->GetRenderType() == CEntity::RT_FIELDBRUSH)) &&
- (m_pbpoRightClickedPolygon != NULL) )
- {
- CBrushSector *pbscHitted = m_pbpoRightClickedPolygon->bpo_pbscSector;
- CWorldEditorDoc *pDoc = GetDocument();
- pDoc->m_selSectorSelection.Clear();
- pDoc->m_selSectorSelection.Select( *pbscHitted);
- }
- }
- LRESULT CWorldEditorView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
- {
- CChildFrame *pCF = GetChildFrame();
- // if test game is active
- if( _pInput->IsInputEnabled())
- { // repost some messages to thread
- switch( message ) {
- case WM_CANCELMODE:
- case WM_KILLFOCUS:
- case WM_ACTIVATEAPP:
- case WM_LBUTTONUP:
- ::PostMessage(NULL, message, wParam, lParam);
- break;
- case WM_MOUSEACTIVATE:
- if( pCF->m_bTestGameOn)
- {
- return MA_ACTIVATEANDEAT;
- }
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- }
- }
- return CView::WindowProc(message, wParam, lParam);
- }
- void CWorldEditorView::OnRButtonDblClk(UINT nFlags, CPoint point)
- {
- m_iaInputAction = IA_NONE;
- BOOL bSpace = (GetKeyState( VK_SPACE)&0x8000) != 0;
- BOOL bCtrl = (GetKeyState( VK_CONTROL)&0x8000) != 0;
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- BOOL bLMB = nFlags & MK_LBUTTON;
- BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0;
- // space+ctrl+rmb zoomes out 2x
- if( (bSpace) && (bCtrl) )
- {
- if( bLMB) return;
- OnZoomLess();
- return;
- }
- // RMB dblclick and ctrl select by texture in sector
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- // Alt+Ctrl requests that clicked polygon sizes its texture
- if( bAlt && bCtrl)
- {
- MultiplyMappingOnPolygon( 2.0f);
- }
- else if( bCtrl && bShift && !bAlt)
- {
- OnSelectByColorInSector();
- }
- else if( bCtrl && !bAlt)
- {
- OnSelectByTextureAdjacent();
- }
- }
- CView::OnRButtonDblClk(nFlags, point);
- }
- void CWorldEditorView::OnLastPrimitive()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CTString strError;
- BOOL bCutEnabled = IsCutEnabled( strError);
- if( theApp.m_bCutModeOn)
- {
- if( !bCutEnabled)
- {
- // exit cut mode
- theApp.m_bCutModeOn = FALSE;
- WarningMessage( "%s", strError);
- return;
- }
- pDoc->ApplyCut();
- }
- else
- {
- // exit cut mode
- theApp.m_bCutModeOn = FALSE;
- pDoc->StartPrimitiveCSG( theApp.m_vfpCurrent.vfp_plPrimitive, FALSE);
- }
- }
- void CWorldEditorView::OnUpdateLastPrimitive(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable( GetDocument()->m_pwoSecondLayer == NULL);
- }
- void CWorldEditorView::OnConusPrimitive()
- {
- // copy last used values for conus primitive as initial values for new primitive
- theApp.m_vfpCurrent = theApp.m_vfpConus;
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->StartPrimitiveCSG( theApp.m_vfpCurrent.vfp_plPrimitive, FALSE);
- }
- void CWorldEditorView::OnTorusPrimitive()
- {
- // copy last used values for torus primitive as initial values for new primitive
- theApp.m_vfpCurrent = theApp.m_vfpTorus;
- // create primitive for the first time
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->StartPrimitiveCSG( theApp.m_vfpCurrent.vfp_plPrimitive, FALSE);
- }
- void CWorldEditorView::OnStaircasePrimitive()
- {
- // copy last used values for staircase primitive as initial values for new primitive
- theApp.m_vfpCurrent = theApp.m_vfpStaircases;
- // create primitive for the first time
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->StartPrimitiveCSG( theApp.m_vfpCurrent.vfp_plPrimitive, FALSE);
- }
- void CWorldEditorView::OnSpherePrimitive()
- {
- // copy last used values for sphere primitive as initial values for new primitive
- theApp.m_vfpCurrent = theApp.m_vfpSphere;
- // create primitive for the first time
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->StartPrimitiveCSG( theApp.m_vfpCurrent.vfp_plPrimitive, FALSE);
- }
- void CWorldEditorView::OnTerrainPrimitive()
- {
- // copy last used values for terrain primitive as initial values for new primitive
- theApp.m_vfpCurrent = theApp.m_vfpTerrain;
- // create primitive for the first time
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->StartPrimitiveCSG( theApp.m_vfpCurrent.vfp_plPrimitive, FALSE);
- }
- void CWorldEditorView::OnUpdateConusPrimitive(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable( GetDocument()->m_pwoSecondLayer == NULL);
- }
- void CWorldEditorView::OnUpdateSpherePrimitive(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable( GetDocument()->m_pwoSecondLayer == NULL);
- }
- void CWorldEditorView::OnUpdateTerrainPrimitive(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable( GetDocument()->m_pwoSecondLayer == NULL);
- }
- void CWorldEditorView::OnUpdateTorusPrimitive(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable( GetDocument()->m_pwoSecondLayer == NULL);
- }
- void CWorldEditorView::OnUpdateStaircasePrimitive(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable( GetDocument()->m_pwoSecondLayer == NULL);
- }
- void CWorldEditorView::OnUpdateMoveDown(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pCmdUI->Enable( (pDoc->m_pwoSecondLayer != NULL) &&
- (pDoc->m_bPrimitiveMode) &&
- (theApp.m_vfpCurrent.vfp_ttTriangularisationType != TT_NONE) );
- }
- void CWorldEditorView::OnUpdateMoveUp(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pCmdUI->Enable( (pDoc->m_pwoSecondLayer != NULL) &&
- (pDoc->m_bPrimitiveMode) &&
- (theApp.m_vfpCurrent.vfp_ttTriangularisationType != TT_NONE) );
- }
- void CWorldEditorView::OnSelectLights()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- CBrushPolygon *pbpoPolygon = crRayHit.cr_pbpoBrushPolygon;
- // if we hit brush entity
- if( (crRayHit.cr_penHit == NULL) ||
- (pbpoPolygon == NULL) ||
- (pbpoPolygon->IsSelected(BPOF_SELECTED)) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- CBrushShadowMap &bsm = itbpo->bpo_smShadowMap;
- FOREACHINLIST(CBrushShadowLayer, bsl_lnInShadowMap, bsm.bsm_lhLayers, itbsl)
- {
- CLightSource *plsLight = itbsl->bsl_plsLightSource;
- CEntity *penLight = plsLight->ls_penEntity;
- if( !pDoc->m_selEntitySelection.IsSelected( *penLight))
- {
- pDoc->m_selEntitySelection.Select( *penLight);
- }
- }
- }
- }
- else
- {
- CBrushShadowMap &bsm = pbpoPolygon->bpo_smShadowMap;
- FOREACHINLIST(CBrushShadowLayer, bsl_lnInShadowMap, bsm.bsm_lhLayers, itbsl)
- {
- CLightSource *plsLight = itbsl->bsl_plsLightSource;
- CEntity *penLight = plsLight->ls_penEntity;
- if( !pDoc->m_selEntitySelection.IsSelected( *penLight))
- {
- pDoc->m_selEntitySelection.Select( *penLight);
- }
- }
- }
- pDoc->SetEditingMode( ENTITY_MODE);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnDiscardShadows()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CEntity *penEntity = NULL;
- CBrushSector *pbscSector = NULL;
- CBrushPolygon *pbpoPolygon = NULL;
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- penEntity = crRayHit.cr_penHit;
- pbscSector = crRayHit.cr_pbpoBrushPolygon->bpo_pbscSector;
- pbpoPolygon = crRayHit.cr_pbpoBrushPolygon;
- }
- if( pDoc->GetEditingMode() == ENTITY_MODE)
- {
- DiscardShadows( penEntity);
- }
- else if( pDoc->GetEditingMode() == SECTOR_MODE)
- {
- DiscardShadows( pbscSector);
- }
- else if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- DiscardShadows( pbpoPolygon);
- }
- }
- void CWorldEditorView::OnCopySectorAmbient()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- CBrushSector *pbscHitted = NULL;
- if( (m_penEntityHitOnContext != NULL) &&
- (m_penEntityHitOnContext->GetRenderType() == CEntity::RT_BRUSH) &&
- (m_pbpoRightClickedPolygon != NULL) )
- {
- CopySectorAmbient( m_pbpoRightClickedPolygon->bpo_pbscSector);
- }
- }
- void CWorldEditorView::OnPasteSectorAmbient()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- CBrushSector *pbscHitted = NULL;
- if( (m_penEntityHitOnContext != NULL) &&
- (m_penEntityHitOnContext->GetRenderType() == CEntity::RT_BRUSH) &&
- (m_pbpoRightClickedPolygon != NULL) )
- {
- PasteSectorAmbient( m_pbpoRightClickedPolygon->bpo_pbscSector);
- }
- }
- void CWorldEditorView::OnSelectAllPolygons( void)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- CBrushSector *pbscHitted = NULL;
- if( (m_penEntityHitOnContext != NULL) &&
- (m_penEntityHitOnContext->GetRenderType() == CEntity::RT_BRUSH) &&
- (m_pbpoRightClickedPolygon != NULL) )
- {
- pbscHitted = m_pbpoRightClickedPolygon->bpo_pbscSector;
- }
- if( (pbscHitted == NULL) || pbscHitted->IsSelected( BSCF_SELECTED) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selSectorSelection, CBrushSector, itbsc)
- {
- FOREACHINSTATICARRAY(itbsc->bsc_abpoPolygons, CBrushPolygon, itbpo)
- {
- if( !itbpo->IsSelected(BPOF_SELECTED)) pDoc->m_selPolygonSelection.Select( *itbpo);
- }
- }
- }
- else
- {
- FOREACHINSTATICARRAY(pbscHitted->bsc_abpoPolygons, CBrushPolygon, itpo)
- {
- if( !itpo->IsSelected(BPOF_SELECTED)) pDoc->m_selPolygonSelection.Select( *itpo);
- }
- }
- pDoc->SetEditingMode( POLYGON_MODE);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnSelectAllVertices()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- CBrushPolygon *pbpoHitted = NULL;
- if( (m_penEntityHitOnContext != NULL) &&
- (m_penEntityHitOnContext->GetRenderType() == CEntity::RT_BRUSH) &&
- (m_pbpoRightClickedPolygon != NULL) )
- {
- pbpoHitted = m_pbpoRightClickedPolygon;
- }
- if( (pbpoHitted == NULL) || pbpoHitted->IsSelected( BPOF_SELECTED) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- FOREACHINSTATICARRAY(itbpo->bpo_apbvxTriangleVertices, CBrushVertex *, itpbvx)
- {
- if( !(*itpbvx)->IsSelected(BVXF_SELECTED)) pDoc->m_selVertexSelection.Select( **itpbvx);
- }
- }
- }
- else
- {
- FOREACHINSTATICARRAY(pbpoHitted->bpo_apbvxTriangleVertices, CBrushVertex *, itpbvx)
- {
- if( !(*itpbvx)->IsSelected(BVXF_SELECTED)) pDoc->m_selVertexSelection.Select( **itpbvx);
- }
- }
- pDoc->SetEditingMode( VERTEX_MODE);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnCopySectors()
- {
- OnEditCopy();
- }
- void CWorldEditorView::OnPasteSectors()
- {
- OnEditPaste();
- }
- void CWorldEditorView::OnDeleteSectors()
- {
- OnDeleteEntities();
- }
- void CWorldEditorView::GetToolTipText( char *pToolTipText)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CPoint CursorPos;
- ::GetCursorPos(&CursorPos);
- ScreenToClient(&CursorPos);
- // obtain information about where mouse points into the world
- BOOL bHitModels = pDoc->GetEditingMode() != POLYGON_MODE;
- BOOL bHitFields = pDoc->GetEditingMode() == ENTITY_MODE;
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse, FALSE, bHitModels, bHitFields);
- CEntity *penEntity = crRayHit.cr_penHit;
- CBrushPolygon *pbpoPolygon = crRayHit.cr_pbpoBrushPolygon;
- CBrushSector *pbscSector = NULL;
- if( pbpoPolygon != NULL) pbscSector = crRayHit.cr_pbpoBrushPolygon->bpo_pbscSector;
- char *pchrCursor = pToolTipText;
- INDEX iLongestLineLetters = 1;
- CDLLEntityClass *pdecDLLClass;
- if( (pDoc->GetEditingMode() == ENTITY_MODE) && (penEntity != NULL))
- {
- // get description line for all properties with name
- pdecDLLClass = penEntity->GetClass()->ec_pdecDLLClass;
- pchrCursor += sprintf(pchrCursor, "Class: %-24.24s\n", pdecDLLClass->dec_strName);
- INDEX ctLetters = strlen("Class: ")+strlen(pdecDLLClass->dec_strName);
- memset(pchrCursor, '�', ctLetters);
- pchrCursor+=ctLetters;
- *pchrCursor = '\n';
- pchrCursor++;
- }
- INDEX ctMips = 0;
- INDEX iMipIndex = 0;
- INDEX ctEntities = 0;
- INDEX ctSectors = 0;
- INDEX ctPolygons = 0;
- INDEX ctEdges = 0;
- INDEX ctVertices = 0;
- INDEX ctPlanes = 0;
- // see if info should apply to whole selection
- BOOL bCountSelection = TRUE;
- if( (pDoc->GetEditingMode() == ENTITY_MODE) &&
- (penEntity != NULL) &&
- (!penEntity->IsSelected( ENF_SELECTED)) )
- {
- bCountSelection = FALSE;
- }
- if( (pDoc->GetEditingMode() == POLYGON_MODE) &&
- (pbpoPolygon != NULL) &&
- (!pbpoPolygon->IsSelected( BPOF_SELECTED)) )
- {
- bCountSelection = FALSE;
- }
- if( (pDoc->GetEditingMode() == SECTOR_MODE) &&
- (pbscSector != NULL) &&
- (!pbscSector->IsSelected( BSCF_SELECTED)) )
- {
- bCountSelection = FALSE;
- }
- if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- CTerrain *ptrTerrain=GetTerrain();
- if(ptrTerrain!=NULL)
- {
- pchrCursor += sprintf(pchrCursor, "%-24s %g x %g x %g\n%-24s %d x %d\n%-24s %d x %d\n%-24s %d x %d\n%-24s %d\n%-24s %d\n%-24s %g\n",
- "Terrain size", ptrTerrain->tr_vTerrainSize(1),ptrTerrain->tr_vTerrainSize(2),ptrTerrain->tr_vTerrainSize(3),
- "Height map size", ptrTerrain->tr_pixHeightMapWidth, ptrTerrain->tr_pixHeightMapHeight,
- "Shadow map size", ptrTerrain->GetShadowMapWidth(), ptrTerrain->GetShadowMapHeight(),
- "Model shading map size", ptrTerrain->GetShadingMapWidth(), ptrTerrain->GetShadingMapHeight(),
- "Layers", ptrTerrain->tr_atlLayers.Count(),
- "Tiles", ptrTerrain->tr_ctTiles,
- "LOD switch distance", ptrTerrain->tr_fDistFactor);
- }
- else
- {
- pchrCursor += sprintf(pchrCursor, "Terrain not selected\n");
- }
- }
- if( pDoc->GetEditingMode() == ENTITY_MODE)
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- if( (bCountSelection && iten->IsSelected( ENF_SELECTED)) ||
- (!bCountSelection && (iten ==penEntity)) )
- {
- ctEntities ++;
- CEntity::RenderType rt = iten->GetRenderType();
- if (rt==CEntity::RT_BRUSH || rt==CEntity::RT_FIELDBRUSH)
- {
- CBrush3D *pBrush3D = iten->GetBrush();
- if(pBrush3D != NULL)
- {
- FLOAT fCurrentMipFactor = GetCurrentlyActiveMipFactor();
- CBrush3D *pbrBrush = iten->GetBrush();
- if( pbrBrush != NULL)
- {
- CBrushMip *pbmCurrentMip = pbrBrush->GetBrushMipByDistance( fCurrentMipFactor);
- if( pbmCurrentMip != NULL)
- {
- ctSectors += pbmCurrentMip->bm_abscSectors.Count();
- FOREACHINDYNAMICARRAY(pbmCurrentMip->bm_abscSectors, CBrushSector, itbsc)
- {
- ctPolygons += itbsc->bsc_abpoPolygons.Count();
- ctEdges += itbsc->bsc_abedEdges.Count();
- ctVertices+= itbsc->bsc_abvxVertices.Count();
- ctPlanes += itbsc->bsc_abplPlanes.Count();
- }
- }
- }
- }
- }
- }
- }
- pchrCursor += sprintf(pchrCursor, "%-24s %d\n%-24s %d\n%-24s %d\n%-24s %d\n%-24s %d\n%-24s %d\n",
- "No of entities:", ctEntities,
- "No of sectors:", ctSectors,
- "No of polygons:", ctPolygons,
- "No of edges:", ctEdges,
- "No of vertices:", ctVertices,
- "No of planes:", ctPlanes);
- pchrCursor += sprintf(pchrCursor, "%s\n", "������������������������������");
- if( !bCountSelection)
- {
- CEntity::RenderType rt = penEntity->GetRenderType();
- if (rt==CEntity::RT_BRUSH || rt==CEntity::RT_FIELDBRUSH)
- {
- CBrush3D *pBrush3D = penEntity->GetBrush();
- if(pBrush3D != NULL)
- {
- INDEX iMip = 0;
- FOREACHINLIST(CBrushMip, bm_lnInBrush, pBrush3D->br_lhBrushMips, itbm)
- {
- FLOAT fMipSwitchDistance = itbm->GetMipDistance();
- CTString strTmp;
- strTmp.PrintF("Mip %d is visible until ", iMip);
- pchrCursor += sprintf(pchrCursor, "%-24s %g m\n", strTmp, fMipSwitchDistance);
- iMip++;
- }
- pchrCursor += sprintf(pchrCursor, "%s\n", "������������������������������");
- }
- }
- }
- }
- if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- if( bCountSelection)
- {
- INDEX ctEdges = 0;
- ULONG ulShadowMemory = 0;
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- ctEdges += itbpo->bpo_abpePolygonEdges.Count();
- ulShadowMemory += itbpo->bpo_smShadowMap.GetShadowSize();
- }
- pchrCursor += sprintf(pchrCursor, "Selection has %d polygons with %d edges\n", pDoc->m_selPolygonSelection.Count(), ctEdges);
- pchrCursor += sprintf(pchrCursor, "Shadows on selected polygons occupy %g kb\n", ulShadowMemory/1024.0f);
- }
- if( pbpoPolygon != NULL)
- {
- CTextureData *ptd;
- #define SET_MAPPING_INFO(mp, tex_name)\
- ptd = (CTextureData*) mp.bpt_toTexture.GetData();\
- if( ptd == NULL) pchrCursor += sprintf(pchrCursor, "%-24s None\n", tex_name);\
- else {\
- pchrCursor += sprintf(pchrCursor, "%-24s %.64s %s\n", tex_name, CTString(ptd->GetName()),\
- ptd->GetDescription() );\
- pchrCursor += sprintf(pchrCursor, "%-24s %s %s\n", " ",\
- "Scroll: \""+pDoc->m_woWorld.wo_attTextureTransformations[mp.s.bpt_ubScroll].tt_strName+"\"",\
- "Blend: \""+pDoc->m_woWorld.wo_atbTextureBlendings[mp.s.bpt_ubBlend].tb_strName+"\"");}
- CBrushPolygon &bpo = *crRayHit.cr_pbpoBrushPolygon;
- SET_MAPPING_INFO( bpo.bpo_abptTextures[0], "Texture 1");
- SET_MAPPING_INFO( bpo.bpo_abptTextures[1], "Texture 2");
- SET_MAPPING_INFO( bpo.bpo_abptTextures[2], "Texture 3");
- pchrCursor += sprintf(pchrCursor, "Polygon under mouse has %d edges\n", bpo.bpo_abpePolygonEdges.Count());
- pchrCursor += sprintf(pchrCursor, "Shadow on polygon under mouse occupies %g kb\n", bpo.bpo_smShadowMap.GetShadowSize()/1024.0f);
- }
- }
- if( pDoc->GetEditingMode() == SECTOR_MODE)
- {
- if( bCountSelection)
- {
- ctSectors = pDoc->m_selSectorSelection.Count();
- FOREACHINDYNAMICCONTAINER(pDoc->m_selSectorSelection, CBrushSector, itbsc)
- {
- ctPolygons += itbsc->bsc_abpoPolygons.Count();
- ctEdges += itbsc->bsc_abedEdges.Count();
- ctVertices+= itbsc->bsc_abvxVertices.Count();
- ctPlanes += itbsc->bsc_abplPlanes.Count();
- }
- pchrCursor += sprintf(pchrCursor, "%-24s %d\n%-24s %d\n%-24s %d\n%-24s %d\n%-24s %d\n%",
- "No of sectors:", ctSectors,
- "No of polygons:", ctPolygons,
- "No of edges:", ctEdges,
- "No of vertices:", ctVertices,
- "No of planes:", ctPlanes);
- }
- else
- {
- ctPolygons = pbscSector->bsc_abpoPolygons.Count();
- ctEdges = pbscSector->bsc_abedEdges.Count();
- ctVertices = pbscSector->bsc_abvxVertices.Count();
- ctPlanes = pbscSector->bsc_abplPlanes.Count();
- UBYTE ubR, ubG, ubB;
- UBYTE ubH, ubS, ubV;
- ColorToRGB( pbscSector->bsc_colAmbient, ubR, ubG, ubB);
- ColorToHSV( pbscSector->bsc_colAmbient, ubH, ubS, ubV);
- CTString strSectorName = pbscSector->bsc_strName;
- if( strSectorName == "") strSectorName = "<not defined>";
- INDEX iContentType = pbscSector->GetContentType();
- CTString strContentType = pDoc->m_woWorld.wo_actContentTypes[iContentType].ct_strName;
- if( strContentType == "") strContentType = "<not defined>";
- INDEX iEnvironmentType = pbscSector->GetEnvironmentType();
- CTString strEnvironmentType = pDoc->m_woWorld.wo_aetEnvironmentTypes[iEnvironmentType].et_strName;
- if( strEnvironmentType == "") strEnvironmentType = "<not defined>";
- INDEX iForceType = pbscSector->GetForceType();
- CBrush3D *pbrBrush = pbscSector->bsc_pbmBrushMip->bm_pbrBrush;
- CTString strForceType = pbrBrush->br_penEntity->GetForceName( iForceType);
- if( strForceType == "") strForceType = "<not defined>";
- pchrCursor += sprintf(pchrCursor, "%-24.24s %.64s\n%-24s %d\n%-24s %d\n%-24s %d\n%-24s %d\n%-24s"
- "(R=%d G=%d B=%d) (H=%d S=%d V=%d)\n%-24.24s %.64s\n%-24.24s %.64s\n%-24.24s %.64s\n",
- "Name:", strSectorName,
- "No of polygons:", ctPolygons,
- "No of edges:", ctEdges,
- "No of vertices:", ctVertices,
- "No of planes:", ctPlanes,
- "Ambient color:", ubR, ubG, ubB, ubH, ubS, ubV,
- "Content type:", strContentType,
- "Environment type:", strEnvironmentType,
- "Force type:", strForceType);
- }
- }
- if( pDoc->GetEditingMode() == CSG_MODE)
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_pwoSecondLayer->wo_cenEntities, CEntity, iten)
- {
- CEntity::RenderType rt = iten->GetRenderType();
- if (rt==CEntity::RT_BRUSH || rt==CEntity::RT_FIELDBRUSH)
- {
- CBrush3D *pBrush3D = iten->GetBrush();
- if( pBrush3D != NULL)
- {
- FLOAT fCurrentMipFactor = GetCurrentlyActiveMipFactor();
- CBrush3D *pbrBrush = iten->GetBrush();
- if( pbrBrush != NULL)
- {
- CBrushMip *pbmCurrentMip = pbrBrush->GetBrushMipByDistance( fCurrentMipFactor);
- if( pbmCurrentMip != NULL)
- {
- FOREACHINDYNAMICARRAY(pbmCurrentMip->bm_abscSectors, CBrushSector, itbsc)
- {
- ctPolygons += itbsc->bsc_abpoPolygons.Count();
- ctEdges += itbsc->bsc_abedEdges.Count();
- ctVertices+= itbsc->bsc_abvxVertices.Count();
- ctPlanes += itbsc->bsc_abplPlanes.Count();
- }
- }
- }
- }
- }
- }
- pchrCursor += sprintf(pchrCursor, "Primitive info:\n���������������\n%-24s %d\n%-24s %d\n%-24s %d\n%-24s %d",
- "No of polygons:", ctPolygons,
- "No of edges:", ctEdges,
- "No of vertices:", ctVertices,
- "No of planes:", ctPlanes);
- }
- if( (pDoc->GetEditingMode() == ENTITY_MODE) && (penEntity!=NULL) )
- {
- // add count of occupiing sectors and their names
- INDEX ctIntersectingSectors = penEntity->en_rdSectors.Count();
- INDEX ctWithName = 0;
- {FOREACHSRCOFDST(penEntity->en_rdSectors, CBrushSector, bsc_rsEntities, pbsc)
- if( pbsc->bsc_strName != "") ctWithName++;
- ENDFOR}
- INDEX ctLetters = sprintf(pchrCursor, "In %d sectors (%d with name):\n", ctIntersectingSectors, ctWithName);
- if( ctLetters > iLongestLineLetters) iLongestLineLetters = ctLetters;
- pchrCursor += ctLetters;
- {FOREACHSRCOFDST(penEntity->en_rdSectors, CBrushSector, bsc_rsEntities, pbsc)
- if( pbsc->bsc_strName != "")
- {
- INDEX ctLetters = sprintf(pchrCursor, "In: %-24.24s\n", pbsc->bsc_strName);
- if( ctLetters > iLongestLineLetters) iLongestLineLetters = ctLetters;
- pchrCursor += ctLetters;
- }
- ENDFOR}
- for(;pdecDLLClass!=NULL; pdecDLLClass = pdecDLLClass->dec_pdecBase)
- {
- CTString strValue;
- for(INDEX iProperty=0; iProperty<pdecDLLClass->dec_ctProperties; iProperty++)
- {
- CEntityProperty &epProperty = pdecDLLClass->dec_aepProperties[iProperty];
- if( epProperty.ep_strName == CTString("")) continue;
- strValue = "!!! Unkown property type";
- switch( epProperty.ep_eptType)
- {
- case CEntityProperty::EPT_FLAGS:
- {
- strValue = "Flag array property";
- }
- case CEntityProperty::EPT_ENUM:
- {
- INDEX iCurrentEnum = ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, INDEX);
- CEntityPropertyEnumType *epEnum = epProperty.ep_pepetEnumType;
- for( INDEX iEnum = 0; iEnum< epEnum->epet_ctValues; iEnum++)
- {
- INDEX iEnumID = epEnum->epet_aepevValues[ iEnum].epev_iValue;
- if( iEnumID == iCurrentEnum)
- strValue = (epEnum->epet_aepevValues[ iEnum].epev_strName);
- }
- break;
- }
- case CEntityProperty::EPT_BOOL:
- {
- if( ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, BOOL))strValue = "TRUE";
- else strValue = "FALSE";
- break;
- }
- case CEntityProperty::EPT_FLOAT:
- {
- strValue.PrintF( "%g", ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, FLOAT));
- break;
- }
- case CEntityProperty::EPT_RANGE:
- {
- strValue.PrintF( "%g m", ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, FLOAT));
- break;
- }
- case CEntityProperty::EPT_COLOR:
- {
- COLOR colColor = ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, COLOR);
- UBYTE ubR, ubG, ubB, ubA;
- UBYTE ubH, ubS, ubV;
- ubA=colColor&0xFF;
- ColorToRGB( colColor, ubR, ubG, ubB);
- ColorToHSV( colColor, ubH, ubS, ubV);
- strValue.PrintF( "RGBA(%d,%d,%d,%d) HSV(%d,%d,%d)", ubR,ubG,ubB,ubA,ubH,ubS,ubV);
- break;
- }
- case CEntityProperty::EPT_STRING:
- case CEntityProperty::EPT_STRINGTRANS:
- case CEntityProperty::EPT_FILENAMENODEP:
- {
- strValue = ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, CTString);
- if( strValue == "") strValue = "<no value>";
- break;
- }
- case CEntityProperty::EPT_ENTITYPTR:
- {
- CEntity *pen=ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, CEntity *);
- if( pen == NULL) strValue = "-> None";
- else strValue = "-> "+pen->GetName();
- break;
- }
- case CEntityProperty::EPT_PARENT:
- {
- CEntity *pen=penEntity->GetParent();
- if( pen == NULL) strValue = "-> None";
- else strValue = "-> "+pen->GetName();
- break;
- }
- case CEntityProperty::EPT_FILENAME:
- {
- strValue = ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, CTFileName);
- if( strValue == "") strValue = "<no file>";
- break;
- }
- case CEntityProperty::EPT_INDEX:
- case CEntityProperty::EPT_ANGLE:
- {
- strValue.PrintF( "%d", ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, INDEX) );
- break;
- }
- case CEntityProperty::EPT_ANIMATION:
- {
- CAnimData *pAD = penEntity->GetAnimData( epProperty.ep_slOffset);
- if( pAD == NULL)
- {
- strValue = "<no animation>";
- }
- else
- {
- CAnimInfo aiInfo;
- INDEX iAnimation = ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, INDEX);
- pAD->GetAnimInfo( iAnimation, aiInfo);
- strValue = aiInfo.ai_AnimName;
- }
- break;
- }
- case CEntityProperty::EPT_ILLUMINATIONTYPE:
- {
- INDEX iIllumination = ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, INDEX);
- strValue = pDoc->m_woWorld.wo_aitIlluminationTypes[iIllumination].it_strName;
- break;
- }
- case CEntityProperty::EPT_FLOATAABBOX3D:
- {
- FLOATaabbox3D bbox = ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, FLOATaabbox3D);
- FLOAT3D vMin = bbox.Min();
- FLOAT3D vMax = bbox.Max();
- strValue.PrintF( "Min(%g,%g,%g), Max(%g,%g,%g)",
- vMin(1), vMin(2), vMin(3), vMax(1), vMax(2), vMax(3));
- break;
- }
- case CEntityProperty::EPT_FLOAT3D:
- {
- FLOAT3D vVector = ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, FLOAT3D);
- strValue.PrintF( "%g,%g,%g", vVector(1), vVector(2), vVector(3));
- break;
- }
- case CEntityProperty::EPT_ANGLE3D:
- {
- ANGLE3D aAngle = ENTITYPROPERTY( &*penEntity, epProperty.ep_slOffset, ANGLE3D);
- strValue.PrintF( "%g,%g,%g", DegAngle(aAngle(1)), DegAngle(aAngle(2)), DegAngle(aAngle(3)));
- break;
- }
- }
- INDEX ctLetters = sprintf(pchrCursor, "%-24.24s %.64s \n", epProperty.ep_strName, strValue);
- if( ctLetters > iLongestLineLetters) iLongestLineLetters = ctLetters;
- pchrCursor += ctLetters;
- }
- }
- if( iLongestLineLetters>2)
- {
- iLongestLineLetters-=2;
- memset(pchrCursor, '_', iLongestLineLetters);
- pchrCursor+=iLongestLineLetters;
- *pchrCursor = '\n';
- pchrCursor++;
- }
- if( penEntity->GetParent() != NULL)
- {
- pchrCursor += sprintf(pchrCursor, "Parent: %s\n", penEntity->GetParent()->GetName());
- }
- else
- {
- pchrCursor += sprintf(pchrCursor, "No parent\n");
- }
- CTString strSpawn = "";
- ULONG ulSpawn = penEntity->GetSpawnFlags();
- ULONG ulAllways = SPF_EASY|SPF_NORMAL|SPF_HARD|SPF_EXTREME|SPF_SINGLEPLAYER|SPF_COOPERATIVE|SPF_DEATHMATCH;
- if( (ulSpawn & ulAllways) == ulAllways)
- {
- pchrCursor += sprintf(pchrCursor, "%s", "Entity exists allways");
- }
- else
- {
- if( ulSpawn & SPF_EASY) strSpawn+="Easy,";
- if( ulSpawn & SPF_NORMAL) strSpawn+="Normal,";
- if( ulSpawn & SPF_HARD) strSpawn+="Hard,";
- if( ulSpawn & SPF_EXTREME) strSpawn+="Extreme,";
- if( ulSpawn & SPF_SINGLEPLAYER) strSpawn+="Single,";
- if( ulSpawn & SPF_COOPERATIVE) strSpawn+="Cooperative,";
- if( ulSpawn & SPF_DEATHMATCH) strSpawn+="Deathmatch,";
- if( strSpawn != "")
- {
- pchrCursor += sprintf(pchrCursor, "%s", strSpawn);
- *(pchrCursor-1) = 0;
- }
- else
- {
- pchrCursor += sprintf(pchrCursor, "%s", "Does not exist acording to spawn flags");
- }
- }
- }
- if( pDoc->GetEditingMode() == VERTEX_MODE)
- {
- pchrCursor += sprintf(pchrCursor, "%d %s", pDoc->m_selVertexSelection.Count(), "vertices");
- }
- }
- void CWorldEditorView::OnMenuCopyMapping()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- ASSERT( m_pbpoRightClickedPolygon != NULL);
- CopyMapping(m_pbpoRightClickedPolygon);
- }
- void CWorldEditorView::OnKeyPaste()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- theApp.m_iTerrainBrushMode=TBM_PAINT;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- pDoc->SetStatusLineModeInfoMessage();
- }
- else
- {
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- // paste mapping
- PasteMapping( crRayHit.cr_pbpoBrushPolygon, FALSE);
- }
- }
- }
- void CWorldEditorView::OnKeyPasteAsProjected()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- // paste mapping
- PasteMapping( crRayHit.cr_pbpoBrushPolygon, TRUE);
- }
- }
- void CWorldEditorView::OnMenuPasteMapping()
- {
- PasteMapping( m_pbpoRightClickedPolygon, FALSE);
- }
- void CWorldEditorView::OnMenuPasteAsProjectedMapping()
- {
- PasteMapping( m_pbpoRightClickedPolygon, TRUE);
- }
- void CWorldEditorView::CopyMapping(CBrushPolygon *pbpo)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- ASSERT(pbpo!=NULL);
- CBrushPlane *pbpl = pbpo->bpo_pbplPlane;
- CEntity *pen = pbpo->bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush->br_penEntity;
- ASSERT(pen!=NULL);
- // get the mapping in absolute space
- theApp.m_mdMapping = pbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping;
- theApp.m_mdMapping.Transform(pbpl->bpl_plRelative, pen->GetPlacement(), _plOrigin);
- theApp.m_plMapping = pbpl->bpl_plAbsolute;
- theApp.m_mdMapping1 = pbpo->bpo_abptTextures[0].bpt_mdMapping;
- theApp.m_mdMapping1.Transform(pbpl->bpl_plRelative, pen->GetPlacement(), _plOrigin);
- theApp.m_plMapping1 = pbpl->bpl_plAbsolute;
- theApp.m_mdMapping2 = pbpo->bpo_abptTextures[1].bpt_mdMapping;
- theApp.m_mdMapping2.Transform(pbpl->bpl_plRelative, pen->GetPlacement(), _plOrigin);
- theApp.m_plMapping2 = pbpl->bpl_plAbsolute;
- theApp.m_mdMapping3 = pbpo->bpo_abptTextures[2].bpt_mdMapping;
- theApp.m_mdMapping3.Transform(pbpl->bpl_plRelative, pen->GetPlacement(), _plOrigin);
- theApp.m_plMapping3 = pbpl->bpl_plAbsolute;
- }
- void CWorldEditorView::PasteMappingOnOnePolygon(CBrushPolygon *pbpo, BOOL bAsProjected)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- PasteOneLayerMapping(pDoc->m_iTexture, theApp.m_mdMapping, theApp.m_plMapping, pbpo, bAsProjected);
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
-
- void CWorldEditorView::PasteOneLayerMapping(INDEX iLayer, CMappingDefinition &md,
- FLOATplane3D &pl, CBrushPolygon *pbpo, BOOL bAsProjected)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- // get the mapping in relative space of the brush polygon's entity
- CEntity *pen = pbpo->bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush->br_penEntity;
- CSimpleProjection3D pr;
- pr.ObjectPlacementL() = _plOrigin;
- pr.ViewerPlacementL() = pen->GetPlacement();
- pr.Prepare();
- FLOATplane3D plRelative;
- pr.Project(pl, plRelative);
- CMappingDefinition mdRelative = md;
- mdRelative.Transform(pl, _plOrigin, pen->GetPlacement());
- // paste the mapping
- if( bAsProjected)
- {
- pbpo->bpo_abptTextures[iLayer].bpt_mdMapping.ProjectMapping(
- plRelative, mdRelative, pbpo->bpo_pbplPlane->bpl_plRelative);
- }
- else
- {
- pbpo->bpo_abptTextures[iLayer].bpt_mdMapping = mdRelative;
- }
- }
- void CWorldEditorView::PasteMapping(CBrushPolygon *pbpo, BOOL bAsProjected)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- // paste mapping over selection if clicked polygon is selected
- if( (pbpo == NULL) || (pbpo->IsSelected( BPOF_SELECTED)) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- PasteMappingOnOnePolygon(itbpo, bAsProjected);
- }
- }
- else
- {
- PasteMappingOnOnePolygon(pbpo, bAsProjected);
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnSelectAllEntitiesInSectors()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- CBrushSector *pbscHitted = NULL;
- if( (m_penEntityHitOnContext != NULL) &&
- (m_penEntityHitOnContext->GetRenderType() == CEntity::RT_BRUSH) &&
- (m_pbpoRightClickedPolygon != NULL) )
- {
- pbscHitted = m_pbpoRightClickedPolygon->bpo_pbscSector;
- }
- // if right clicked on nothing or selected sector
- if( (pbscHitted == NULL) || pbscHitted->IsSelected( BSCF_SELECTED) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selSectorSelection, CBrushSector, itbsc)
- {
- {FOREACHDSTOFSRC(itbsc->bsc_rsEntities, CEntity, en_rdSectors, pen)
- if( !pen->IsSelected( ENF_SELECTED) )
- {
- pDoc->m_selEntitySelection.Select( *pen);
- }
- ENDFOR}
- }
- }
- else
- {
- {FOREACHDSTOFSRC(pbscHitted->bsc_rsEntities, CEntity, en_rdSectors, pen)
- if( !pen->IsSelected( ENF_SELECTED) )
- {
- pDoc->m_selEntitySelection.Select( *pen);
- }
- ENDFOR}
- }
- pDoc->SetEditingMode( ENTITY_MODE);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnSelectAllSectors()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- if( m_penEntityHitOnContext == NULL)
- {
- // in all entities in world
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- CEntity::RenderType rt = iten->GetRenderType();
- if (rt==CEntity::RT_BRUSH || rt==CEntity::RT_FIELDBRUSH)
- {
- // for each mip in its brush
- FOREACHINLIST(CBrushMip, bm_lnInBrush, iten->GetBrush()->br_lhBrushMips, itbm)
- {
- // for all sectors in this mip
- FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc)
- {
- // if sector is not hidden and not selected
- if( !(itbsc->bsc_ulFlags & BSCF_HIDDEN) && !itbsc->IsSelected( BSCF_SELECTED) )
- {
- // select it
- pDoc->m_selSectorSelection.Select( *itbsc);
- }
- }
- }
- }
- }
- }
- // perform select sectors on whole entity selection
- else if( m_penEntityHitOnContext->IsSelected( ENF_SELECTED))
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- CEntity::RenderType rt = iten->GetRenderType();
- if (rt==CEntity::RT_BRUSH || rt==CEntity::RT_FIELDBRUSH)
- {
- FOREACHINLIST(CBrushMip, bm_lnInBrush, iten->GetBrush()->br_lhBrushMips, itbm)
- {
- // for all sectors in this mip
- FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc)
- {
- // if sector is not hidden and not selected
- if( !(itbsc->bsc_ulFlags & BSCF_HIDDEN) && !itbsc->IsSelected( BSCF_SELECTED) )
- {
- // select it
- pDoc->m_selSectorSelection.Select( *itbsc);
- }
- }
- }
- }
- }
- }
- else if (m_penEntityHitOnContext->GetRenderType() == CEntity::RT_BRUSH)
- {
- // select all sectors in all mip levels
- FOREACHINLIST(CBrushMip, bm_lnInBrush, m_penEntityHitOnContext->GetBrush()->br_lhBrushMips, itbm)
- {
- // select all sectors in current mip
- FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc)
- {
- if( !(itbsc->bsc_ulFlags & BSCF_HIDDEN) && !itbsc->IsSelected( BSCF_SELECTED) )
- {
- pDoc->m_selSectorSelection.Select( *itbsc);
- }
- }
- }
- }
- pDoc->SetEditingMode( SECTOR_MODE);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::CenterSelected(void)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CPropertyID *ppidProperty = pMainFrame->m_PropertyComboBar.GetSelectedProperty();
- // bounding box of visible sectors
- FLOATaabbox3D boxBoundingBox;
- if( pDoc->GetEditingMode() == ENTITY_MODE && (pDoc->m_selEntitySelection.Count() != 0) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- FLOAT3D vPos = iten->GetPlacement().pl_PositionVector;
- FLOATaabbox3D boxEntity;
- if( (ppidProperty != NULL) && (ppidProperty->pid_eptType == CEntityProperty::EPT_RANGE))
- {
- // obtain property ptr
- CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
- // get editing range
- FLOAT fRange = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOAT);
- boxEntity |= FLOATaabbox3D( FLOAT3D(0.0f, 0.0f ,0.0f), fRange);
- }
- else
- {
- iten->GetSize( boxEntity);
- }
- boxEntity+=vPos;
- boxBoundingBox |= boxEntity;
- }
- }
- else if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- CTerrain *ptrTerrain=GetTerrain();
- if(ptrTerrain!=NULL)
- {
- ptrTerrain->GetAllTerrainBBox(boxBoundingBox);
- }
- }
- else if( pDoc->GetEditingMode() == POLYGON_MODE && (pDoc->m_selPolygonSelection.Count() != 0) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- boxBoundingBox |= itbpo->bpo_boxBoundingBox;
- }
- }
- else if( pDoc->GetEditingMode() == SECTOR_MODE && (pDoc->m_selSectorSelection.Count() != 0) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selSectorSelection, CBrushSector, itbsc)
- {
- boxBoundingBox |= itbsc->bsc_boxBoundingBox;
- }
- }
- else if( (pDoc->GetEditingMode() == VERTEX_MODE) && (pDoc->m_selVertexSelection.Count() != 0) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selVertexSelection, CBrushVertex, itbvtx)
- {
- FLOATaabbox3D boxVtxBox = FLOATaabbox3D( itbvtx->bvx_vAbsolute);
- boxVtxBox.Expand( 20);
- boxBoundingBox |= boxVtxBox;
- }
- }
- else
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- CEntity::RenderType rt = iten->GetRenderType();
- if (rt==CEntity::RT_BRUSH || rt==CEntity::RT_FIELDBRUSH)
- {
- // for each mip in its brush
- FOREACHINLIST(CBrushMip, bm_lnInBrush, iten->GetBrush()->br_lhBrushMips, itbm)
- {
- // for all sectors in this mip
- FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc)
- {
- // if sector is not hidden
- if( !(itbsc->bsc_ulFlags & BSCF_HIDDEN))
- {
- boxBoundingBox |= itbsc->bsc_boxBoundingBox;
- }
- }
- }
- }
- else
- {
- FLOAT3D vPos = iten->GetPlacement().pl_PositionVector;
- FLOATaabbox3D boxEntity;
- iten->GetSize( boxEntity);
- boxEntity+=vPos;
- boxBoundingBox |= boxEntity;
- }
- }
- }
- AllignBox( boxBoundingBox);
- }
- void CWorldEditorView::AllignBox( FLOATaabbox3D bbox)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- CChildFrame *pCF = GetChildFrame();
- FLOAT3D vSize = bbox.Size();
- if( vSize.Length() <= 1.0f)
- vSize = FLOAT3D( 2.0f, 2.0f, 2.0f);
- // width is alligned inside horizontal borders of draw port, height and lenght
- // are alligned to height of draw port
- FLOAT fDX = (FLOAT)m_pdpDrawPort->GetWidth()*9/10;
- FLOAT fDY = (FLOAT)m_pdpDrawPort->GetHeight()*9/10;
- FLOAT fWantedZoom = Min( Min( fDX/vSize(1), fDY/vSize(2)), fDY/vSize(3));
- if( (fWantedZoom>1E-4) && (fWantedZoom<1E4) )
- {
- // create a slave viewer
- CSlaveViewer svViewer(pCF->m_mvViewer, m_ptProjectionType, pDoc->m_plGrid,
- m_pdpDrawPort);
- pCF->m_mvViewer.mv_fTargetDistance = svViewer.GetDistanceForZoom(fWantedZoom);
- pCF->m_mvViewer.SetTargetPlacement( bbox.Center());
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::AllignPolygon( CBrushPolygon *pbpo)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- CChildFrame *pCF = GetChildFrame();
-
- FLOATaabbox3D bbox = pbpo->bpo_boxBoundingBox;
- FLOAT3D vSize = bbox.Size();
- if( vSize.Length() <= 1.0f)
- vSize = FLOAT3D( 2.0f, 2.0f, 2.0f);
- // width is alligned inside horizontal borders of draw port, height and lenght
- // are alligned to height of draw port
- FLOAT fDX = (FLOAT)m_pdpDrawPort->GetWidth()*9/10;
- FLOAT fDY = (FLOAT)m_pdpDrawPort->GetHeight()*9/10;
- FLOAT fWantedZoom = Min( Min( fDX/vSize(1), fDY/vSize(2)), fDY/vSize(3));
- if( (fWantedZoom>1E-4) && (fWantedZoom<1E4) )
- {
- // create a slave viewer
- CSlaveViewer svViewer(pCF->m_mvViewer, m_ptProjectionType, pDoc->m_plGrid, m_pdpDrawPort);
- pCF->m_mvViewer.mv_fTargetDistance = svViewer.GetDistanceForZoom(fWantedZoom);
- FLOAT3D vDirection = pbpo->bpo_pbplPlane->bpl_plAbsolute;
- DirectionVectorToAngles( -vDirection, pCF->m_mvViewer.mv_plViewer.pl_OrientationAngle);
- pCF->m_mvViewer.SetTargetPlacement( bbox.Center());
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnCloneToMorePreciseMip()
- {
- OnAddMorePreciseMip(TRUE);
- }
- void CWorldEditorView::OnCreateEmptyMorePreciseMip()
- {
- OnAddMorePreciseMip(FALSE);
- }
- void CWorldEditorView::OnCloneToRougherMipLevel()
- {
- OnAddRougherMipLevel( TRUE);
- }
- void CWorldEditorView::OnCreateEmptyRougherMip()
- {
- OnAddRougherMipLevel( FALSE);
- }
- void CWorldEditorView::OnAddMorePreciseMip(BOOL bClone)
- {
- // remember current time as time when last mip brushing option has been used
- _fLastMipBrushingOptionUsed = _pTimer->GetRealTimeTick();
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->RememberUndo();
- CBrushMip *pbmCurrentMip = GetCurrentBrushMip();
- if (pbmCurrentMip==NULL) {
- return;
- }
- CBrushMip *pbmAdded = pbmCurrentMip->bm_pbrBrush->NewBrushMipBefore(pbmCurrentMip, bClone);
- GetChildFrame()->m_fManualMipBrushingFactor = pbmAdded->GetMipDistance()-0.01f;
- // document has changed
- pDoc->SetModifiedFlag();
- // update all views
- pDoc->UpdateAllViews( NULL);
- // set text describing data that is edited
- SetEditingDataPaneInfo( TRUE);
- }
- void CWorldEditorView::OnAddRougherMipLevel(BOOL bClone)
- {
- // remember current time as time when last mip brushing option has been used
- _fLastMipBrushingOptionUsed = _pTimer->GetRealTimeTick();
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->RememberUndo();
- CBrushMip *pbmCurrentMip = GetCurrentBrushMip();
- if (pbmCurrentMip==NULL) {
- return;
- }
- CBrushMip *pbmAdded = pbmCurrentMip->bm_pbrBrush->NewBrushMipAfter(pbmCurrentMip, bClone);
- GetChildFrame()->m_fManualMipBrushingFactor = pbmAdded->GetMipDistance()-0.01f;
- // document has changed
- pDoc->SetModifiedFlag();
- // update all views
- pDoc->UpdateAllViews( NULL);
- // set text describing data that is edited
- SetEditingDataPaneInfo( TRUE);
- }
- // get current brush mip of current csg target brush
- CBrushMip *CWorldEditorView::GetCurrentBrushMip(void)
- {
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CEntity *penBrush = pMainFrame->m_CSGDesitnationCombo.GetSelectedBrushEntity();
- if (penBrush==NULL) {
- return NULL;
- }
- // get entity's brush
- CBrush3D *pbrBrush = penBrush->GetBrush();
- if( pbrBrush == NULL) {
- return NULL;
- }
- // get currently active mip factor
- FLOAT fCurrentMipFactor = GetCurrentlyActiveMipFactor();
- return pbrBrush->GetBrushMipByDistance(fCurrentMipFactor);
- }
- void CWorldEditorView::OnDeleteMip()
- {
- // remember current time as time when last mip brushing option has been used
- _fLastMipBrushingOptionUsed = _pTimer->GetRealTimeTick();
- CBrushMip *pbmCurrentMip = GetCurrentBrushMip();
- if (pbmCurrentMip==NULL) {
- return;
- }
- // delete currently visible mip brush
- pbmCurrentMip->bm_pbrBrush->DeleteBrushMip(pbmCurrentMip);
- CWorldEditorDoc* pDoc = GetDocument();
- // document has changed
- pDoc->SetModifiedFlag();
- // update all views
- pDoc->UpdateAllViews( NULL);
- // set text describing data that is edited
- SetEditingDataPaneInfo( TRUE);
- }
- void CWorldEditorView::OnPreviousMipBrush()
- {
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CEntity *penBrush = pMainFrame->m_CSGDesitnationCombo.GetSelectedBrushEntity();
- if (penBrush == NULL) return;
- CBrush3D &brBrush = *penBrush->en_pbrBrush;
- // remember current time as time when last mip brushing option has been used
- _fLastMipBrushingOptionUsed = _pTimer->GetRealTimeTick();
- CBrushMip *pbmCurrentMip = GetCurrentBrushMip();
- CBrushMip *pbmPrevMip = NULL;
-
- if (pbmCurrentMip==NULL)
- {
- pbmPrevMip = brBrush.GetLastMip();
- }
- else
- {
- pbmPrevMip = pbmCurrentMip->GetPrev();
- }
- if (pbmPrevMip==NULL) return;
- // set manual mip factor to show previous mip brush
- GetChildFrame()->m_fManualMipBrushingFactor = pbmPrevMip->GetMipDistance()-0.01f;
- // update all views
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->UpdateAllViews( NULL);
- // set text describing data that is edited
- SetEditingDataPaneInfo( TRUE);
- }
- void CWorldEditorView::OnNextMipBrush()
- {
- // remember current time as time when last mip brushing option has been used
- _fLastMipBrushingOptionUsed = _pTimer->GetRealTimeTick();
- CBrushMip *pbmCurrentMip = GetCurrentBrushMip();
- if (pbmCurrentMip==NULL) {
- return;
- }
- CBrushMip *pbmNextMip = pbmCurrentMip->GetNext();
- if (pbmNextMip==NULL) {
- return;
- }
- // set manual mip factor to show next mip brush
- GetChildFrame()->m_fManualMipBrushingFactor = pbmNextMip->GetMipDistance()-0.01f;
- // update all views
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->UpdateAllViews( NULL);
- // set text describing data that is edited
- SetEditingDataPaneInfo( TRUE);
- }
- void CWorldEditorView::OnUpdateCloneToMorePreciseMip(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable( GetCurrentBrushMip()!=NULL && !GetChildFrame()->m_bAutoMipBrushingOn);
- }
- void CWorldEditorView::OnUpdateCloneToRougherMipLevel(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable( GetCurrentBrushMip()!=NULL && !GetChildFrame()->m_bAutoMipBrushingOn);
- }
- void CWorldEditorView::OnUpdateCreateEmptyMorePreciseMip(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable( GetCurrentBrushMip()!=NULL && !GetChildFrame()->m_bAutoMipBrushingOn);
- }
- void CWorldEditorView::OnUpdateCreateEmptyRougherMip(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable( GetCurrentBrushMip()!=NULL && !GetChildFrame()->m_bAutoMipBrushingOn);
- }
- void CWorldEditorView::OnUpdateDeleteMip(CCmdUI* pCmdUI)
- {
- CBrushMip *pbm = GetCurrentBrushMip();
- pCmdUI->Enable(
- pbm!=NULL &&
- pbm->bm_pbrBrush->br_lhBrushMips.Count()>1 &&
- !GetChildFrame()->m_bAutoMipBrushingOn);
- }
- void CWorldEditorView::OnUpdatePreviousMipBrush(CCmdUI* pCmdUI)
- {
- CBrushMip *pbm = GetCurrentBrushMip();
- pCmdUI->Enable(
- ( (pbm==NULL) ||
- (pbm->GetPrev()!=NULL) ) &&
- !GetChildFrame()->m_bAutoMipBrushingOn);
- }
- void CWorldEditorView::OnUpdateNextMipBrush(CCmdUI* pCmdUI)
- {
- CBrushMip *pbm = GetCurrentBrushMip();
- pCmdUI->Enable(
- pbm!=NULL &&
- pbm->GetNext()!=NULL &&
- !GetChildFrame()->m_bAutoMipBrushingOn);
- }
- // paste polygon properties but don't paste mapping
- void CWorldEditorView::OnEditPasteAlternative()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- if( theApp.m_ctLastCopyType == CT_POLYGON_PROPERTIES)
- {
- // if mouse is over polygon
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- if( crRayHit.cr_pbpoBrushPolygon->IsSelected( BPOF_SELECTED))
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- // apply all parameters from remembered
- itbpo->CopyProperties( *theApp.m_pbpoClipboardPolygon);
- }
- }
- else
- {
- // apply all parameters from remembered
- crRayHit.cr_pbpoBrushPolygon->CopyProperties( *theApp.m_pbpoClipboardPolygon);
- }
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag();
- pDoc->UpdateAllViews( NULL);
- }
- if( theApp.m_ctLastCopyType == CT_POLYGON_PROPERTIES_ALTERNATIVE)
- {
- // if mouse is over polygon
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- if( crRayHit.cr_pbpoBrushPolygon->IsSelected( BPOF_SELECTED))
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- // apply all parameters from remembered
- itbpo->CopyProperties( *theApp.m_pbpoClipboardPolygon);
- PasteOneLayerMapping(0, theApp.m_mdMapping1, theApp.m_plMapping1, &*itbpo, TRUE);
- PasteOneLayerMapping(1, theApp.m_mdMapping2, theApp.m_plMapping2, &*itbpo, TRUE);
- PasteOneLayerMapping(2, theApp.m_mdMapping3, theApp.m_plMapping3, &*itbpo, TRUE);
- }
- }
- else
- {
- // apply all parameters from remembered
- crRayHit.cr_pbpoBrushPolygon->CopyProperties( *theApp.m_pbpoClipboardPolygon);
- PasteOneLayerMapping(0, theApp.m_mdMapping1, theApp.m_plMapping1, crRayHit.cr_pbpoBrushPolygon, TRUE);
- PasteOneLayerMapping(1, theApp.m_mdMapping2, theApp.m_plMapping2, crRayHit.cr_pbpoBrushPolygon, TRUE);
- PasteOneLayerMapping(2, theApp.m_mdMapping3, theApp.m_plMapping3, crRayHit.cr_pbpoBrushPolygon, TRUE);
- }
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag();
- pDoc->UpdateAllViews( NULL);
- }
- else if (theApp.m_ctLastCopyType == CT_ENTITY)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CPlacement3D plPaste = GetMouseInWorldPlacement();
- // load world from clipboard file and start template CSG
- pDoc->StartTemplateCSG( plPaste, (CTString)"Temp\\ClipboardEntityWorld.wld");
- // update all views
- pDoc->UpdateAllViews( NULL);
- }
- }
- void CWorldEditorView::OnUpdateEditPasteAlternative(CCmdUI* pCmdUI)
- {
- }
- void CWorldEditorView::ToggleHittedPolygon( CCastRay &crRayHit)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( (crRayHit.cr_penHit == NULL) ||
- (crRayHit.cr_pbpoBrushPolygon == NULL) )
- {
- return;
- }
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- // remember if first clicked polygon is to be deselected
- m_bWeDeselectedFirstPolygon = crRayHit.cr_pbpoBrushPolygon->IsSelected( BPOF_SELECTED) != 0;
- INDEX ctPolygonsSelectedBefore = pDoc->m_selPolygonSelection.Count();
- // if shift is not pressed
- if( !bShift)
- {
- if( ctPolygonsSelectedBefore>1)
- {
- m_bWeDeselectedFirstPolygon = FALSE;
- }
- // deselect all selected polygons
- pDoc->m_selPolygonSelection.Clear();
- }
- // if we have to deselect first polygon but we didn't deselect it with clear
- if( (m_bWeDeselectedFirstPolygon) &&
- (crRayHit.cr_pbpoBrushPolygon->IsSelected( BPOF_SELECTED)) )
- {
- // deselect clicked polygon
- pDoc->m_selPolygonSelection.Deselect( *crRayHit.cr_pbpoBrushPolygon);
- }
- // if we must select first polygon
- if( !m_bWeDeselectedFirstPolygon)
- {
- // select it
- pDoc->m_selPolygonSelection.Select( *crRayHit.cr_pbpoBrushPolygon);
- }
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- // update all views
- pDoc->UpdateAllViews( this);
- }
- void CWorldEditorView::ToggleHittedSector( CCastRay &crRayHit)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // if any polygon hit toggle or add its sector
- if( (crRayHit.cr_penHit == NULL) ||
- (crRayHit.cr_pbscBrushSector == NULL) )
- {
- return;
- }
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- // remember if first clicked sector is to be deselected
- m_bWeDeselectedFirstSector = crRayHit.cr_pbscBrushSector->IsSelected( BSCF_SELECTED) != 0;
- INDEX ctSectorsSelectedBefore = pDoc->m_selSectorSelection.Count();
- // if shift is not pressed
- if( !bShift)
- {
- if( ctSectorsSelectedBefore>1)
- {
- m_bWeDeselectedFirstSector = FALSE;
- }
- // deselect all selected sectors
- pDoc->m_selSectorSelection.Clear();
- }
- // if we have to deselect first sector but we didn't deselect it with clear
- if( (m_bWeDeselectedFirstSector) &&
- (crRayHit.cr_pbscBrushSector->IsSelected( BSCF_SELECTED)) )
- {
- // deselect clicked sector
- pDoc->m_selSectorSelection.Deselect( *crRayHit.cr_pbscBrushSector);
- }
- // if we must select first sector
- if( !m_bWeDeselectedFirstSector)
- {
- // select it
- pDoc->m_selSectorSelection.Select( *crRayHit.cr_pbscBrushSector);
- }
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- // update all views
- pDoc->UpdateAllViews( this);
- }
- void CWorldEditorView::OnSelectAllEntitiesInWorld()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // deselect all entities
- pDoc->m_selEntitySelection.Clear();
- // add each entity in world
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- CBrushSector *pbscSector = iten->GetFirstSector();
- BOOL bSectorVisible = (pbscSector == NULL) ||
- !(pbscSector->bsc_ulFlags & BSCF_HIDDEN);
- // if it isn't classified in hidden sector and is not hidden itself
- if( bSectorVisible && !(iten->en_ulFlags&ENF_HIDDEN))
- {
- // add it to selection
- pDoc->m_selEntitySelection.Select( *iten);
- }
- }
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- // update all views
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnSelectSectorsWithSameName()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( m_pbpoRightClickedPolygon == NULL) return;
- // select all sectors in world with same name
- CBrushSector *pbscSrc = m_pbpoRightClickedPolygon->bpo_pbscSector;
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- CEntity::RenderType rt = iten->GetRenderType();
- if (rt==CEntity::RT_BRUSH || rt==CEntity::RT_FIELDBRUSH)
- {
- // for each mip in its brush
- FOREACHINLIST(CBrushMip, bm_lnInBrush, iten->GetBrush()->br_lhBrushMips, itbm)
- {
- // for all sectors in this mip
- FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc)
- {
- // if sector is not hidden and has same name, select it
- if( !(itbsc->bsc_ulFlags & BSCF_HIDDEN) &&
- (itbsc->bsc_strName==pbscSrc->bsc_strName) )
- {
- if( !itbsc->IsSelected( BSCF_SELECTED))
- {
- pDoc->m_selSectorSelection.Select( *itbsc);
- }
- }
- }
- }
- }
- }
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- // update all views
- pDoc->UpdateAllViews( this);
- }
- void CWorldEditorView::OnSelectSectorsArroundEntity()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- // if none selected
- if(pDoc->m_selEntitySelection.Count() == 0)
- {
- // perform on ray-hitted entity
- BOOL bHitModels = pDoc->GetEditingMode() != POLYGON_MODE;
- BOOL bHitFields = pDoc->GetEditingMode() == ENTITY_MODE;
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse, FALSE, bHitModels, bHitFields);
- // if none of entities is hitted
- if(crRayHit.cr_penHit == NULL) return;
- {FOREACHSRCOFDST(crRayHit.cr_penHit->en_rdSectors, CBrushSector, bsc_rsEntities, pbsc)
- // if sector is not hidden and not selected
- if( !(pbsc->bsc_ulFlags & BSCF_HIDDEN) && !pbsc->IsSelected( BSCF_SELECTED) )
- {
- // select it
- pDoc->m_selSectorSelection.Select( *pbsc);
- }
- ENDFOR}
- }
- else
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- {FOREACHSRCOFDST(iten->en_rdSectors, CBrushSector, bsc_rsEntities, pbsc)
- // if sector is not hidden and not selected
- if( !(pbsc->bsc_ulFlags & BSCF_HIDDEN) && !pbsc->IsSelected( BSCF_SELECTED) )
- {
- // select it
- pDoc->m_selSectorSelection.Select( *pbsc);
- }
- ENDFOR}
- }
- }
- pDoc->SetEditingMode( SECTOR_MODE);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnSelectSectorsArroundEntityOnContext()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- if( m_penEntityHitOnContext == NULL)
- {
- return;
- }
- // perform select sectors on whole entity selection
- if( m_penEntityHitOnContext->IsSelected( ENF_SELECTED))
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- {FOREACHSRCOFDST(iten->en_rdSectors, CBrushSector, bsc_rsEntities, pbsc)
- // if sector is not hidden and not selected
- if( !(pbsc->bsc_ulFlags & BSCF_HIDDEN) && !pbsc->IsSelected( BSCF_SELECTED) )
- {
- // select it
- pDoc->m_selSectorSelection.Select( *pbsc);
- }
- ENDFOR}
- }
- }
- else
- {
- {FOREACHSRCOFDST(m_penEntityHitOnContext->en_rdSectors, CBrushSector, bsc_rsEntities, pbsc)
- // if sector is not hidden and not selected
- if( !(pbsc->bsc_ulFlags & BSCF_HIDDEN) && !pbsc->IsSelected( BSCF_SELECTED) )
- {
- // select it
- pDoc->m_selSectorSelection.Select( *pbsc);
- }
- ENDFOR}
- }
- pDoc->SetEditingMode( SECTOR_MODE);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::CopySectorAmbient( CBrushSector *pbscSector)
- {
- theApp.m_colSectorAmbientClipboard = pbscSector->bsc_colAmbient;
- }
- void CWorldEditorView::PasteSectorAmbient( CBrushSector *pbscSector)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( (pbscSector == NULL) || (pbscSector->IsSelected( BSCF_SELECTED)) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selSectorSelection, CBrushSector, itbsc)
- {
- itbsc->bsc_colAmbient = theApp.m_colSectorAmbientClipboard;
- itbsc->UncacheLightMaps();
- }
- }
- else
- {
- pbscSector->bsc_colAmbient = theApp.m_colSectorAmbientClipboard;
- pbscSector->UncacheLightMaps();
- }
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::PasteTexture( CBrushPolygon *pbpoPolygon)
- {
- if( theApp.m_ptdActiveTexture==NULL) return;
- CWorldEditorDoc* pDoc = GetDocument();
- CTFileName fnTextureName = theApp.m_ptdActiveTexture->GetName();
- try
- {
- if( (pbpoPolygon == NULL) || (pbpoPolygon->IsSelected( BPOF_SELECTED)) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.SetData_t( fnTextureName);
- }
- }
- else
- {
- pbpoPolygon->bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.SetData_t( fnTextureName);
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag( TRUE);
- }
- catch( char *strError)
- {
- AfxMessageBox( CString(strError));
- return;
- }
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::StorePolygonSelection(CBrushPolygonSelection &selPolygons,
- CDynamicContainer<CBrushPolygon> &dcPolygons)
- {
- dcPolygons.Clear();
- FOREACHINDYNAMICCONTAINER( selPolygons, CBrushPolygon, itbpo)
- {
- dcPolygons.Add( itbpo);
- }
- }
- void CWorldEditorView::RestorePolygonSelection(CBrushPolygonSelection &selPolygons,
- CDynamicContainer<CBrushPolygon> &dcPolygons)
- {
- selPolygons.Clear();
- FOREACHINDYNAMICCONTAINER( dcPolygons, CBrushPolygon, itbpo)
- {
- selPolygons.Select( *itbpo);
- }
- }
- void CWorldEditorView::DiscardShadows( CEntity *penEntity)
- {
- CWorldEditorDoc* pDoc = GetDocument();
-
- CDynamicContainer<CBrushPolygon> dcPolygons;
- StorePolygonSelection( pDoc->m_selPolygonSelection, dcPolygons);
- pDoc->m_selPolygonSelection.Clear();
- FLOATaabbox3D boxForDiscard;
- if( (penEntity == NULL) || (penEntity->IsSelected( ENF_SELECTED)) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- // if it is brush
- if (iten->en_RenderType == CEntity::RT_BRUSH)
- {
- // for each mip in its brush
- FOREACHINLIST(CBrushMip, bm_lnInBrush, iten->en_pbrBrush->br_lhBrushMips, itbm)
- {
- // for all sectors in this mip
- FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc)
- {
- // for all polygons in sector
- FOREACHINSTATICARRAY(itbsc->bsc_abpoPolygons, CBrushPolygon, itbpo)
- {
- boxForDiscard |= itbpo->bpo_boxBoundingBox;
- itbpo->bpo_smShadowMap.DiscardAllLayers();
- itbpo->InitializeShadowMap();
- pDoc->m_selPolygonSelection.Select( *itbpo);
- }
- itbsc->UncacheLightMaps();
- }
- }
- }
- }
- }
- else
- {
- // if it is brush
- if (penEntity->en_RenderType == CEntity::RT_BRUSH)
- {
- // for each mip in its brush
- FOREACHINLIST(CBrushMip, bm_lnInBrush, penEntity->en_pbrBrush->br_lhBrushMips, itbm)
- {
- // for all sectors in this mip
- FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc)
- {
- // for all polygons in sector
- FOREACHINSTATICARRAY(itbsc->bsc_abpoPolygons, CBrushPolygon, itbpo)
- {
- boxForDiscard |= itbpo->bpo_boxBoundingBox;
- itbpo->bpo_smShadowMap.DiscardAllLayers();
- itbpo->InitializeShadowMap();
- pDoc->m_selPolygonSelection.Select( *itbpo);
- }
- itbsc->UncacheLightMaps();
- }
- }
- }
- }
- pDoc->m_woWorld.FindShadowLayers( boxForDiscard, TRUE);
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- RestorePolygonSelection( pDoc->m_selPolygonSelection, dcPolygons);
- }
- void CWorldEditorView::DiscardShadows( CBrushSector *pbscSector)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CDynamicContainer<CBrushPolygon> dcPolygons;
- StorePolygonSelection( pDoc->m_selPolygonSelection, dcPolygons);
- pDoc->m_selPolygonSelection.Clear();
- FLOATaabbox3D boxForDiscard;
- if( (pbscSector == NULL) || (pbscSector->IsSelected( BSCF_SELECTED)) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selSectorSelection, CBrushSector, itbsc)
- {
- FOREACHINSTATICARRAY(itbsc->bsc_abpoPolygons, CBrushPolygon, itbpo)
- {
- boxForDiscard |= itbpo->bpo_boxBoundingBox;
- itbpo->bpo_smShadowMap.DiscardAllLayers();
- itbpo->InitializeShadowMap();
- pDoc->m_selPolygonSelection.Select( *itbpo);
- }
- itbsc->UncacheLightMaps();
- }
- }
- else
- {
- FOREACHINSTATICARRAY(pbscSector->bsc_abpoPolygons, CBrushPolygon, itbpo)
- {
- boxForDiscard |= itbpo->bpo_boxBoundingBox;
- itbpo->bpo_smShadowMap.DiscardAllLayers();
- itbpo->InitializeShadowMap();
- pDoc->m_selPolygonSelection.Select( *itbpo);
- }
- pbscSector->UncacheLightMaps();
- }
- pDoc->m_woWorld.FindShadowLayers( boxForDiscard, TRUE);
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- RestorePolygonSelection( pDoc->m_selPolygonSelection, dcPolygons);
- }
- void CWorldEditorView::DiscardShadows( CBrushPolygon *pbpoPolygon)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CDynamicContainer<CBrushPolygon> dcPolygons;
- StorePolygonSelection( pDoc->m_selPolygonSelection, dcPolygons);
- FLOATaabbox3D boxForDiscard;
- if( (pbpoPolygon == NULL) || (pbpoPolygon->IsSelected( BPOF_SELECTED)) )
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- // calculate bounding box for all polygons
- boxForDiscard |= itbpo->bpo_boxBoundingBox;
- itbpo->bpo_smShadowMap.DiscardAllLayers();
- itbpo->InitializeShadowMap();
- }
- }
- else
- {
- pbpoPolygon->bpo_smShadowMap.DiscardAllLayers();
- pbpoPolygon->InitializeShadowMap();
- boxForDiscard |= pbpoPolygon->bpo_boxBoundingBox;
- pDoc->m_selPolygonSelection.Clear();
- pDoc->m_selPolygonSelection.Select( *pbpoPolygon);
- }
- pDoc->m_woWorld.FindShadowLayers( boxForDiscard, TRUE);
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- RestorePolygonSelection( pDoc->m_selPolygonSelection, dcPolygons);
- }
- void CWorldEditorView::OnInsertVertex()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- MarkClosestVtxAndEdgeOnPrimitiveBase( m_ptMouse);
- if( m_iDragEdge != -1) pDoc->InsertPrimitiveVertex( m_iDragEdge, m_vMouseDownSecondLayer);
- }
- void CWorldEditorView::OnDeleteVertex()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- MarkClosestVtxAndEdgeOnPrimitiveBase( m_ptMouse);
- if( m_iDragVertice != -1) pDoc->DeletePrimitiveVertex( m_iDragVertice);
- }
- void CWorldEditorView::OnKeyBackslash()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- CPoint ptMouse;
- GetCursorPos( &ptMouse);
- if( theApp.m_iTerrainEditMode==TEM_LAYER)
- {
- CTerrainLayer *ptlLayer=GetLayer();
- if(ptlLayer==NULL) return;
- if( ptlLayer->tl_ltType==LT_TILE)
- {
- InvokeTerrainTilePalette(ptMouse.x, ptMouse.y);
- return;
- }
- }
- InvokeTerrainBrushPalette( ptMouse.x-BRUSH_PALETTE_WIDTH/2, ptMouse.y+BRUSH_PALETTE_HEIGHT/2);
- }
- else
- {
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- if( pDoc->m_selEntitySelection.Count() == 1)
- {
- pDoc->m_selEntitySelection.Lock();
- CEntity *penOnlySelected = &pDoc->m_selEntitySelection[0];
- pDoc->m_selEntitySelection.Unlock();
- CEntity *penToSelect = NULL;
- CPropertyID *ppidProperty = pMainFrame->m_PropertyComboBar.GetSelectedProperty();
- if( ppidProperty == NULL) return;
- if( ppidProperty->pid_eptType == CEntityProperty::EPT_PARENT)
- {
- penToSelect = penOnlySelected->GetParent();
- }
- else if( ppidProperty->pid_eptType == CEntityProperty::EPT_ENTITYPTR)
- {
- // obtain entity class ptr
- CDLLEntityClass *pdecDLLClass = penOnlySelected->GetClass()->ec_pdecDLLClass;
- // for all classes in hierarchy of this entity
- for(;
- pdecDLLClass!=NULL;
- pdecDLLClass = pdecDLLClass->dec_pdecBase) {
- // for all properties
- for(INDEX iProperty=0; iProperty<pdecDLLClass->dec_ctProperties; iProperty++) {
- CEntityProperty &epProperty = pdecDLLClass->dec_aepProperties[iProperty];
- if( (ppidProperty->pid_strName == epProperty.ep_strName) &&
- (ppidProperty->pid_eptType == epProperty.ep_eptType) )
- {
- // get target entity
- penToSelect = ENTITYPROPERTY( &*penOnlySelected, epProperty.ep_slOffset, CEntityPointer);
- }
- }
- }
- }
- if( penToSelect == NULL) return;
- pDoc->m_selEntitySelection.Clear();
- pDoc->m_selEntitySelection.Select( *penToSelect);
- pMainFrame->m_PropertyComboBar.UpdateData( FALSE);
- pDoc->m_chSelections.MarkChanged();
- }
- }
- }
- void CWorldEditorView::OnSavePicturesForEnvironment()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->m_selEntitySelection.Lock();
- CEntity *pen = &pDoc->m_selEntitySelection[0];
- pDoc->m_selEntitySelection.Unlock();
- CTFileName fnName = _EngineGUI.FileRequester( "Save pictures as ...",
- FILTER_TGA FILTER_ALL FILTER_END,"Environment pictures directory", "Textures\\");
- if( fnName == "") return;
- CTFileName fnBase = fnName.NoExt();
- CDrawPort *pdp;
- CImageInfo II;
- CTextureData TD;
- CAnimData AD;
- ULONG flags = NONE;
- CChildFrame *pChild = GetChildFrame();
- // create canvas to render picture
- _pGfx->CreateWorkCanvas( 256, 256, &pdp);
- if( pdp != NULL)
- {
- if( pdp->Lock())
- {
- CViewPrefs vpOld = m_vpViewPrefs;
- // set rendering type for world
- m_vpViewPrefs.m_wrpWorldRenderPrefs.SetHiddenLinesOn( FALSE);
- m_vpViewPrefs.m_wrpWorldRenderPrefs.SetEditorModelsOn( FALSE);
- m_vpViewPrefs.m_wrpWorldRenderPrefs.SetFieldBrushesOn( FALSE);
- m_vpViewPrefs.m_wrpWorldRenderPrefs.SetBackgroundTextureOn( TRUE);
- m_vpViewPrefs.m_wrpWorldRenderPrefs.SetVerticesFillType( CWorldRenderPrefs::FT_NONE);
- m_vpViewPrefs.m_wrpWorldRenderPrefs.SetEdgesFillType( CWorldRenderPrefs::FT_NONE);
- m_vpViewPrefs.m_wrpWorldRenderPrefs.SetPolygonsFillType( CWorldRenderPrefs::FT_TEXTURE);
- m_vpViewPrefs.m_wrpWorldRenderPrefs.SetLensFlaresType( CWorldRenderPrefs::LFT_REFLECTIONS_AND_GLARE);
- // for models
- m_vpViewPrefs.m_mrpModelRenderPrefs.SetRenderType( RT_TEXTURE);
- m_vpViewPrefs.m_mrpModelRenderPrefs.SetShadingType( RT_SHADING_PHONG);
- m_vpViewPrefs.m_mrpModelRenderPrefs.SetShadowQuality( 0);
- m_vpViewPrefs.m_mrpModelRenderPrefs.SetWire( FALSE);
- m_vpViewPrefs.m_mrpModelRenderPrefs.SetHiddenLines( FALSE);
- m_vpViewPrefs.m_mrpModelRenderPrefs.BBoxFrameShow( FALSE);
- m_vpViewPrefs.m_mrpModelRenderPrefs.BBoxAllShow( FALSE);
- // remember old viewer settings
- CPlacement3D plOrgPlacement = pChild->m_mvViewer.mv_plViewer;
- FLOAT fOldTargetDistance = pChild->m_mvViewer.mv_fTargetDistance;
- enum CSlaveViewer::ProjectionType ptOld = m_ptProjectionType;
- m_ptProjectionType = CSlaveViewer::PT_PERSPECTIVE;
- // set new viewer settings
- pChild->m_mvViewer.mv_plViewer = pen->GetPlacement();
- pChild->m_mvViewer.mv_fTargetDistance = 10.0f;
- #define GRAB_BCG( ext, angDelta) \
- pChild->m_mvViewer.mv_plViewer = pen->GetPlacement();\
- pChild->m_mvViewer.mv_plViewer.pl_OrientationAngle+=angDelta;\
- RenderView( pdp);\
- pdp->GrabScreen(II);\
- try { II.SaveTGA_t( fnBase+ext); } \
- catch (char *strError)\
- { AfxMessageBox(CString(strError)); }
- GRAB_BCG( "N.tga", ANGLE3D( 0, 0, 0));
- GRAB_BCG( "W.tga", ANGLE3D( 90.0f, 0, 0));
- GRAB_BCG( "S.tga", ANGLE3D( 180.0f, 0, 0));
- GRAB_BCG( "E.tga", ANGLE3D( -90.0f, 0, 0));
- GRAB_BCG( "C.tga", ANGLE3D( 0, 90.0f, 0));
- GRAB_BCG( "F.tga", ANGLE3D( 0, -90.0f, 0));
- // restore original settings
- m_ptProjectionType = ptOld;
- pChild->m_mvViewer.mv_plViewer = plOrgPlacement;
- pChild->m_mvViewer.mv_fTargetDistance = fOldTargetDistance;
- m_vpViewPrefs = vpOld;
- pdp->Unlock();
- }
- _pGfx->DestroyWorkCanvas( pdp);
- pdp = NULL;
- }
- }
- void CWorldEditorView::OnUpdateSavePicturesForEnvironment(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pCmdUI->Enable( pDoc->m_selEntitySelection.Count() == 1);
- }
- BOOL CWorldEditorView::OnEraseBkgnd(CDC* pDC)
- {
- return TRUE;
- }
- void CWorldEditorView::OnMenuAlignMappingU()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->m_selPolygonSelection.Count() == 0) return;
- FLOAT fLastU = 0;
- // for each selected polygon
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo) {
- CBrushPolygon &bpo = *itbpo;
- CMappingDefinition &md = bpo.bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping;
- // find min and max u for the polygon
- md.md_fUOffset = 0;
- FLOAT fMinU = UpperLimit(0.0f);
- FLOAT fMaxU = LowerLimit(0.0f);
- for(INDEX ibpe=0; ibpe<bpo.bpo_abpePolygonEdges.Count(); ibpe++) {
- CBrushPolygonEdge &bpe = bpo.bpo_abpePolygonEdges[ibpe];
- FLOAT3D v0, v1;
- MEX2D(vTex0);
- bpe.GetVertexCoordinatesRelative(v0, v1);
- md.GetTextureCoordinates(
- bpo.bpo_pbplPlane->bpl_pwplWorking->wpl_mvRelative, v0, vTex0);
- FLOAT fU = vTex0(1)/1024.0f;
- fMinU = Min(fMinU, fU);
- fMaxU = Max(fMaxU, fU);
- }
- // add the offsets to its mapping
- md.md_fUOffset=fMinU-fLastU;
- fLastU += fMaxU-fMinU;
- }
- CPrintF("Total length u: %fm\n", fLastU);
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnKeyCtrlShiftK()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- ApplyRndNoiseOntoTerrain();
- }
- else
- {
- OnMenuAlignMappingV();
- }
- }
- void CWorldEditorView::OnMenuAlignMappingV()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->m_selPolygonSelection.Count() == 0) return;
- FLOAT fLastV = 0;
- // for each selected polygon
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo) {
- CBrushPolygon &bpo = *itbpo;
- CMappingDefinition &md = bpo.bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping;
- // find min and max v for the polygon
- md.md_fVOffset = 0;
- FLOAT fMinV = UpperLimit(0.0f);
- FLOAT fMaxV = LowerLimit(0.0f);
- for(INDEX ibpe=0; ibpe<bpo.bpo_abpePolygonEdges.Count(); ibpe++) {
- CBrushPolygonEdge &bpe = bpo.bpo_abpePolygonEdges[ibpe];
- FLOAT3D v0, v1;
- MEX2D(vTex0);
- bpe.GetVertexCoordinatesRelative(v0, v1);
- md.GetTextureCoordinates(
- bpo.bpo_pbplPlane->bpl_pwplWorking->wpl_mvRelative, v0, vTex0);
- FLOAT fV = vTex0(2)/1024.0f;
- fMinV = Min(fMinV, fV);
- fMaxV = Max(fMaxV, fV);
- }
- // add the offsets to its mapping
- md.md_fVOffset=fMinV-fLastV;
- fLastV += fMaxV-fMinV;
- }
- CPrintF("Total length v %fm\n", fLastV);
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnDestroy()
- {
- // destroy canvas that is currently used
- _pGfx->DestroyWindowCanvas( m_pvpViewPort);
- m_pvpViewPort = NULL;
- CView::OnDestroy();
- }
- void CWorldEditorView::OnFallDown()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- iten->FallDownToFloor();
- }
- pDoc->UpdateAllViews( NULL);
- pDoc->SetModifiedFlag( TRUE);
- }
- void CWorldEditorView::OnUpdatePrevious(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- // for browsing trough properties
- if( bShift && (pDoc->GetEditingMode() == ENTITY_MODE) && (pDoc->m_selEntitySelection.Count() != 0) )
- {
- pCmdUI->Enable( TRUE);
- }
- else if( (pDoc->GetEditingMode() == POLYGON_MODE) && (pDoc->m_selPolygonSelection.Count() != 0) )
- {
- pCmdUI->Enable( TRUE);
- }
- else if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- pCmdUI->Enable( TRUE);
- }
- else if( (pDoc->m_bBrowseEntitiesMode) || (pDoc->m_cenEntitiesSelectedByVolume.Count()>0) )
- {
- pDoc->OnUpdatePreviousSelectedEntity(pCmdUI);
- }
- else
- {
- OnUpdatePreviousMipBrush( pCmdUI);
- }
- }
- void CWorldEditorView::OnUpdateNext(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- // for browsing trough properties
- if( bShift && (pDoc->GetEditingMode() == ENTITY_MODE) && (pDoc->m_selEntitySelection.Count() != 0) )
- {
- pCmdUI->Enable( TRUE);
- }
- else if( (pDoc->GetEditingMode() == POLYGON_MODE) && (pDoc->m_selPolygonSelection.Count() != 0) )
- {
- pCmdUI->Enable( TRUE);
- }
- else if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- pCmdUI->Enable( TRUE);
- }
- else if( (pDoc->m_bBrowseEntitiesMode) || (pDoc->m_cenEntitiesSelectedByVolume.Count()>0) )
- {
- pDoc->OnUpdateNextSelectedEntity(pCmdUI);
- }
- else
- {
- OnUpdateNextMipBrush( pCmdUI);
- }
- }
- void CWorldEditorView::OnPrevious()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CPropertyComboBar &dlgProperty = pMainFrame->m_PropertyComboBar;
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- BOOL bCtrl = (GetKeyState( VK_CONTROL)&0x8000) != 0;
- // in entity mode use shift to select previous property
- if( (pDoc->GetEditingMode() == ENTITY_MODE) && bShift )
- {
- // shift only is used to select previous empty target property
- if( !bCtrl)
- {
- dlgProperty.SelectPreviousEmptyTarget();
- }
- // ctrl+shift is used to select previous property
- else
- {
- dlgProperty.SelectPreviousProperty();
- }
- }
- else if( (pDoc->GetEditingMode() == POLYGON_MODE) && (pDoc->m_selPolygonSelection.Count() != 0) )
- {
- OnPreviousPolygon();
- }
- else if( (pDoc->m_bBrowseEntitiesMode) || (pDoc->m_cenEntitiesSelectedByVolume.Count()>0) )
- {
- pDoc->OnPreviousSelectedEntity();
- }
- else if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- CTerrainLayer *ptlLayer=GetLayer();
- if(theApp.m_iTerrainEditMode==TEM_LAYER && ptlLayer!=NULL && ptlLayer->tl_ltType==LT_TILE)
- {
- CDynamicContainer<CTileInfo> dcTileInfo;
- INDEX ctTilesPerRaw=0;
- ObtainLayerTileInfo( &dcTileInfo, ptlLayer->tl_ptdTexture, ctTilesPerRaw);
- INDEX ctTiles=dcTileInfo.Count();
- ptlLayer->tl_iSelectedTile= Clamp( ptlLayer->tl_iSelectedTile+INDEX(1), (INDEX)0, INDEX(ctTiles-1) );
- // free allocated tile info structures
- for(INDEX i=0; i<dcTileInfo.Count(); i++)
- {
- delete &dcTileInfo[i];
- }
- dcTileInfo.Clear();
- }
- else
- {
- theApp.m_fCurrentTerrainBrush=ClampUp(theApp.m_fCurrentTerrainBrush+1.0f,FLOAT(CT_BRUSHES-1));
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- }
- }
- else
- {
- OnPreviousMipBrush();
- }
- }
- void CWorldEditorView::OnNext()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CPropertyComboBar &dlgProperty = pMainFrame->m_PropertyComboBar;
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- BOOL bCtrl = (GetKeyState( VK_CONTROL)&0x8000) != 0;
- // in entity mode use shift to select next property
- if( (pDoc->GetEditingMode() == ENTITY_MODE) && bShift )
- {
- // shift only is used to select next empty target property
- if( !bCtrl)
- {
- dlgProperty.SelectNextEmptyTarget();
- }
- // ctrl+shift is used to select next property
- else
- {
- dlgProperty.SelectNextProperty();
- }
- }
- else if( (pDoc->GetEditingMode() == POLYGON_MODE) && (pDoc->m_selPolygonSelection.Count() != 0) )
- {
- OnNextPolygon();
- }
- else if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- CTerrainLayer *ptlLayer=GetLayer();
- if(theApp.m_iTerrainEditMode==TEM_LAYER && ptlLayer!=NULL && ptlLayer->tl_ltType==LT_TILE)
- {
- CDynamicContainer<CTileInfo> dcTileInfo;
- INDEX ctTilesPerRaw=0;
- ObtainLayerTileInfo( &dcTileInfo, ptlLayer->tl_ptdTexture, ctTilesPerRaw);
- INDEX ctTiles=dcTileInfo.Count();
- ptlLayer->tl_iSelectedTile= Clamp( ptlLayer->tl_iSelectedTile-INDEX(1), (INDEX)0, INDEX(ctTiles-1) );
- // free allocated tile info structures
- for(INDEX i=0; i<dcTileInfo.Count(); i++)
- {
- delete &dcTileInfo[i];
- }
- dcTileInfo.Clear();
- }
- else
- {
- theApp.m_fCurrentTerrainBrush=ClampDn(theApp.m_fCurrentTerrainBrush-1.0f,0.0f);
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- }
- }
- else if( (pDoc->m_bBrowseEntitiesMode) || (pDoc->m_cenEntitiesSelectedByVolume.Count()>0) )
- {
- pDoc->OnNextSelectedEntity();
- }
- else
- {
- OnNextMipBrush();
- }
- }
- void CWorldEditorView::OnPreviousPolygon(void)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- pDoc->m_selPolygonSelection.Lock();
- ASSERT( pDoc->m_selPolygonSelection.Count() != 0);
- INDEX iSelectedPolygon=0;
- if( !pDoc->m_selPolygonSelection.IsMember( pDoc->m_pbpoLastCentered))
- {
- pDoc->m_pbpoLastCentered = &pDoc->m_selPolygonSelection[0];
- iSelectedPolygon=0;
- }
- else
- {
- INDEX iCurrent = pDoc->m_selPolygonSelection.Index( pDoc->m_pbpoLastCentered);
- INDEX iNext = (iCurrent+1) % pDoc->m_selPolygonSelection.Count();
- pDoc->m_pbpoLastCentered = &pDoc->m_selPolygonSelection[iNext];
- iSelectedPolygon=iNext;
- }
- AllignPolygon( pDoc->m_pbpoLastCentered);
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CTString strMessage;
- strMessage.PrintF("Polygon %d/%d", iSelectedPolygon, pDoc->m_selPolygonSelection.Count());
- pMainFrame->SetStatusBarMessage( strMessage, STATUS_LINE_PANE, 2);
- pDoc->m_selPolygonSelection.Unlock();
- }
- void CWorldEditorView::OnNextPolygon(void)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- pDoc->m_selPolygonSelection.Lock();
- ASSERT( pDoc->m_selPolygonSelection.Count() != 0);
- INDEX iSelectedPolygon=0;
- if( !pDoc->m_selPolygonSelection.IsMember( pDoc->m_pbpoLastCentered))
- {
- pDoc->m_pbpoLastCentered = &pDoc->m_selPolygonSelection[0];
- iSelectedPolygon=0;
- }
- else
- {
- INDEX iCurrent = pDoc->m_selPolygonSelection.Index( pDoc->m_pbpoLastCentered);
- INDEX iPrev = (iCurrent+pDoc->m_selPolygonSelection.Count()-1) % pDoc->m_selPolygonSelection.Count();
- pDoc->m_pbpoLastCentered = &pDoc->m_selPolygonSelection[iPrev];
- iSelectedPolygon=iPrev;
- }
- AllignPolygon( pDoc->m_pbpoLastCentered);
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CTString strMessage;
- strMessage.PrintF("Polygon %d/%d", iSelectedPolygon, pDoc->m_selPolygonSelection.Count());
- pMainFrame->SetStatusBarMessage( strMessage, STATUS_LINE_PANE, 2);
- pDoc->m_selPolygonSelection.Unlock();
- }
- void CWorldEditorView::OnRemoveUnusedTextures()
- {
- CWorldEditorDoc *pDoc = GetDocument();
-
- try
- {
- // for each entity in the world
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten) {
- // if it is brush entity
- if (iten->en_RenderType == CEntity::RT_BRUSH) {
- // for each mip in its brush
- FOREACHINLIST(CBrushMip, bm_lnInBrush, iten->en_pbrBrush->br_lhBrushMips, itbm) {
- // for all sectors in this mip
- FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc) {
- // for all polygons in sector
- FOREACHINSTATICARRAY(itbsc->bsc_abpoPolygons, CBrushPolygon, itbpo)
- {
- // if it is non translucent portal same texture
- if ( ((itbpo->bpo_ulFlags&BPOF_PORTAL) && !(itbpo->bpo_ulFlags&BPOF_TRANSLUCENT)) &&
- (itbpo->bpo_bppProperties.bpp_uwPretenderDistance==0) )
- {
- itbpo->bpo_abptTextures[0].bpt_toTexture.SetData_t( CTString(""));
- itbpo->bpo_abptTextures[1].bpt_toTexture.SetData_t( CTString(""));
- itbpo->bpo_abptTextures[2].bpt_toTexture.SetData_t( CTString(""));
- }
- }
- }
- }
- }
- }
- }
- // if failed
- catch( char *err_str)
- {
- // report error
- AfxMessageBox( CString(err_str));
- return;
- }
- }
- void CWorldEditorView::OnRotate()
- {
- Rotate(90.0f, 0.0f);
- }
- void CWorldEditorView::OnRotateBack()
- {
- Rotate(-90.0f, 0.0f);
- }
- #define ANGLE_KEY_DELTA 15.0f
- void CWorldEditorView::OnRotateLeft()
- {
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- Rotate(ANGLE_KEY_DELTA, 0.0f, bShift);
- }
- void CWorldEditorView::OnRotateRight()
- {
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- Rotate(-ANGLE_KEY_DELTA, 0.0f, bShift);
- }
- void CWorldEditorView::OnRotateUp()
- {
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- CWorldEditorDoc *pDoc = GetDocument();
- if( (pDoc->m_pwoSecondLayer != NULL) &&
- (pDoc->m_bPrimitiveMode) &&
- (theApp.m_vfpCurrent.vfp_ttTriangularisationType != TT_NONE) )
- {
- OnMoveUp();
- }
- else
- {
- Rotate(0.0f,-ANGLE_KEY_DELTA, bShift);
- }
- }
- void CWorldEditorView::OnRotateDown()
- {
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- CWorldEditorDoc *pDoc = GetDocument();
- if( (pDoc->m_pwoSecondLayer != NULL) &&
- (pDoc->m_bPrimitiveMode) &&
- (theApp.m_vfpCurrent.vfp_ttTriangularisationType != TT_NONE) )
- {
- OnMoveDown();
- }
- else
- {
- Rotate(0.0f,ANGLE_KEY_DELTA, bShift);
- }
- }
- void CWorldEditorView::Rotate( FLOAT fAngleLR, FLOAT fAngleUD, BOOL bSmooth/*=FALSE*/)
- {
- if( bSmooth && Abs(fAngleLR)!=90.0f)
- {
- fAngleLR/=10;
- fAngleUD/=10;
- }
- CWorldEditorDoc *pDoc = GetDocument();
- ANGLE3D a3dForRotation = ANGLE3D(0.0f, 0.0f, 0.0f);
- switch( m_ptProjectionType)
- {
- case CSlaveViewer::PT_ISOMETRIC_FRONT:
- case CSlaveViewer::PT_ISOMETRIC_BACK:
- {
- a3dForRotation(3) = fAngleLR;
- a3dForRotation(2) = fAngleUD;
- break;
- }
- case CSlaveViewer::PT_ISOMETRIC_RIGHT:
- case CSlaveViewer::PT_ISOMETRIC_LEFT:
- {
- a3dForRotation(2) = fAngleLR;
- a3dForRotation(3) = -fAngleUD;
- break;
- }
- default:
- {
- a3dForRotation(1) = fAngleLR;
- a3dForRotation(2) = fAngleUD;
- }
- }
-
- if( (pDoc->GetEditingMode() == POLYGON_MODE))
- {
- if( Abs(fAngleLR)!=90.0f)
- {
- fAngleLR/=50;
- fAngleUD/=50;
- }
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if mouse is over polygon
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- CBrushPolygon &bpo = *crRayHit.cr_pbpoBrushPolygon;
- FLOAT3D vCenter=bpo.bpo_boxBoundingBox.Center();
- vCenter=bpo.bpo_pbplPlane->bpl_plAbsolute.ProjectPoint( vCenter);
- CEntity *pen = bpo.bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush->br_penEntity;
- CSimpleProjection3D pr;
- pr.ObjectPlacementL() = _plOrigin;
- pr.ViewerPlacementL() = pen->GetPlacement();
- pr.Prepare();
- FLOATplane3D vRelative;
- pr.ProjectCoordinate(vCenter, vRelative);
-
- // rotate it
- ANGLE3D angMappingRotation=ANGLE3D(0,0,0);
- angMappingRotation(1)=fAngleLR;
- bpo.bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.Rotate(
- bpo.bpo_pbplPlane->bpl_pwplWorking->wpl_mvRelative,
- vRelative, angMappingRotation(1));
- }
- }
- else if( (pDoc->GetEditingMode() == CSG_MODE))
- {
- pDoc->m_plSecondLayer.pl_OrientationAngle += a3dForRotation;
- }
- else if( (pDoc->GetEditingMode() == ENTITY_MODE))
- {
- CEntity *penBrush = NULL;
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- if (iten->en_RenderType == CEntity::RT_BRUSH) {
- penBrush = &*iten;
- }
- if( !(iten->GetFlags() & ENF_ANCHORED) ||
- GetChildFrame()->m_bAncoredMovingAllowed)
- {
- CPlacement3D plEntity = iten->GetPlacement();
- plEntity.pl_OrientationAngle += a3dForRotation;
- iten->SetPlacement( plEntity);
- }
- }}
- // check for terrain updating
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- CLightSource *pls = iten->GetLightSource();
- if (pls!=NULL)
- {
- // if light is directional
- if(pls->ls_ulFlags &LSF_DIRECTIONAL)
- {
- CTerrain *ptrTerrain=GetTerrain();
- if(ptrTerrain!=NULL) ptrTerrain->UpdateShadowMap();
- }
- }
- }}
- if( penBrush != NULL)
- {
- DiscardShadows( penBrush);
- }
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
-
- void CWorldEditorView::MultiplyMappingOnPolygon( FLOAT fFactor)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if mouse is over polygon
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- CMappingDefinitionUI mdui;
- CBrushPolygon *pbpo = crRayHit.cr_pbpoBrushPolygon;
- pbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.ToUI( mdui);
- mdui.mdui_fUStretch *= fFactor;
- mdui.mdui_fVStretch *= fFactor;
- pbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.FromUI( mdui);
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- }
- void CWorldEditorView::OnSelectVisibleSectors()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- pDoc->m_selSectorSelection.Clear();
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- // don't select for hidden entities
- if( !(iten->en_ulFlags & ENF_HIDDEN))
- {
- continue;
- }
- CEntity::RenderType rt = iten->GetRenderType();
- if (rt==CEntity::RT_BRUSH || rt==CEntity::RT_FIELDBRUSH)
- {
- CBrush3D *pBrush3D = iten->GetBrush();
- if(pBrush3D != NULL)
- {
- FLOAT fCurrentMipFactor = GetCurrentlyActiveMipFactor();
- CBrush3D *pbrBrush = iten->GetBrush();
- if( pbrBrush != NULL)
- {
- CBrushMip *pbmCurrentMip = pbrBrush->GetBrushMipByDistance( fCurrentMipFactor);
- if( pbmCurrentMip != NULL)
- {
- FOREACHINDYNAMICARRAY(pbmCurrentMip->bm_abscSectors, CBrushSector, itbsc)
- {
- if( !(itbsc->bsc_ulFlags & BSCF_HIDDEN))
- {
- // add it to selection
- pDoc->m_selSectorSelection.Select( *itbsc);
- }
- }
- }
- }
- }
- }
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnEditCopyAlternative()
- {
- EditCopy( TRUE);
- }
- /*
- * Draw a line for arrow drawing.
- */
- static inline void DrawArrowLine(CDrawPort &dp, const FLOAT2D &vPoint0,
- const FLOAT2D &vPoint1, COLOR color, ULONG ulLineType)
- {
- PIX x0 = (PIX)vPoint0(1);
- PIX x1 = (PIX)vPoint1(1);
- PIX y0 = (PIX)vPoint0(2);
- PIX y1 = (PIX)vPoint1(2);
- dp.DrawLine(x0, y0, x1, y1, color, ulLineType);
- }
- /*
- * Draw an arrow for debugging edge directions.
- */
- static inline void DrawArrow(CDrawPort &dp, PIX i0, PIX j0, PIX i1, PIX j1, COLOR color,
- ULONG ulLineType)
- {
- FLOAT2D vPoint0 = FLOAT2D((FLOAT)i0, (FLOAT)j0);
- FLOAT2D vPoint1 = FLOAT2D((FLOAT)i1, (FLOAT)j1);
- FLOAT2D vDelta = vPoint1-vPoint0;
- FLOAT fDelta = vDelta.Length();
- FLOAT2D vArrowLen, vArrowWidth;
- if (fDelta>0.01) {
- vArrowLen = vDelta/fDelta*FLOAT(10.0);
- vArrowWidth = vDelta/fDelta*FLOAT(2.0);
- } else {
- vArrowWidth = vArrowLen = FLOAT2D(0.0f, 0.0f);
- }
- // FLOAT3D vArrowLen = vDelta/5.0f;
- // FLOAT3D vArrowWidth = vDelta/30.0f;
- Swap(vArrowWidth(1), vArrowWidth(2));
- //vArrowWidth(2) *= -1.0f;
- DrawArrowLine(dp, vPoint0, vPoint1, color, ulLineType);
- DrawArrowLine(dp, vPoint1-vArrowLen+vArrowWidth, vPoint1, color, ulLineType);
- DrawArrowLine(dp, vPoint1-vArrowLen-vArrowWidth, vPoint1, color, ulLineType);
- //DrawArrowLine(dp, vPoint0+vArrowWidth, vPoint0-vArrowWidth, color, ulLineType);
- }
- void CWorldEditorView::DrawAxis(const PIX2D &pixC, PIX len, COLOR colAxisColor, COLOR colTextColor,
- CTString strU, CTString strV)
- {
- if( strU=="" || strV=="") return;
- // draw arrow-headed axis
- DrawArrow( *m_pdpDrawPort, pixC(1), pixC(2), pixC(1)+len, pixC(2), colAxisColor, _FULL_);
- DrawArrow( *m_pdpDrawPort, pixC(1), pixC(2), pixC(1), pixC(2)-len, colAxisColor, _FULL_);
- // type axis text line
- m_pdpDrawPort->SetFont( _pfdConsoleFont);
- m_pdpDrawPort->SetTextAspect( 1.0f);
- m_pdpDrawPort->SetTextScaling( 1.0f);
- m_pdpDrawPort->PutTextCXY( strU, pixC(1)+len+8, pixC(2), colTextColor);
- m_pdpDrawPort->PutTextCXY( strV, pixC(1), pixC(2)-len-8, colTextColor);
- }
- void CWorldEditorView::DrawArrowAndTypeText( CProjection3D &prProjection,
- const FLOAT3D &v0, const FLOAT3D &v1, COLOR colColor, CTString strText)
- {
- // get transformed end vertices
- FLOAT3D tv0, tv1;
- prProjection.PreClip(v0, tv0);
- prProjection.PreClip(v1, tv1);
- // clip the edge line
- FLOAT3D vClipped0 = tv0;
- FLOAT3D vClipped1 = tv1;
- ULONG ulClipFlags = prProjection.ClipLine(vClipped0, vClipped1);
- // if the edge remains after clipping to front plane
- if (ulClipFlags != LCF_EDGEREMOVED) {
- // project the vertices
- FLOAT3D v3d0, v3d1;
- prProjection.PostClip(vClipped0, v3d0);
- prProjection.PostClip(vClipped1, v3d1);
- // make 2d vertices
- FLOAT2D v2d0, v2d1;
- v2d0(1) = v3d0(1); v2d0(2) = v3d0(2);
- v2d1(1) = v3d1(1); v2d1(2) = v3d1(2);
- if( (Abs(v2d1(1)-v2d0(1)) > 8) || (Abs(v2d1(2)-v2d0(2)) > 8) )
- {
- // draw arrow-headed line between vertices
- DrawArrow( *m_pdpDrawPort, (PIX)v2d0(1), (PIX)v2d0(2),
- (PIX)v2d1(1), (PIX)v2d1(2), colColor, _FULL_);
- // type text over line
- if( strText != "")
- m_pdpDrawPort->PutTextCXY( strText, (v2d0(1)+v2d1(1))/2, (v2d0(2)+v2d1(2))/2);
- }
- }
- }
- void CWorldEditorView::SelectWhoTargets( CDynamicContainer<CEntity> &dcTargetedEntities)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- pDoc->m_selEntitySelection.Clear();
- CEntityProperty *pepSelected = NULL;
- // for each that can be targeted
- FOREACHINDYNAMICCONTAINER(dcTargetedEntities, CEntity, itenTargets)
- {
- // for each entity in world
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- // obtain entity class ptr
- CDLLEntityClass *pdecDLLClass = iten->GetClass()->ec_pdecDLLClass;
- // for all classes in hierarchy of this entity
- for(;pdecDLLClass!=NULL; pdecDLLClass = pdecDLLClass->dec_pdecBase)
- {
- // for all properties
- for(INDEX iProperty=0; iProperty<pdecDLLClass->dec_ctProperties; iProperty++)
- {
- CEntityProperty *pepProperty = &pdecDLLClass->dec_aepProperties[iProperty];
- if( pepProperty->ep_eptType == CEntityProperty::EPT_ENTITYPTR)
- {
- // obtain property ptr
- CEntity *penCurrentPtr = ENTITYPROPERTY( &*iten, pepProperty->ep_slOffset, CEntityPointer);
- if( (penCurrentPtr == &*itenTargets) && !iten->IsSelected( ENF_SELECTED) )
- {
- pepSelected = pepProperty;
- pDoc->m_selEntitySelection.Select( *iten);
- }
- }
- }
- }
- }
- }
- pDoc->m_chSelections.MarkChanged();
-
- // if only one entity targets
- if( pDoc->m_selEntitySelection.Count() == 1)
- {
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- pMainFrame->m_PropertyComboBar.SelectProperty( pepSelected);
- }
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnSelectWhoTargetsOnContext()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- // to hold entities for selecting
- CDynamicContainer<CEntity> dcEntities;
- // if right-clicked on void or selected entity
- if( (m_penEntityHitOnContext == NULL) ||
- (m_penEntityHitOnContext->IsSelected( ENF_SELECTED)) )
- {
- // perform on whole selection
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- dcEntities.Add( iten);
- }}
- }
- else
- {
- // perform only on right-clicked entity
- dcEntities.Add( m_penEntityHitOnContext);
- }
- // select all entities that target ones from dynamic container
- SelectWhoTargets( dcEntities);
- }
- void CWorldEditorView::OnSelectWhoTargets()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- // to hold entities for selecting
- CDynamicContainer<CEntity> dcEntities;
- // perform on whole selection
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- dcEntities.Add( iten);
- }}
- // select all entities that target ones from dynamic container
- SelectWhoTargets( dcEntities);
- }
- void CWorldEditorView::OnSelectAllTargetsOnContext()
- {
- CEntity *pen = m_penEntityHitOnContext;
- if( pen==NULL || pen->IsSelected( ENF_SELECTED))
- {
- SelectAllTargetsOfSelectedEntities();
- return;
- }
- else
- {
- SelectAllTargetsOfEntity(pen);
- }
- }
- void CWorldEditorView::OnSelectAllTargets()
- {
- SelectAllTargetsOfSelectedEntities();
- }
- void CWorldEditorView::SelectAllTargetsOfEntity(CEntity *pen)
- {
- ASSERT( pen!= NULL);
- CWorldEditorDoc *pDoc = GetDocument();
- // obtain entity class ptr
- CDLLEntityClass *pdecDLLClass = pen->GetClass()->ec_pdecDLLClass;
- // to hold entities for selecting
- CDynamicContainer<CEntity> dcEntities;
- // for all classes in hierarchy of this entity
- for(;pdecDLLClass!=NULL; pdecDLLClass = pdecDLLClass->dec_pdecBase)
- {
- // for all properties
- for(INDEX iProperty=0; iProperty<pdecDLLClass->dec_ctProperties; iProperty++)
- {
- CEntityProperty &epProperty = pdecDLLClass->dec_aepProperties[iProperty];
- if( epProperty.ep_eptType == CEntityProperty::EPT_ENTITYPTR &&
- epProperty.ep_strName!=NULL &&
- CTString(epProperty.ep_strName)!="")
- {
- // obtain property ptr
- CEntity *penTarget = ENTITYPROPERTY( &*pen, epProperty.ep_slOffset, CEntityPointer);
- if( penTarget != NULL)
- {
- // add it to container
- dcEntities.Add( penTarget);
- }
- }
- }
- }
- // for all entities in dynamic container
- FOREACHINDYNAMICCONTAINER(dcEntities, CEntity, iten)
- {
- // if not yet selected
- if( !iten->IsSelected( ENF_SELECTED))
- {
- // select it
- pDoc->m_selEntitySelection.Select( *iten);
- }
- }
-
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::SelectAllTargetsOfSelectedEntities(void)
- {
- CWorldEditorDoc *pDoc = GetDocument();
- // to hold entities for selecting
- CDynamicContainer<CEntity> dcEntities;
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- // obtain entity class ptr
- CDLLEntityClass *pdecDLLClass = iten->GetClass()->ec_pdecDLLClass;
- // for all classes in hierarchy of this entity
- for(;pdecDLLClass!=NULL; pdecDLLClass = pdecDLLClass->dec_pdecBase)
- {
- // for all properties
- for(INDEX iProperty=0; iProperty<pdecDLLClass->dec_ctProperties; iProperty++)
- {
- CEntityProperty &epProperty = pdecDLLClass->dec_aepProperties[iProperty];
- if(epProperty.ep_eptType==CEntityProperty::EPT_ENTITYPTR &&
- epProperty.ep_strName!=NULL &&
- CTString(epProperty.ep_strName)!="")
- {
- // obtain property ptr
- CEntity *penTarget = ENTITYPROPERTY( &*iten, epProperty.ep_slOffset, CEntityPointer);
- if( penTarget != NULL)
- {
- // add it to container
- dcEntities.Add( penTarget);
- }
- }
- }
- }
- }}
- // for all entities in dynamic container
- FOREACHINDYNAMICCONTAINER( dcEntities, CEntity, iten)
- {
- // if not yet selected
- if( !iten->IsSelected( ENF_SELECTED))
- {
- // select it
- pDoc->m_selEntitySelection.Select( *iten);
- }
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- return;
- }
- void CWorldEditorView::OnSelectInvalidTris()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- // for each entity in the world
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten) {
- // if it is brush entity
- if (iten->en_RenderType == CEntity::RT_BRUSH) {
- // for each mip in its brush
- FOREACHINLIST(CBrushMip, bm_lnInBrush, iten->en_pbrBrush->br_lhBrushMips, itbm) {
- // for all sectors in this mip
- FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc) {
- // for all polygons in sector
- FOREACHINSTATICARRAY(itbsc->bsc_abpoPolygons, CBrushPolygon, itbpo) {
- // if it has invalid triangles
- if ((itbpo->bpo_ulFlags&BPOF_INVALIDTRIANGLES)&&
- !(itbpo->IsSelected(BPOF_SELECTED))) {
- // select it
- pDoc->m_selPolygonSelection.Select( *itbpo);
- }
- }
- }
- }
- }
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- BOOL CWorldEditorView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
- {
- INDEX iCount = zDelta/120;
- BOOL bSpace = (GetKeyState( ' ') & 128) != 0;
- BOOL bCtrl = nFlags & MK_CONTROL;
- BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0;
- BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
- CWorldEditorDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- // ctrl + mouse wheel toggle modes
- /*
- if( bCtrl && !bSpace && !bShift && !bAlt)
- {
- for( INDEX iKnee=0; iKnee<Abs(iCount); iKnee++)
- {
- if(iCount<0)
- {
- switch(pDoc->GetEditingMode())
- {
- case( ENTITY_MODE):
- {
- pDoc->SetEditingMode( SECTOR_MODE);
- break;
- }
- case( SECTOR_MODE):
- {
- pDoc->SetEditingMode( POLYGON_MODE);
- break;
- }
- case( POLYGON_MODE):
- {
- pDoc->SetEditingMode( VERTEX_MODE);
- break;
- }
- case( VERTEX_MODE):
- {
- pDoc->SetEditingMode( TERRAIN_MODE);
- break;
- }
- case( TERRAIN_MODE):
- {
- pDoc->SetEditingMode( ENTITY_MODE);
- break;
- }
- }
- }
- else
- {
- switch(pDoc->GetEditingMode())
- {
- case( ENTITY_MODE):
- {
- pDoc->SetEditingMode( TERRAIN_MODE);
- break;
- }
- case( SECTOR_MODE):
- {
- pDoc->SetEditingMode( ENTITY_MODE);
- break;
- }
- case( POLYGON_MODE):
- {
- pDoc->SetEditingMode( SECTOR_MODE);
- break;
- }
- case( VERTEX_MODE):
- {
- pDoc->SetEditingMode( POLYGON_MODE);
- break;
- }
- case( TERRAIN_MODE):
- {
- pDoc->SetEditingMode( VERTEX_MODE);
- break;
- }
- }
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- }
- */
- // space+ctrl+lmb zoomes in 2x
- if( bSpace && bCtrl)
- {
- BOOL bHitModels = (pDoc->GetEditingMode() == ENTITY_MODE) || bSpace;
- BOOL bHitFields = (pDoc->GetEditingMode() == ENTITY_MODE) || bSpace;
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse, FALSE, bHitModels, bHitFields);
- // set new target
- GetChildFrame()->m_mvViewer.SetTargetPlacement( crRayHit.cr_vHit);
- // move mouse to center of screen
- CPoint ptCenter = CPoint( m_pdpDrawPort->GetWidth()/2, m_pdpDrawPort->GetHeight()/2);
- ClientToScreen( &ptCenter);
- SetCursorPos(ptCenter.x, ptCenter.y);
- OnZoomMore();
- pDoc->UpdateAllViews( NULL);
- m_ptMouseDown = ptCenter;
- for( INDEX iKnee=0; iKnee<Abs(iCount); iKnee++)
- {
- if(iCount<0) OnZoomLess();
- else OnZoomMore();
- }
- }
- else
- {
- for( INDEX iKnee=0; iKnee<Abs(iCount); iKnee++)
- {
- if(iCount<0) PostMessage( WM_COMMAND, ID_PREVIOUS, 0);
- else PostMessage( WM_COMMAND, ID_NEXT, 0);
- }
- }
- return CView::OnMouseWheel(nFlags, zDelta, pt);
- }
- void CWorldEditorView::OnSelectSectorsOtherSide()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon->bpo_ulFlags & BPOF_PORTAL))
- {
- CBrushPolygon &bpo = *crRayHit.cr_pbpoBrushPolygon;
- // for all sectors behind portal
- {FOREACHDSTOFSRC(bpo.bpo_rsOtherSideSectors, CBrushSector, bsc_rdOtherSidePortals, pbsc)
- if( !pbsc->IsSelected( BSCF_SELECTED))
- {
- pDoc->m_selSectorSelection.Select( *pbsc);
- }
- ENDFOR}
-
- pDoc->SetEditingMode( SECTOR_MODE);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- }
- void CWorldEditorView::OnSelectLinksToSector()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL))
- {
- CBrushSector &bsc = *crRayHit.cr_pbpoBrushPolygon->bpo_pbscSector;
- // for all sectors behind portal
- {FOREACHSRCOFDST(bsc.bsc_rdOtherSidePortals, CBrushPolygon, bpo_rsOtherSideSectors, pbpo)
- if( !pbpo->IsSelected( BPOF_SELECTED))
- {
- pDoc->m_selPolygonSelection.Select( *pbpo);
- }
- ENDFOR}
-
- pDoc->SetEditingMode( POLYGON_MODE);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- }
- void CWorldEditorView::OnRemainSelectedByOrientation()
- {
- OnRemainSelectedByOrientation(TRUE);
- }
- void CWorldEditorView::OnRemainSelectedbyOrientationSingle()
- {
- OnRemainSelectedByOrientation(FALSE);
- }
- void CWorldEditorView::OnRemainSelectedByOrientation(BOOL bBothSides)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- CBrushPolygon *pbpoPolygon = crRayHit.cr_pbpoBrushPolygon;
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (pbpoPolygon != NULL) )
- {
- FLOAT3D vReference = pbpoPolygon->bpo_pbplPlane->bpl_plAbsolute;
- // copy polygon selection to container
- CDynamicContainer<CBrushPolygon> dcTemp;
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- dcTemp.Add( itbpo);
- }}
- pDoc->m_selPolygonSelection.Clear();
- {FOREACHINDYNAMICCONTAINER( dcTemp, CBrushPolygon, itbpo)
- {
- FLOAT fCos;
- if( bBothSides)
- {
- fCos = Abs(vReference % itbpo->bpo_pbplPlane->bpl_plAbsolute);
- }
- else
- {
- fCos = vReference % itbpo->bpo_pbplPlane->bpl_plAbsolute;
- }
- if( fCos > CosFast(360.0f/8.0f))
- {
- pDoc->m_selPolygonSelection.Select( *itbpo);
- }
- }}
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- }
- void CWorldEditorView::OnDeselectByOrientation()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- CBrushPolygon *pbpoPolygon = crRayHit.cr_pbpoBrushPolygon;
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (pbpoPolygon != NULL) )
- {
- FLOAT3D vReference = pbpoPolygon->bpo_pbplPlane->bpl_plAbsolute;
- // copy polygon selection to container
- CDynamicContainer<CBrushPolygon> dcTemp;
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- dcTemp.Add( itbpo);
- }}
- pDoc->m_selPolygonSelection.Clear();
- {FOREACHINDYNAMICCONTAINER( dcTemp, CBrushPolygon, itbpo)
- {
- FLOAT fCos = Abs(vReference % itbpo->bpo_pbplPlane->bpl_plAbsolute);
- if( fCos < CosFast(360.0f/8.0f))
- {
- pDoc->m_selPolygonSelection.Select( *itbpo);
- }
- }}
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- }
- void CWorldEditorView::OnReoptimizeBrushes()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CWaitCursor wc;
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- pDoc->ClearSelections();
- pDoc->m_chSelections.MarkChanged();
- CEntity *penEntityHit = crRayHit.cr_penHit;
- BOOL bSelected = crRayHit.cr_penHit->IsSelected( ENF_SELECTED);
- if( bSelected && (pDoc->GetEditingMode() == ENTITY_MODE))
- {
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- if (iten->en_RenderType == CEntity::RT_BRUSH)
- {
- CBrush3D *pbrBrush = iten->GetBrush();
- // for each mip in the brush
- FOREACHINLIST(CBrushMip, bm_lnInBrush, pbrBrush->br_lhBrushMips, itbm)
- {
- // reoptimize it
- itbm->Reoptimize();
- }
- DiscardShadows( &*iten);
- if( iten->GetFlags() & ENF_ZONING)
- {
- pbrBrush->SwitchToZoning();
- }
- else
- {
- pbrBrush->SwitchToNonZoning();
- }
- }
- }}
- }
- else
- {
- if (penEntityHit->en_RenderType == CEntity::RT_BRUSH)
- {
- CBrush3D *pbrBrush = penEntityHit->GetBrush();
- // for each mip in the brush
- FOREACHINLIST(CBrushMip, bm_lnInBrush, pbrBrush->br_lhBrushMips, itbm)
- {
- // reoptimize it
- itbm->Reoptimize();
- }
- DiscardShadows( penEntityHit);
- if( penEntityHit->GetFlags() & ENF_ZONING)
- {
- pbrBrush->SwitchToZoning();
- }
- else
- {
- pbrBrush->SwitchToNonZoning();
- }
- }
- }
- // automaticly update portal links
- pDoc->m_woWorld.RebuildLinks();
- pDoc->UpdateAllViews( NULL);
- pDoc->SetModifiedFlag();
- }
- // ray-hit didn't hit any entity, reoptimize the whole world
- else
- {
- // for each entity in the world
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- // if it is brush entity
- if (iten->en_RenderType == CEntity::RT_BRUSH)
- {
- CBrush3D *pbrBrush = iten->GetBrush();
- // for each mip in the brush
- FOREACHINLIST(CBrushMip, bm_lnInBrush, pbrBrush->br_lhBrushMips, itbm)
- {
- // reoptimize it
- itbm->Reoptimize();
- }
- DiscardShadows( iten);
- if( iten->GetFlags() & ENF_ZONING)
- {
- pbrBrush->SwitchToZoning();
- }
- else
- {
- pbrBrush->SwitchToNonZoning();
- }
- }
- }
- }
- }
- void CWorldEditorView::OnMergeVertices()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pDoc->RememberUndo();
- pDoc->ClearSelections( ST_VERTEX);
- CDynamicContainer<CBrushVertex> cbvxAllreadyDone;
- DOUBLE3D vMergeToVertex;
- {FOREACHINDYNAMICCONTAINER( pDoc->m_selVertexSelection, CBrushVertex, itbvx)
- {
- vMergeToVertex = FLOATtoDOUBLE(itbvx->bvx_vAbsolute);
- }}
- // deselect vertices that are on right spot, to avoid unnecessary triangularisation
- {FOREACHINDYNAMICCONTAINER( pDoc->m_selVertexSelection, CBrushVertex, itbvx)
- {
- if( FLOATtoDOUBLE(itbvx->bvx_vAbsolute) == vMergeToVertex)
- {
- cbvxAllreadyDone.Add(itbvx);
- }
- }}
- {FOREACHINDYNAMICCONTAINER( cbvxAllreadyDone, CBrushVertex, itbvx)
- {
- pDoc->m_selVertexSelection.Deselect( *itbvx);
- }}
- // triangularize all influenced polygons
- pDoc->m_woWorld.TriangularizeForVertices( pDoc->m_selVertexSelection);
- // for each vertex
- {FOREACHINDYNAMICCONTAINER( pDoc->m_selVertexSelection, CBrushVertex, itbvx)
- {
- // set its new position
- itbvx->SetAbsolutePosition( vMergeToVertex);
- }}
- // reselect vertices
- {FOREACHINDYNAMICCONTAINER( cbvxAllreadyDone, CBrushVertex, itbvx)
- {
- pDoc->m_selVertexSelection.Select( *itbvx);
- }}
- // update sectors
- pDoc->m_woWorld.UpdateSectorsDuringVertexChange( pDoc->m_selVertexSelection);
- pDoc->m_woWorld.UpdateSectorsAfterVertexChange( pDoc->m_selVertexSelection);
- pDoc->UpdateAllViews( NULL);
- pDoc->SetModifiedFlag();
- }
- void CWorldEditorView::OnExportDisplaceMap()
- {
- CImageInfo ii;
-
- CDlgDisplaceMapSize dlgDisplaceMapSize;
- if( dlgDisplaceMapSize.DoModal() != IDOK)
- {
- return;
- }
- CWorldEditorDoc* pDoc = GetDocument();
- // find bounding box of all selected polygons
- FLOATaabbox3D boxSelection;
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- // calculate bounding box for all polygons
- boxSelection |= itbpo->bpo_boxBoundingBox;
- }
- PIX pixWidth = dlgDisplaceMapSize.m_pixWidth;
- PIX pixHeight = dlgDisplaceMapSize.m_pixHeight;
- FLOAT fMinX = boxSelection.Min()(1);
- FLOAT fMaxX = boxSelection.Max()(1);
- FLOAT fMinY = boxSelection.Min()(2);
- FLOAT fMaxY = boxSelection.Max()(2);
- FLOAT fSizeY = boxSelection.Size()(2);
- FLOAT fMinZ = boxSelection.Min()(3);
- FLOAT fMaxZ = boxSelection.Max()(3);
- FLOAT fDeltaX;
- FLOAT fDeltaZ;
- if (dlgDisplaceMapSize.m_bMidPixSample)
- {
- fDeltaX = (fMaxX-fMinX)/pixWidth;
- fDeltaZ = (fMaxZ-fMinZ)/pixHeight;
- }
- else
- {
- fDeltaX = (fMaxX-fMinX-0.5f)/pixWidth;
- fDeltaZ = (fMaxZ-fMinZ-0.5f)/pixHeight;
- }
- CPrintF("Export displace map...\n");
- CPrintF("Min: (%gf, %gf, %gf), Max: (%gf, %gf, %gf), Delta X=%g, Delta Z=%g\n",
- fMinX, fMinY, fMinZ,
- fMaxX, fMaxY, fMaxZ,
- fDeltaX, fDeltaZ);
- CTFileName fnDocName = CTString(CStringA(pDoc->GetPathName()));
- CTFileName fnDirectory = fnDocName.FileDir();
- CTFileName fnDefaultSelected = fnDocName.FileName()+CTString("DisplaceMap.tga");
- try
- {
- fnDirectory.RemoveApplicationPath_t();
- }
- catch( char *str_err)
- {
- AfxMessageBox( CString(str_err));
- return;
- }
- // note: NULL given instead of profile string name, to avoid using last directory
- CTFileName fnDisplaceMap =
- _EngineGUI.FileRequester( "Select name to export displace map",
- "Pictures (*.tga)\0*.tga\0" FILTER_END,
- NULL, fnDirectory, fnDefaultSelected, NULL, FALSE);
- if( fnDisplaceMap == "") return;
- ULONG ulSize = pixWidth*pixHeight*3;
- UBYTE *pubPicture = (UBYTE *) AllocMemory( ulSize);
-
- // initializes structure members and attaches pointer to image
- ii.Attach( pubPicture, pixWidth, pixHeight, 24);
- // for each line of pixels in height map
- for( INDEX iY=0; iY<pixHeight; iY++)
- {
- // for each horizontal pixel in height map
- for( INDEX iX=0; iX<pixWidth; iX++)
- {
-
- FLOAT fX;
- FLOAT fZ;
-
- // calculate coordinate in world
- if (dlgDisplaceMapSize.m_bMidPixSample)
- {
- fX = fMinX+fDeltaX*iX+fDeltaX/2;
- fZ = fMinZ+fDeltaZ*iY+fDeltaZ/2;
- }
- else
- {
- fX = fMinX+fDeltaX*iX+0.1;
- fZ = fMinZ+fDeltaZ*iY+0.1;
- }
- // cast ray to recive height
- CCastRay crRayHit = CCastRay( NULL, CPlacement3D(FLOAT3D(fX, fMaxY+1.0f, fZ), ANGLE3D(0,-90,0)) );
- crRayHit.cr_bAllowOverHit = TRUE;
- crRayHit.cr_bHitPortals = FALSE;
- crRayHit.cr_ttHitModels = CCastRay::TT_NONE;
- // cast ray, go for hit data
- pDoc->m_woWorld.CastRay( crRayHit);
- if (!dlgDisplaceMapSize.m_bHighResolution){
- // set black pixel if nothing hit
- UBYTE ubPixelColor = 0;
- if( crRayHit.cr_penHit != NULL)
- {
- FLOAT fYHit = crRayHit.cr_vHit(2);
- ubPixelColor = (UBYTE) ((fYHit-fMinY)/fSizeY*255.0f);
- }
-
- UBYTE *pPixel=pubPicture+iY*pixWidth*3+iX*3;
- *(pPixel+0) = ubPixelColor;
- *(pPixel+1) = ubPixelColor;
- *(pPixel+2) = ubPixelColor;
- }
- else
- {
- // set black pixel if nothing hit
- unsigned short usPixelColor = 0;
- if( crRayHit.cr_penHit != NULL)
- {
- FLOAT fYHit = crRayHit.cr_vHit(2);
- usPixelColor = (unsigned short) ((fYHit-fMinY)/fSizeY*65535);
- }
-
- UBYTE *pPixel=pubPicture+iY*pixWidth*3+iX*3;
- *(pPixel+0) = 0;
- *(pPixel+1) = usPixelColor>>8;
- *(pPixel+2) = usPixelColor&0xFF;
- }
- }
- }
- // try to
- try {
- // save displace map as TGA
- ii.SaveTGA_t( fnDisplaceMap);
- } // if failed
- catch (char *strError) {
- // report error
- AfxMessageBox(CString(strError));
- }
- }
- void CWorldEditorView::OnCutMode()
- {
- // if we should enter cut mode
- if( !theApp.m_bCutModeOn)
- {
- CTString strError;
- BOOL bCutEnabled = IsCutEnabled( strError);
- if( !bCutEnabled)
- {
- // warn user
- WarningMessage( "%s", strError);
- return;
- }
- }
- theApp.m_bCutModeOn = !theApp.m_bCutModeOn;
- theApp.m_bMeasureModeOn = FALSE;
- }
- void CWorldEditorView::OnUpdateCutMode(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // cut is enabled only in sector and polygon mode
- if( (pDoc->GetEditingMode() == POLYGON_MODE) ||
- (pDoc->GetEditingMode() == ENTITY_MODE) ||
- (pDoc->GetEditingMode() == SECTOR_MODE) )
- {
- pCmdUI->Enable( TRUE);
- }
- else
- {
- pCmdUI->Enable( FALSE);
- }
- pCmdUI->SetCheck( theApp.m_bCutModeOn);
- //pDoc->UpdateAllViews( NULL); !!!!!!!!!!!!!!!!!!!!! unbelievable !!!!!!!!!!!!!!!!!
- }
- BOOL CWorldEditorView::IsCutEnabled(CTString &strError)
- {
- CWorldEditorDoc* pDoc = GetDocument();
-
- if( pDoc->GetEditingMode() == ENTITY_MODE)
- {
- // there must be at least one entity in selection
- if( pDoc->m_selEntitySelection.Count() == 0)
- {
- strError = "You must select entity(s) that you want to mirror!";
- return FALSE;
- }
- }
- else if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- // there must be at least one polygon in selection
- if( pDoc->m_selPolygonSelection.Count() == 0)
- {
- strError = "You must select polygon(s) that you want to cut!";
- return FALSE;
- }
- // all polygons must be of the same brush
- CBrush3D *pbrBrush = NULL;
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- // remember first polygon's brush
- if( pbrBrush == NULL)
- {
- pbrBrush = itbpo->bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush;
- }
- else
- {
- // if any of the other polygons are not from same brush
- if( pbrBrush != itbpo->bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush)
- {
- // don't allow cut
- strError = "All polygons must be from the same brush to be able to cut them!";
- return FALSE;
- }
- }
- }
- }
- else if(pDoc->GetEditingMode() == SECTOR_MODE)
- {
- // there must be at least one sector in selection
- if( pDoc->m_selSectorSelection.Count() == 0)
- {
- strError = "You must select sector(s) that you want to cut!";
- return FALSE;
- }
- // all sectors must be of the same brush
- CBrush3D *pbrBrush = NULL;
- FOREACHINDYNAMICCONTAINER(pDoc->m_selSectorSelection, CBrushSector, itbsc)
- {
- // remember first sector's brush
- if( pbrBrush == NULL)
- {
- pbrBrush = itbsc->bsc_pbmBrushMip->bm_pbrBrush;
- }
- else
- {
- // if any of the other sectors are not from same brush
- if( pbrBrush != itbsc->bsc_pbmBrushMip->bm_pbrBrush)
- {
- // don't allow cut
- strError = "All sector must be from the same brush to be able to cut them!";
- return FALSE;
- }
- }
- }
- }
- return TRUE;
- }
- void CWorldEditorView::OnUpdateSelectClones(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // allow clone selecting only if we have only one entity selected
- if( pDoc->m_selEntitySelection.Count() == 1)
- {
- pCmdUI->Enable( TRUE);
- return;
- }
- pCmdUI->Enable( FALSE);
- }
- void CWorldEditorView::OnSelectClones()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CEntity *pen = pDoc->m_selEntitySelection.GetFirstInSelection();
- // for each entity in the world
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- // if has same name
- if( pen->GetName() == iten->GetName() )
- {
- // if is not yet selected
- if( !iten->IsSelected( ENF_SELECTED))
- {
- // select it
- pDoc->m_selEntitySelection.Select( *iten);
- }
- }
- }
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- BOOL CWorldEditorView::IsSelectClonesOnContextEnabled( void)
- {
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- if( crRayHit.cr_penHit != NULL)
- {
- return TRUE;
- }
- return FALSE;
- }
- void CWorldEditorView::OnSelectClonesOnContext()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- if( crRayHit.cr_penHit != NULL)
- {
- // get hitted entity
- CEntity *pen = crRayHit.cr_penHit;
- // for each entity in the world
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- // if has same name
- if( pen->GetName() == iten->GetName() )
- {
- // if is not yet selected
- if( !iten->IsSelected( ENF_SELECTED))
- {
- // select it
- pDoc->m_selEntitySelection.Select( *iten);
- }
- }
- }
- }
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnKeyCtrlShiftE()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if(pDoc->GetEditingMode()==TERRAIN_MODE)
- {
- ApplyEqualizeOntoTerrain();
- }
- else
- {
- OnSelectOfSameClass();
- }
- }
- void CWorldEditorView::OnSelectOfSameClass()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CEntity *pen = pDoc->m_selEntitySelection.GetFirstInSelection();
- // to hold entities for selecting
- CDynamicContainer<CEntity> dcEntities;
- // for all selected entities
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- dcEntities.Add( &*iten);
- }}
- // for each non-hidden entity in the world
- {FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- CBrushSector *pbscSector = iten->GetFirstSector();
- BOOL bSectorVisible = (pbscSector == NULL) ||
- !(pbscSector->bsc_ulFlags & BSCF_HIDDEN);
- // if it isn't classified in hidden sector and is not hidden itself
- if( !bSectorVisible || (iten->en_ulFlags&ENF_HIDDEN) )
- {
- continue;
- }
- // obtain this entity's class ptr
- CEntityClass *pdecClass = iten->GetClass();
- // test all classes
- {FOREACHINDYNAMICCONTAINER(dcEntities, CEntity, itenClass)
- {
- CEntityClass *pdecClassTest = itenClass->GetClass();
- // if of same class
- if( pdecClassTest == pdecClass)
- {
- // if not yet selected
- if( !iten->IsSelected( ENF_SELECTED))
- {
- // select it
- pDoc->m_selEntitySelection.Select( *iten);
- }
- }
- }}
- }}
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnSelectOfSameClassOnContext()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- if( crRayHit.cr_penHit != NULL)
- {
- // get hitted entity
- CEntity *pen = crRayHit.cr_penHit;
- // obtain this entity's class ptr
- CEntityClass *pdecClassTest = pen->GetClass();
- // for each non-hidden entity in the world
- {FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- CBrushSector *pbscSector = iten->GetFirstSector();
- BOOL bSectorVisible = (pbscSector == NULL) ||
- !(pbscSector->bsc_ulFlags & BSCF_HIDDEN);
- // if it isn't classified in hidden sector and is not hidden itself
- if( !bSectorVisible || (iten->en_ulFlags&ENF_HIDDEN) )
- {
- continue;
- }
-
- CEntityClass *pdecClass = iten->GetClass();
- // if of same class
- if( pdecClassTest == pdecClass)
- {
- // if not yet selected
- if( !iten->IsSelected( ENF_SELECTED))
- {
- // select it
- pDoc->m_selEntitySelection.Select( *iten);
- }
- }
- }}
- }
- // mark that selections have been changed
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- BOOL CWorldEditorView::IsSelectOfSameClassOnContextEnabled( void)
- {
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- if( crRayHit.cr_penHit != NULL)
- {
- return TRUE;
- }
- return FALSE;
- }
- // limit current frame rate if neeeded
- void LimitFrameRate(void)
- {
- // measure passed time for each loop
- /*
- static CTimerValue tvLast(-1.0f);
- CTimerValue tvNow = _pTimer->GetHighPrecisionTimer();
- TIME tmCurrentDelta = (tvNow-tvLast).GetSeconds();
- // limit maximum frame rate
- wed_iMaxFPSActive = ClampDn( (INDEX)wed_iMaxFPSActive, 1L);
- TIME tmWantedDelta = 1.0f / wed_iMaxFPSActive;
- if( tmCurrentDelta<tmWantedDelta) Sleep( (tmWantedDelta-tmCurrentDelta)*1000.0f);
-
- // remember new time
- tvLast = _pTimer->GetHighPrecisionTimer();*/
- }
- void CWorldEditorView::ApplyFreeModeControls( CPlacement3D &pl, ANGLE3D &aAbs, FLOAT &fSpeedMultiplier, BOOL bPrescan)
- {
- CChildFrame *pcf = GetChildFrame();
- CWorldEditorDoc* pDoc = GetDocument();
- #define FB_SPEED 1.0f
- #define LR_SPEED 1.0f
- #define UD_SPEED 1.0f
- #define ROT_SPEED 0.75f
- FLOAT fFB = 0.0f; // forward/backward movement
- FLOAT fLR = 0.0f; // left/right movement
- FLOAT fUD = 0.0f; // up/down movement
- FLOAT fRLR = 0.0f; // rotate left/right
- FLOAT fRUD = 0.0f; // rotate up/down
- _pInput->GetInput(bPrescan);
- if (!bPrescan) {
- // additional key indentifiers are not on
- BOOL bShift = _pInput->GetButtonState( KID_LSHIFT) || _pInput->GetButtonState( KID_RSHIFT);
- BOOL bAlt = _pInput->GetButtonState( KID_LALT) || _pInput->GetButtonState( KID_RALT);
- BOOL bCtrl = _pInput->GetButtonState( KID_LCONTROL) || _pInput->GetButtonState( KID_RCONTROL);
- // apply view configuration from first perspective view of child configuration
- if(_pInput->GetButtonState( KID_NUM0)) pcf->ApplySettingsFromPerspectiveView( this, 0);
- if(_pInput->GetButtonState( KID_NUM1)) pcf->ApplySettingsFromPerspectiveView( this, 1);
- if(_pInput->GetButtonState( KID_NUM2)) pcf->ApplySettingsFromPerspectiveView( this, 2);
- if(_pInput->GetButtonState( KID_NUM3)) pcf->ApplySettingsFromPerspectiveView( this, 3);
- if(_pInput->GetButtonState( KID_NUM4)) pcf->ApplySettingsFromPerspectiveView( this, 4);
- if(_pInput->GetButtonState( KID_NUM5)) pcf->ApplySettingsFromPerspectiveView( this, 5);
- if(_pInput->GetButtonState( KID_NUM6)) pcf->ApplySettingsFromPerspectiveView( this, 6);
- if(_pInput->GetButtonState( KID_NUM7)) pcf->ApplySettingsFromPerspectiveView( this, 7);
- if(_pInput->GetButtonState( KID_NUM8)) pcf->ApplySettingsFromPerspectiveView( this, 8);
- if(_pInput->GetButtonState( KID_NUM9)) pcf->ApplySettingsFromPerspectiveView( this, 9);
- // apply view configuration from available buffers
- if(_pInput->GetButtonState( KID_0)) OnKeyBuffer( ID_BUFFER10);
- if(_pInput->GetButtonState( KID_1)) OnKeyBuffer( ID_BUFFER01);
- if(_pInput->GetButtonState( KID_2)) OnKeyBuffer( ID_BUFFER02);
- if(_pInput->GetButtonState( KID_3)) OnKeyBuffer( ID_BUFFER03);
- if(_pInput->GetButtonState( KID_4)) OnKeyBuffer( ID_BUFFER04);
- if(_pInput->GetButtonState( KID_5)) OnKeyBuffer( ID_BUFFER05);
- if(_pInput->GetButtonState( KID_6)) OnKeyBuffer( ID_BUFFER06);
- if(_pInput->GetButtonState( KID_7)) OnKeyBuffer( ID_BUFFER07);
- if(_pInput->GetButtonState( KID_8)) OnKeyBuffer( ID_BUFFER08);
- if(_pInput->GetButtonState( KID_9)) OnKeyBuffer( ID_BUFFER09);
- // ---------- Simulate moving as in fly mode
- // forward
- if(
- _pInput->GetButtonState( KID_W) ||
- _pInput->GetButtonState( KID_MOUSE2) ||
- _pInput->GetButtonState( KID_ARROWUP))
- {
- fFB = -FB_SPEED*fSpeedMultiplier;
- }
- // backward
- if(
- _pInput->GetButtonState( KID_S) ||
- _pInput->GetButtonState( KID_MOUSE1) ||
- _pInput->GetButtonState( KID_ARROWDOWN) )
- {
- fFB = +FB_SPEED*fSpeedMultiplier;
- }
- /*
- if( _pInput->GetButtonState( KID_MOUSE1))
- {
- fLR = -_pInput->GetAxisRelative(1)/15.0f;
- }*/
- // strife left
- if(
- _pInput->GetButtonState( KID_Q) ||
- _pInput->GetButtonState( KID_A) ||
- _pInput->GetButtonState( KID_ARROWLEFT) )
- {
- fLR = -LR_SPEED*fSpeedMultiplier;
- }
- // strife right
- if(
- _pInput->GetButtonState( KID_E) ||
- _pInput->GetButtonState( KID_D) ||
- _pInput->GetButtonState( KID_ARROWRIGHT) )
- {
- fLR = +LR_SPEED*fSpeedMultiplier;
- }
- // up
- if( (_pInput->GetButtonState( KID_R) && !bAlt) ||
- _pInput->GetButtonState( KID_SPACE) )
- {
- fUD = +UD_SPEED*fSpeedMultiplier;
- }
- // down
- if( _pInput->GetButtonState( KID_F))
- {
- fUD = -UD_SPEED*fSpeedMultiplier;
- }
- // drop marker here
- if( _pInput->GetButtonState( KID_C))
- {
- CTFileName fnDropClass;
- CTString strTargetProperty;
- if(pDoc->m_selEntitySelection.Count() == 1)
- {
- CEntity &enOnly = pDoc->m_selEntitySelection.GetFirst();
- if(enOnly.DropsMarker( fnDropClass, strTargetProperty))
- {
- OnDropMarker(pl);
- }
- }
- }
- static BOOL bLastTurboDown = FALSE;
- static FLOAT fSpeedMultiplierBeforeTurbo = 1.0f;
- if( _pInput->GetButtonState( KID_TAB))
- {
- if( !bLastTurboDown)
- {
- fSpeedMultiplierBeforeTurbo = fSpeedMultiplier;
- }
- bLastTurboDown = TRUE;
- fSpeedMultiplier = Clamp( fSpeedMultiplier+0.5f, 1.0f, 20.0f);
- }
- else if( bLastTurboDown)
- {
- bLastTurboDown = FALSE;
- fSpeedMultiplier = fSpeedMultiplierBeforeTurbo;
- }
- }
-
- // get current rotation
- fRLR = _pInput->GetAxisValue(1)*ROT_SPEED;
- fRUD = -_pInput->GetAxisValue(2)*ROT_SPEED;
- // apply translation
- if (!bPrescan) {
- pl.Translate_OwnSystem( FLOAT3D(fLR, fUD, fFB));
- // apply rotation
- pl.pl_OrientationAngle = aAbs;//.Rotate_HPB( ANGLE3D(-fRLR, -fRUD, 0));
- }
- aAbs+=ANGLE3D(-fRLR, -fRUD, 0);
- }
- // placements and orientation used in free fly mode
- static CPlacement3D _plNew;
- static CPlacement3D _plOld;
- static ANGLE3D _aAbs;
- void CWorldEditorView::PumpWindowsMessagesInFreeMode(BOOL &bRunning, FLOAT &fSpeedMultiplier)
- {
- CChildFrame *pcf = GetChildFrame();
- CWorldEditorDoc* pDoc = GetDocument();
- // additional key indentifiers are not on
- BOOL bShift = _pInput->GetButtonState( KID_LSHIFT) || _pInput->GetButtonState( KID_RSHIFT);
- BOOL bAlt = _pInput->GetButtonState( KID_LALT) || _pInput->GetButtonState( KID_RALT);
- BOOL bCtrl = _pInput->GetButtonState( KID_LCONTROL) || _pInput->GetButtonState( KID_RCONTROL);
- // while there are any messages in the message queue
- MSG msg;
- while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- // process scripts that are invoked on shortcuts from within WED
- ProcesWEDConsoleShortcuts( &msg);
-
- if(msg.message==_uiMessengerMsg)
- {
- // if one application allready started
- HWND hwndMessenger = ::FindWindow(NULL, L"Croteam Messenger");
- if(hwndMessenger != NULL)
- {
- // force messenger to popup
- ::PostMessage( hwndMessenger, _uiMessengerForcePopup, 0, 0);
- }
- }
-
- // ---------- Simulate some important commands of wed
- if( msg.message==WM_KEYDOWN || msg.message==WM_SYSKEYDOWN)
- {
- // 'G' links on/off
- if( msg.wParam=='G' && !bCtrl) pcf->OnRenderTargets();
- // 'G' links on/off
- if( msg.wParam=='G' && bCtrl) pcf->OnToggleEntityNames();
- // 'H' shadow on off
- if( msg.wParam=='H') pcf->OnViewShadowsOnoff();
- // 'Num -' toggle frame rate
- if( msg.wParam == VK_SUBTRACT) pcf->OnSceneRenderingTime();
- // 'B' toggle auto mip leveling
- if( msg.wParam=='B') pcf->OnAutoMipLeveling();
- // 'Alt+R' toggle frame rate
- if( msg.wParam=='R' && bAlt) pcf->OnSceneRenderingTime();
- // 'Shift+Backspace' center background viewer
- if( (msg.wParam == VK_BACK) && bShift)
- {
- OnCenterBcgViewer();
- _plNew = pcf->m_mvViewer.mv_plViewer;
- _plOld = _plNew;
- _aAbs = _plNew.pl_OrientationAngle;
- }
- // 'Backspace' center to 0
- else if( msg.wParam == VK_BACK)
- {
- OnResetViewer();
- _plNew = pcf->m_mvViewer.mv_plViewer;
- _plOld = _plNew;
- _aAbs = _plNew.pl_OrientationAngle;
- }
- // 'F5, F6, F7, F8' type of projections
- if( (msg.wParam == VK_F5) && bShift) OnIsometricBottom();
- else if( msg.wParam == VK_F5) OnIsometricTop();
- if( (msg.wParam == VK_F6) && bShift) OnIsometricLeft();
- else if( msg.wParam == VK_F6) OnIsometricRight();
- if( (msg.wParam == VK_F7) && bShift) OnIsometricBack();
- else if( msg.wParam == VK_F7) OnIsometricFront();
- if( (msg.wParam == VK_F8)) OnPerspective();
- // 'Home', 'End', 'Page Up', 'Page Dn' 'Ctrl+' combinations for storing and restoring positions
- if( (msg.wParam == VK_HOME) && bCtrl) pcf->OnStorePosition01();
- else if( msg.wParam == VK_HOME)
- {
- pcf->OnRestorePosition01();
- _plNew = pcf->m_mvViewer.mv_plViewer;
- _plOld = _plNew;
- _aAbs = _plNew.pl_OrientationAngle;
- }
- if( (msg.wParam == VK_END) && bCtrl) pcf->OnStorePosition02();
- else if( msg.wParam == VK_END)
- {
- pcf->OnRestorePosition02();
- _plNew = pcf->m_mvViewer.mv_plViewer;
- _plOld = _plNew;
- _aAbs = _plNew.pl_OrientationAngle;
- }
- if( (msg.wParam == VK_PRIOR) && bCtrl) pcf->OnStorePosition03();
- else if( msg.wParam == VK_PRIOR)
- {
- pcf->OnRestorePosition03();
- _plNew = pcf->m_mvViewer.mv_plViewer;
- _plOld = _plNew;
- _aAbs = _plNew.pl_OrientationAngle;
- }
- if( (msg.wParam == VK_NEXT) && bCtrl) pcf->OnStorePosition04();
- else if( msg.wParam == VK_NEXT)
- {
- pcf->OnRestorePosition04();
- _plNew = pcf->m_mvViewer.mv_plViewer;
- _plOld = _plNew;
- _aAbs = _plNew.pl_OrientationAngle;
- }
- // 'X', 'Alt+X', 'Alt+A' hide selected, unselected, show all
- if( (msg.wParam == 'X') && bAlt) pDoc->OnHideUnselected();
- else if( msg.wParam == 'X') pDoc->OnHideSelected();
- if( (msg.wParam == 'A') && bAlt) pDoc->OnShowAll();
- // 'Z' for toggle view selection
- if( msg.wParam == 'Z') pcf->OnViewSelection();
- }
- // use mouse wheel to increase/decrease moving speed
- if( msg.message==WM_MOUSEWHEEL)
- {
- short zDelta = (short) HIWORD(msg.wParam);
- INDEX iCount = zDelta/120;
- for( INDEX iKnee=0; iKnee<Abs(iCount); iKnee++)
- {
- if(iCount<0) fSpeedMultiplier/=2;
- else fSpeedMultiplier*=2;
- }
- }
- // if it is not a mouse message
- if(!(msg.message>=WM_MOUSEFIRST&&msg.message<=WM_MOUSELAST))
- {
- // if not system key messages
- if (!(msg.message==WM_KEYDOWN && msg.wParam==VK_F10
- ||msg.message==WM_SYSKEYDOWN))
- {
- // translate it
- TranslateMessage(&msg);
- }
- // if paint message
- if (msg.message==WM_PAINT)
- {
- // dispatch it
- DispatchMessage(&msg);
- }
- }
- // if should stop
- if( (msg.message==WM_KEYDOWN && msg.wParam==VK_ESCAPE)
- ||(msg.message==WM_ACTIVATE)
- ||(msg.message==WM_CANCELMODE)
- ||(msg.message==WM_KILLFOCUS)
- ||(msg.message==WM_ACTIVATEAPP))
- {
- // stop running
- bRunning = FALSE;
- break;
- }
- }
- }
- void CWorldEditorView::OnAlternativeMovingMode()
- {
- INDEX iAllowMouseAcceleration = _pShell->GetINDEX("inp_bAllowMouseAcceleration");
- INDEX iFilterMouse = _pShell->GetINDEX("inp_bFilterMouse");
- _pShell->SetINDEX("inp_bAllowMouseAcceleration", 1);
- _pShell->SetINDEX("inp_bFilterMouse", 1);
- CWorldEditorDoc* pDoc = GetDocument();
- CViewPrefs vpOrg = m_vpViewPrefs;
- // obtain child frame ptr
- CChildFrame *pcf = GetChildFrame();
- _plNew = pcf->m_mvViewer.mv_plViewer;
- _plOld = _plNew;
- _aAbs = _plNew.pl_OrientationAngle;
- BOOL bAutoMipBrushingBefore = pcf->m_bAutoMipBrushingOn;
- BOOL bDisableVisibilityTweaksBefore = pcf->m_bDisableVisibilityTweaks;
- // enable input
- _pInput->EnableInput(m_pvpViewPort);
- // initialy, game is running
- BOOL bRunning = TRUE;
- INDEX iLastTick = 0;
- CTimerValue tvStart = _pTimer->GetHighPrecisionTimer();
- // while it is still running
- while( bRunning)
- {
- // process all windows messages
- PumpWindowsMessagesInFreeMode( bRunning, _fFlyModeSpeedMultiplier);
- CTimerValue tvNow = _pTimer->GetHighPrecisionTimer();
- FLOAT fPassed = (tvNow-tvStart).GetSeconds();
- INDEX iNowTick = INDEX(fPassed/_pTimer->TickQuantum);
- // apply controls for frame rates below tick quantum
- while(iLastTick<iNowTick-1)
- {
- _plOld = _plNew;
- ApplyFreeModeControls( _plNew, _aAbs, _fFlyModeSpeedMultiplier, FALSE);
- iLastTick++;
- }
- ApplyFreeModeControls( _plNew, _aAbs, _fFlyModeSpeedMultiplier, TRUE);
- // set new viewer position
- FLOAT fLerpFactor = (fPassed-iNowTick*_pTimer->TickQuantum)/_pTimer->TickQuantum;
- ASSERT(fLerpFactor>0 && fLerpFactor<1.0f);
- pcf->m_mvViewer.mv_plViewer.Lerp( _plOld, _plNew, Clamp(fLerpFactor, 0.0f, 1.0f));
- pcf->m_mvViewer.mv_plViewer.pl_OrientationAngle = _aAbs;
- // disable auto rendering range
- m_vpViewPrefs.m_bAutoRenderingRange = FALSE;
- m_vpViewPrefs.m_fRenderingRange = 2.0f;
- pcf->m_bAutoMipBrushingOn = TRUE;
- pcf->m_bDisableVisibilityTweaks=FALSE;
- // render view again
- CDC *pDC = GetDC();
- OnDraw( pDC);
- ReleaseDC( pDC);
- // smooth frame rate
- LimitFrameRate();
- }
- _pInput->DisableInput();
- // restore rendering range settings from remembered stat view prefs
- m_vpViewPrefs.m_bAutoRenderingRange = vpOrg.m_bAutoRenderingRange;
- m_vpViewPrefs.m_wrpWorldRenderPrefs.SetMinimumRenderRange(vpOrg.m_wrpWorldRenderPrefs.GetMinimumRenderRange());
- pcf->m_bAutoMipBrushingOn = bAutoMipBrushingBefore;
- pcf->m_bDisableVisibilityTweaks=bDisableVisibilityTweaksBefore;
- _pShell->SetINDEX("inp_bAllowMouseAcceleration", iAllowMouseAcceleration);
- _pShell->SetINDEX("inp_bFilterMouse", iFilterMouse);
- }
- void CWorldEditorView::OnReTriple()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CBrushPolygon *pbpo = pDoc->m_selPolygonSelection.GetFirstInSelection();
- pbpo->bpo_pbscSector->ReTriple( pDoc->m_selPolygonSelection);
- }
- void CWorldEditorView::OnClearAllTargets(void)
- {
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CWorldEditorDoc* pDoc = GetDocument();
- if( m_bEntityHitedOnContext && m_penEntityHitOnContext != NULL)
- {
- if( ::MessageBoxA( pMainFrame->m_hWnd, "Are you sure that you want to clear all targets?",
- "Warning !", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2|
- MB_SYSTEMMODAL | MB_TOPMOST) != IDYES)
- {
- return;
- }
- // clear all targets of right-clicked entity
- pMainFrame->m_PropertyComboBar.ClearAllTargets( m_penEntityHitOnContext);
- pDoc->UpdateAllViews( NULL);
- pDoc->SetModifiedFlag();
- }
- }
- void CWorldEditorView::OnSelectCsgTarget()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CBrushMip *pbmCurrentMip = GetCurrentBrushMip();
- if (pbmCurrentMip!=NULL)
- {
- // obtain entity
- CEntity *pen = pbmCurrentMip->bm_pbrBrush->br_penEntity;
- if( !pen->IsSelected( ENF_SELECTED))
- {
- pDoc->m_selEntitySelection.Select( *pen);
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- }
- }
- void CWorldEditorView::OnUpdateSelectCsgTarget(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CBrushMip *pbmCurrentMip = GetCurrentBrushMip();
- pCmdUI->Enable(pbmCurrentMip!=NULL);
- }
- void CWorldEditorView::OnUpdateReTriple(CCmdUI* pCmdUI)
- {
- BOOL bEnableRetripling = FALSE;
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->m_selPolygonSelection.Count() != 0)
- {
- CBrushPolygon *pbpo = pDoc->m_selPolygonSelection.GetFirstInSelection();
- bEnableRetripling = pbpo->bpo_pbscSector->IsReTripleAvailable( pDoc->m_selPolygonSelection);
- }
- pCmdUI->Enable(bEnableRetripling);
- }
- void CWorldEditorView::OnTriangularizePolygon()
- {
- CWorldEditorDoc *pDoc = GetDocument();
- CBrushPolygon *pbpoHitted = NULL;
- if( (m_penEntityHitOnContext != NULL) &&
- (m_penEntityHitOnContext->GetRenderType() == CEntity::RT_BRUSH) &&
- (m_pbpoRightClickedPolygon != NULL) )
- {
- pbpoHitted = m_pbpoRightClickedPolygon;
- }
- if( pbpoHitted != NULL)
- {
- pDoc->m_selVertexSelection.Clear();
- if( pbpoHitted->IsSelected(BPOF_SELECTED))
- {
- OnTriangularizeSelection();
- return;
- }
- else
- {
- pDoc->m_selVertexSelection.Clear();
- pDoc->m_selPolygonSelection.Clear();
- pbpoHitted->bpo_pbscSector->TriangularizePolygon( pbpoHitted);
- }
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnEntityContextHelp()
- {
- if( m_penEntityHitOnContext != NULL)
- {
- theApp.DisplayHelp(m_penEntityHitOnContext->GetClass()->GetName(), HH_DISPLAY_TOPIC, NULL);
- }
- }
- void CWorldEditorView::AutoFitMapping(CBrushPolygon *pbpo, BOOL bInvert/*=FALSE*/, BOOL bFitBoth/*=FALSE*/)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pbpo==NULL) return;
- if( pbpo->IsSelected(BPOF_SELECTED))
- {
- // for each selected polygon
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- AutoFitMappingOnPolygon(*itbpo, bInvert, bFitBoth);
- }
- }
- else
- {
- AutoFitMappingOnPolygon(*pbpo, bInvert, bFitBoth);
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::AutoFitMappingOnPolygon(CBrushPolygon &bpo, BOOL bInvert/*=FALSE*/, BOOL bFitBoth/*=FALSE*/)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CMappingDefinition &md = bpo.bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping;
-
- // reset u,v stretches
- CMappingDefinitionUI mdui;
- md.ToUI(mdui);
- mdui.mdui_fUStretch = 1.0f;
- mdui.mdui_fVStretch = 1.0f;
- mdui.mdui_fUOffset = 0.0f;
- mdui.mdui_fVOffset = 0.0f;
- md.FromUI(mdui);
- // find min and max u and v for the polygon
- FLOAT fMinU = UpperLimit(0.0f);
- FLOAT fMaxU = LowerLimit(0.0f);
- FLOAT fMinV = UpperLimit(0.0f);
- FLOAT fMaxV = LowerLimit(0.0f);
- INDEX ibpe=0;
- for(; ibpe<bpo.bpo_abpePolygonEdges.Count(); ibpe++)
- {
- CBrushPolygonEdge &bpe = bpo.bpo_abpePolygonEdges[ibpe];
- FLOAT3D v0, v1;
- MEX2D(vTex0);
- bpe.GetVertexCoordinatesRelative(v0, v1);
- md.GetTextureCoordinates( bpo.bpo_pbplPlane->bpl_pwplWorking->wpl_mvRelative, v0, vTex0);
- FLOAT fU = vTex0(1)/1024.0f;
- FLOAT fV = vTex0(2)/1024.0f;
- fMinU = Min(fMinU, fU);
- fMaxU = Max(fMaxU, fU);
- fMinV = Min(fMinV, fV);
- fMaxV = Max(fMaxV, fV);
- }
- // calculate u,v fit stretches
- FLOAT fFitStretchU = fMaxU-fMinU;
- FLOAT fFitStretchV = fMaxV-fMinV;
- // get fit stretch
- FLOAT fFitStretch;
- if( !bInvert)
- {
- fFitStretch = Min(fFitStretchV,fFitStretchU);
- }
- else
- {
- fFitStretch = Max(fFitStretchV,fFitStretchU);
- }
- // adjust stretch for texture size
- CTextureData *ptd = (CTextureData *)bpo.bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.GetData();
- if( ptd!=NULL)
- {
- MEX mexW=ptd->GetWidth();
- MEX mexH=ptd->GetHeight();
- // if fitting U
- if( fFitStretch==fFitStretchU)
- {
- fFitStretch/=mexW/1024.0f;
- }
- // if fitting V
- else
- {
- fFitStretch/=mexH/1024.0f;
- }
- fFitStretchU/=mexW/1024.0f;
- fFitStretchV/=mexH/1024.0f;
- }
- if( bFitBoth)
- {
- mdui.mdui_fUStretch=fFitStretchU;
- mdui.mdui_fVStretch=fFitStretchV;
- }
- else
- {
- mdui.mdui_fUStretch=fFitStretch;
- mdui.mdui_fVStretch=fFitStretch;
- }
- md.FromUI(mdui);
- CMappingVectors &mv = bpo.bpo_pbplPlane->bpl_pwplWorking->wpl_mvRelative;
- // find vtx that has min u and v
- fMinU = UpperLimit(0.0f);
- fMaxV = LowerLimit(0.0f);
- FLOAT3D vMinU, vMaxV;
- for(ibpe=0; ibpe<bpo.bpo_abpePolygonEdges.Count(); ibpe++)
- {
- CBrushPolygonEdge &bpe = bpo.bpo_abpePolygonEdges[ibpe];
- FLOAT3D v0, v1, va0, va1;
- MEX2D(vTex0);
- bpe.GetVertexCoordinatesRelative(v0, v1);
- bpe.GetVertexCoordinatesAbsolute(va0, va1);
- md.GetTextureCoordinates( mv, v0, vTex0);
- FLOAT fU = vTex0(1)/1024.0f;
- FLOAT fV = vTex0(2)/1024.0f;
- if( fU<fMinU)
- {
- vMinU=v0;
- fMinU=fU;
- }
- if( fV>fMaxV)
- {
- vMaxV=v0;
- fMaxV=fV;
- }
- }
- // remember u offset
- md.Center(mv, vMinU);
- md.ToUI(mdui);
- fMinU = mdui.mdui_fUOffset;
- // remember v offset
- md.Center(mv, vMaxV);
- md.ToUI(mdui);
- fMaxV = mdui.mdui_fVOffset;
- // set offsets
- mdui.mdui_fUOffset=fMinU;
- mdui.mdui_fVOffset=fMaxV;
- md.FromUI(mdui);
- }
- void CWorldEditorView::OnTriangularizeSelection()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CDynamicContainer<CBrushPolygon> dcPolygons;
- // copy polygon selection
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- dcPolygons.Add(&*itbpo);
- }
- // clear selections
- pDoc->m_selPolygonSelection.Clear();
- pDoc->m_selVertexSelection.Clear();
- // apply triangularisation
- pDoc->m_woWorld.TriangularizePolygons( dcPolygons);
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnUpdateTriangularizeSelection(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pCmdUI->Enable(pDoc->m_selPolygonSelection.Count()!=0);
- }
- void CWorldEditorView::OnPopupAutoFitMapping()
- {
- if(m_pbpoRightClickedPolygon != NULL)
- {
- AutoFitMapping( m_pbpoRightClickedPolygon);
- }
- }
- void CWorldEditorView::OnPopupAutoFitMappingSmall()
- {
- if(m_pbpoRightClickedPolygon != NULL)
- {
- AutoFitMapping( m_pbpoRightClickedPolygon, TRUE);
- }
- }
- void CWorldEditorView::OnPopupAutoFitMappingBoth()
- {
- if(m_pbpoRightClickedPolygon != NULL)
- {
- AutoFitMapping( m_pbpoRightClickedPolygon, TRUE, TRUE);
- }
- }
- void CWorldEditorView::ApplyDefaultMapping(CBrushPolygon *pbpo, BOOL bRotation, BOOL bOffset, BOOL bStretch)
- {
- if(m_pbpoRightClickedPolygon == NULL) return;
- CWorldEditorDoc* pDoc = GetDocument();
- // if is selected
- if( m_pbpoRightClickedPolygon->IsSelected(BPOF_SELECTED))
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- CBrushPolygon &po=*itbpo;
- CMappingDefinition &md=po.bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping;
- CMappingDefinitionUI mdui;
- md.ToUI(mdui);
- if( bRotation)
- {
- mdui.mdui_aURotation=0.0f;
- mdui.mdui_aVRotation=0.0f;
- }
- if( bStretch)
- {
- mdui.mdui_fUStretch = 1.0f;
- mdui.mdui_fVStretch = 1.0f;
- }
- if( bOffset)
- {
- mdui.mdui_fUOffset = 0.0f;
- mdui.mdui_fVOffset = 0.0f;
- }
- md.FromUI(mdui);
- }
- }
- else
- {
- CMappingDefinition &md=m_pbpoRightClickedPolygon->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping;
- CMappingDefinitionUI mdui;
- md.ToUI(mdui);
- if( bRotation)
- {
- mdui.mdui_aURotation=0.0f;
- mdui.mdui_aVRotation=0.0f;
- }
- if( bStretch)
- {
- mdui.mdui_fUStretch = 1.0f;
- mdui.mdui_fVStretch = 1.0f;
- }
- if( bOffset)
- {
- mdui.mdui_fUOffset = 0.0f;
- mdui.mdui_fVOffset = 0.0f;
- }
- md.FromUI(mdui);
- }
- }
- void CWorldEditorView::OnResetMappingOffset()
- {
- ApplyDefaultMapping( m_pbpoRightClickedPolygon, FALSE, TRUE, FALSE);
- }
- void CWorldEditorView::OnResetMappingRotation()
- {
- ApplyDefaultMapping( m_pbpoRightClickedPolygon, TRUE, FALSE, FALSE);
- }
- void CWorldEditorView::OnResetMappingStretch()
- {
- ApplyDefaultMapping( m_pbpoRightClickedPolygon, FALSE, FALSE, TRUE);
- }
- void CWorldEditorView::ShowLinkTree(CEntity *pen, BOOL bWhoTargets/*=FALSE*/, BOOL bPropertyNames/*=FALSE*/)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CPoint ptScr=m_ptMouse;
- ClientToScreen( &ptScr);
- if( pen!=NULL || (pDoc->m_selEntitySelection.Count() != 0))
- {
- CDlgLinkTree dlg( pen, ptScr, bWhoTargets, bPropertyNames);
- dlg.DoModal();
- }
- }
- void CWorldEditorView::OnCrossroadForL()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == ENTITY_MODE)
- {
- ShowLinkTree(NULL);
- }
- else if(pDoc->m_pwoSecondLayer != NULL)
- {
- pDoc->OnJoinLayers();
- }
- else if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- theApp.m_iTerrainEditMode=TEM_LAYER;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- }
- void CWorldEditorView::OnSelectUsingTargetTree()
- {
- ShowLinkTree(m_penEntityHitOnContext);
- }
- void CWorldEditorView::OnTargetTree()
- {
- ShowLinkTree(NULL);
- }
- void CWorldEditorView::OnUpdateTargetTree(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pCmdUI->Enable(pDoc->m_selEntitySelection.Count() != 0);
- }
- void SwapLayers( CBrushPolygon &bpo, INDEX il1, INDEX il2)
- {
- CBrushPolygonTexture bptTemp;
- bptTemp.CopyTextureProperties(bpo.bpo_abptTextures[il1], TRUE);
- bpo.bpo_abptTextures[il1].CopyTextureProperties(bpo.bpo_abptTextures[il2], TRUE);
- bpo.bpo_abptTextures[il2].CopyTextureProperties(bptTemp, TRUE);
- }
- void CWorldEditorView::OnSwapLayers12()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- SwapLayers( *itbpo, 0, 1);
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnSwapLayers23()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- SwapLayers( *itbpo, 1, 2);
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnSelectDescendants()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- SelectDescendents( pDoc->m_selEntitySelection, *iten);
- }
- pDoc->m_chSelections.MarkChanged();
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnRotateToTargetOrigin()
- {
- if(m_penEntityHitOnContext != NULL)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- const CPlacement3D &plDst=iten->GetPlacement();
- const CPlacement3D &plSrc=m_penEntityHitOnContext->GetPlacement();
- FLOAT3D vDir=plSrc.pl_PositionVector-plDst.pl_PositionVector;
- vDir.Normalize();
- ANGLE3D ang;
- DirectionVectorToAngles(vDir, ang);
- CPlacement3D plNew=plDst;
- plNew.pl_OrientationAngle=ang;
- iten->SetPlacement(plNew);
- }
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- }
- void CWorldEditorView::OnRotateToTargetCenter()
- {
- if(m_penEntityHitOnContext != NULL)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- const CPlacement3D &plDst=iten->GetPlacement();
- FLOATaabbox3D box;
- m_penEntityHitOnContext->GetSize(box);
- FLOAT3D vTarget=box.Center();
- FLOAT3D vDir=vTarget-plDst.pl_PositionVector;
- vDir.Normalize();
- ANGLE3D ang;
- DirectionVectorToAngles(vDir, ang);
- CPlacement3D plNew=plDst;
- plNew.pl_OrientationAngle=ang;
- iten->SetPlacement(plNew);
- }
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- }
- void CWorldEditorView::OnCopyPlacement()
- {
- if(m_penEntityHitOnContext==NULL) return;
- theApp.m_plClipboard2=m_penEntityHitOnContext->GetPlacement();
- }
- void CWorldEditorView::OnCopyOrientation()
- {
- if(m_penEntityHitOnContext==NULL) return;
- theApp.m_plClipboard1.pl_OrientationAngle=m_penEntityHitOnContext->GetPlacement().pl_OrientationAngle;
- }
- void CWorldEditorView::OnCopyPosition()
- {
- if(m_penEntityHitOnContext==NULL) return;
- theApp.m_plClipboard1.pl_PositionVector=m_penEntityHitOnContext->GetPlacement().pl_PositionVector;
- }
- void CWorldEditorView::OnPastePlacement()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if(m_penEntityHitOnContext==NULL) return;
- if( m_penEntityHitOnContext->IsSelected(ENF_SELECTED))
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- iten->SetPlacement(theApp.m_plClipboard2);
- }
- }
- else
- {
- m_penEntityHitOnContext->SetPlacement(theApp.m_plClipboard2);
- }
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnPasteOrientation()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if(m_penEntityHitOnContext==NULL) return;
- if( m_penEntityHitOnContext->IsSelected(ENF_SELECTED))
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- CPlacement3D pl=iten->GetPlacement();
- pl.pl_OrientationAngle=theApp.m_plClipboard1.pl_OrientationAngle;
- iten->SetPlacement(pl);
- }
- }
- else
- {
- CPlacement3D pl=m_penEntityHitOnContext->GetPlacement();
- pl.pl_OrientationAngle=theApp.m_plClipboard1.pl_OrientationAngle;
- m_penEntityHitOnContext->SetPlacement(pl);
- }
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnPastePosition()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if(m_penEntityHitOnContext==NULL) return;
- if( m_penEntityHitOnContext->IsSelected(ENF_SELECTED))
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- CPlacement3D pl=iten->GetPlacement();
- pl.pl_PositionVector=theApp.m_plClipboard1.pl_PositionVector;
- iten->SetPlacement(pl);
- }
- }
- else
- {
- CPlacement3D pl=m_penEntityHitOnContext->GetPlacement();
- pl.pl_PositionVector=theApp.m_plClipboard1.pl_PositionVector;
- m_penEntityHitOnContext->SetPlacement(pl);
- }
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::Align(BOOL bX,BOOL bY,BOOL bZ,BOOL bH,BOOL bP,BOOL bB)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- INDEX ctSelected=pDoc->m_woWorld.wo_cenEntities.Count();
- CEntity *penLast=NULL;
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- penLast=&*iten;
- }}
- CPlacement3D penSrc=penLast->GetPlacement();
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- CPlacement3D pl=iten->GetPlacement();
- if( bX) {pl.pl_PositionVector(1)=penSrc.pl_PositionVector(1);};
- if( bY) {pl.pl_PositionVector(2)=penSrc.pl_PositionVector(2);};
- if( bZ) {pl.pl_PositionVector(3)=penSrc.pl_PositionVector(3);};
- if( bH) {pl.pl_OrientationAngle(1)=penSrc.pl_OrientationAngle(1);};
- if( bP) {pl.pl_OrientationAngle(2)=penSrc.pl_OrientationAngle(2);};
- if( bB) {pl.pl_OrientationAngle(3)=penSrc.pl_OrientationAngle(3);};
- iten->SetPlacement(pl);
- }}
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnAlignB()
- {
- Align(FALSE,FALSE,FALSE,FALSE,FALSE,TRUE);
- }
- void CWorldEditorView::OnAlignH()
- {
- Align(FALSE,FALSE,FALSE,TRUE,FALSE,FALSE);
- }
- void CWorldEditorView::OnAlignP()
- {
- Align(FALSE,FALSE,FALSE,FALSE,TRUE,FALSE);
- }
- void CWorldEditorView::OnAlignX()
- {
- Align(TRUE,FALSE,FALSE,FALSE,FALSE,FALSE);
- }
- void CWorldEditorView::OnAlignY()
- {
- Align(FALSE,TRUE,FALSE,FALSE,FALSE,FALSE);
- }
- void CWorldEditorView::OnAlignZ()
- {
- Align(FALSE,FALSE,TRUE,FALSE,FALSE,FALSE);
- }
- struct CameraProjectionInfo {
- FLOAT cpi_fOffsetRatioX;
- FLOAT cpi_fOffsetRatioY;
- FLOAT cpi_fOffsetRatioZ;
- ANGLE cpi_angH;
- ANGLE cpi_angP;
- ANGLE cpi_angB;
- double cpi_rMinI;
- double cpi_rMinJ;
- double cpi_rSizeI;
- double cpi_rSizeJ;
- };
- CameraProjectionInfo *_pacpi=NULL;
- INDEX _ctProjections=0;
- CameraProjectionInfo acpiF[] =
- {
- { 0, 0, 1, 0, 0, 0, 0, 0, 1, 1}
- };
- CameraProjectionInfo acpi2x2[] =
- {
- { 0, 0, 1, 0, 0, 0, 0, 0, 0.5, 0.5},
- { 1, 0, 0, 90, 0, 0, 0.5, 0, 0.5, 0.5},
- { 0, 0, -1, 180, 0, 0, 0, 0.5, 0.5, 0.5},
- {-1, 0, 0, 270, 0, 0, 0.5, 0.5, 0.5, 0.5}
- };
- CameraProjectionInfo acpi3x2[] =
- {
- { 0, 0, 1, 0, 0, 0, 0, 0, 0.3, 0.3},
- { 1, 0, 0, 90, 0, 0, 0.3, 0, 0.3, 0.3},
- { 0, 0, -1, 180, 0, 0, 0.6, 0, 0.3, 0.3},
- {-1, 0, 0, 270, 0, 0, 0, 0.3, 0.3, 0.3},
- { 0, 1, 0, 0,-90, 0, 0.3, 0.3, 0.3, 0.3},
- { 0,-1, 0, 0, 90, 0, 0.6, 0.3, 0.3, 0.3},
- };
- // setup viewing parameters for saving pretender textures
- void SetupView(INDEX iFrame, CDrawPort *pdp, CAnyProjection3D &apr, FLOATaabbox3D box)
- {
- // init projection parameters
- CIsometricProjection3D prIsometricProjection;
- prIsometricProjection.ScreenBBoxL() = FLOATaabbox2D(
- FLOAT2D(0.0f, 0.0f),
- FLOAT2D((FLOAT)pdp->GetWidth(), (FLOAT)pdp->GetHeight())
- );
- prIsometricProjection.NearClipDistanceL() = 0.0f;
- // determine far clip plane
- FLOAT3D vSize=box.Size();
- FLOAT3D vHSize=vSize/2.0f;
- FLOAT3D vRatio=FLOAT3D(
- _pacpi[iFrame].cpi_fOffsetRatioX,
- _pacpi[iFrame].cpi_fOffsetRatioY,
- _pacpi[iFrame].cpi_fOffsetRatioZ);
- ANGLE3D ang=ANGLE3D(
- _pacpi[iFrame].cpi_angH,
- _pacpi[iFrame].cpi_angP,
- _pacpi[iFrame].cpi_angB);
- FLOAT fFCD=Max(
- Abs(vRatio(1))*vSize(1), Max(
- Abs(vRatio(2))*vSize(2),
- Abs(vRatio(3))*vSize(3)));
- prIsometricProjection.FarClipDistanceL() = fFCD;
- prIsometricProjection.AspectRatioL() = 1.0f;
- // set up viewer position
- apr = prIsometricProjection;
- FLOAT3D vPos=FLOAT3D(
- vRatio(1)*vHSize(1),
- vRatio(2)*vHSize(2),
- vRatio(3)*vHSize(3))+box.Center();
- FLOAT fMaxSize;
- if( vRatio(1)!=0)
- {
- fMaxSize=Max(vSize(2),vSize(3));
- }
- else if( vRatio(2)!=0)
- {
- fMaxSize=Max(vSize(1),vSize(3));
- }
- else
- {
- fMaxSize=Max(vSize(1),vSize(2));
- }
-
- prIsometricProjection.ZoomFactorL()=pdp->GetWidth()/fMaxSize;
- CPlacement3D plViewer=CPlacement3D(vPos, ang);
- //plViewer.RelativeToAbsolute(plEntity);
- apr=prIsometricProjection;
- apr->ViewerPlacementL() = plViewer;
- apr->ObjectPlacementL() = CPlacement3D(FLOAT3D(0,0,0), ANGLE3D(0,0,0));
- apr->Prepare();
- }
- BOOL CWorldEditorView::SaveAutoTexture(FLOATaabbox3D boxBrush, CTFileName &fnTex)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CDlgAutTexturize dlg;
- if( dlg.DoModal()!=IDOK) return FALSE;
- // call file requester for pretender texture name
- CTFileName fnPretenderTexture = _EngineGUI.FileRequester( "Pretender texture name",
- FILTER_TGA FILTER_END, "Auto save texture", "", "", NULL, TRUE);
- if( fnPretenderTexture == "") return FALSE;
- switch( dlg.m_iPretenderStyle)
- {
- case 0: _pacpi=acpiF; _ctProjections=1; break;
- case 1: _pacpi=acpi2x2; _ctProjections=4; break;
- case 2: _pacpi=acpi3x2; _ctProjections=6; break;
- default: _pacpi=acpi3x2; _ctProjections=6; break;
- }
- CDrawPort *pdp;
- CImageInfo II;
- CTextureData TD;
- CAnimData AD;
- ULONG flags = NONE;
- CChildFrame *pChild = GetChildFrame();
- // create canvas to render picture
- _pGfx->CreateWorkCanvas( dlg.m_pixWidth, dlg.m_pixHeight, &pdp);
- if( pdp != NULL)
- {
- FLOAT3D vSize=boxBrush.Size();
- for(INDEX iFrame=0; iFrame<_ctProjections; iFrame++)
- {
- CameraProjectionInfo &cpi=_pacpi[iFrame];
- CDrawPort dpClone( pdp, cpi.cpi_rMinI, cpi.cpi_rMinJ, cpi.cpi_rSizeI, cpi.cpi_rSizeJ);
- // clone draw port
- if( dpClone.Lock())
- {
- dpClone.FillZBuffer(ZBUF_BACK);
- CAnyProjection3D apr;
- SetupView(iFrame, &dpClone, apr, boxBrush);
- // store rendering preferences
- BOOL bWasBcgOn = _wrpWorldRenderPrefs.IsBackgroundTextureOn();
- CWorldRenderPrefs::SelectionType stBefore=_wrpWorldRenderPrefs.GetSelectionType();
- _wrpWorldRenderPrefs.SetBackgroundTextureOn( FALSE);
- _wrpWorldRenderPrefs.SetSelectionType( CWorldRenderPrefs::ST_NONE);
- COLOR colOld=pDoc->m_woWorld.GetBackgroundColor();
- pDoc->m_woWorld.SetBackgroundColor(dlg.m_colBcg.GetColor());
- // render view
- ::RenderView(pDoc->m_woWorld, *(CEntity*)NULL, apr, dpClone);
- // restore rendering preferences
- pDoc->m_woWorld.SetBackgroundColor(colOld);
- _wrpWorldRenderPrefs.SetSelectionType(stBefore);
- _wrpWorldRenderPrefs.SetBackgroundTextureOn( bWasBcgOn);
- }
- dpClone.Unlock();
- }
- pdp->GrabScreen( II, 2);
- if( dlg.m_bExpandEdges)
- {
- II.ExpandEdges();
- }
- // try to
- try {
- // save screen shot as TGA
- II.SaveTGA_t( fnPretenderTexture);
- fnTex=fnPretenderTexture.NoExt()+".tex";
- // create temporary texture
- CreateTexture_t( fnPretenderTexture, fnTex,
- dlg.m_pixWidth, MAX_MEX_LOG2+1, FALSE);
- _EngineGUI.CreateTexture( fnTex);
- } // if failed
- catch (char *strError) {
- // report error
- AfxMessageBox(CString(strError));
- }
- }
- return TRUE;
- }
- INDEX _aiMinMax[] =
- {
- 0,0,1,
- 1,0,1,
- 1,0,0,
- 0,0,0,
- 0,1,1,
- 1,1,1,
- 1,1,0,
- 0,1,0
- };
- INDEX _aiPlaneVtx[] =
- {
- 4,0,1,5,
- 5,1,2,6,
- 6,2,3,7,
- 7,3,0,4,
- 7,4,5,6,
- 0,3,2,1,
- };
- FLOAT3D _avBoxVtx[8];
- struct BoxPlaneParams {
- FLOATplane3D bpp_plPlane;
- CMappingVectors bpp_mvDefault;
- CMappingVectors bpp_mvVectors;
- CMappingDefinition bpp_mdMappingDefinition;
- };
- BoxPlaneParams _abpp[6];
- BOOL CWorldEditorView::SetAutoTextureBoxParams(FLOATaabbox3D boxBrush, CTFileName &fnTex)
- {
- CTextureData *pTD=NULL;
- try
- {
- pTD=_pTextureStock->Obtain_t( fnTex);
- }
- catch (char *strError)
- {
- WarningMessage(strError);
- return FALSE;
- }
-
- // create box vertices
- FLOAT3D vMin=boxBrush.Min();
- FLOAT3D vMax=boxBrush.Max();
- FLOAT3D vSize=boxBrush.Size();
- for( INDEX iVtx=0; iVtx<8; iVtx++)
- {
- FLOAT fX=_aiMinMax[iVtx*3+0]*vSize(1)+vMin(1);
- FLOAT fY=_aiMinMax[iVtx*3+1]*vSize(2)+vMin(2);
- FLOAT fZ=_aiMinMax[iVtx*3+2]*vSize(3)+vMin(3);
- _avBoxVtx[iVtx]=FLOAT3D(fX,fY,fZ);
- }
-
- // create box planes
- for( INDEX iPlane=0; iPlane<_ctProjections; iPlane++)
- {
- CameraProjectionInfo &cpi=_pacpi[iPlane];
- // create plane
- BoxPlaneParams &bpp=_abpp[iPlane];
- FLOAT3D &vVtx0=_avBoxVtx[_aiPlaneVtx[iPlane*4+0]];
- FLOAT3D &vVtx1=_avBoxVtx[_aiPlaneVtx[iPlane*4+1]];
- FLOAT3D &vVtx2=_avBoxVtx[_aiPlaneVtx[iPlane*4+2]];
- FLOAT3D &vVtx3=_avBoxVtx[_aiPlaneVtx[iPlane*4+3]];
- bpp.bpp_plPlane=FLOATplane3D(vVtx0, vVtx1, vVtx2);
- // create mapping vectors
- bpp.bpp_mvDefault.FromPlane(bpp.bpp_plPlane);
- bpp.bpp_mvVectors.mv_vO=(vVtx0+vVtx2)/2.0f;
- FLOAT3D vDeltaU=vVtx3-vVtx0;
- FLOAT3D vDeltaV=vVtx1-vVtx0;
- FLOAT fStretch = Max(vDeltaU.Length(), vDeltaV.Length())/(pTD->GetWidth()/1024.0f*cpi.cpi_rSizeI);
- bpp.bpp_mvVectors.mv_vU=vDeltaU.Normalize()*fStretch;
- bpp.bpp_mvVectors.mv_vV=vDeltaV.Normalize()*fStretch;
- bpp.bpp_mdMappingDefinition.FromMappingVectors(bpp.bpp_mvDefault, bpp.bpp_mvVectors);
- MEX mexOffsetU = pTD->GetWidth() *(cpi.cpi_rMinI+cpi.cpi_rSizeI/2);
- MEX mexOffsetV = pTD->GetHeight()*(cpi.cpi_rMinJ+cpi.cpi_rSizeJ/2);
- bpp.bpp_mdMappingDefinition.md_fUOffset-=mexOffsetU/1024.0f;
- bpp.bpp_mdMappingDefinition.md_fVOffset-=mexOffsetV/1024.0f;
- }
- return TRUE;
- }
- void CWorldEditorView::AutoApplyTextureOntoPolygon(CBrushPolygon &bpo, FLOATaabbox3D boxBrush, CTFileName &fnTex)
- {
- // get box polygon that has smallest scalar product with our polygon
- FLOAT fMaxScalar=-1e6f;
- INDEX iMaxPlane=0;
- FLOATplane3D &plPlaneAbs=bpo.bpo_pbplPlane->bpl_plAbsolute;
- FLOATplane3D &plPlaneRel=bpo.bpo_pbplPlane->bpl_plRelative;
- for(INDEX iPlane=0; iPlane<6; iPlane++)
- {
- BoxPlaneParams &bpp=_abpp[iPlane];
- FLOAT fScalar=plPlaneAbs%bpp.bpp_plPlane;
- if( fScalar>fMaxScalar)
- {
- iMaxPlane=iPlane;
- fMaxScalar=fScalar;
- }
- }
-
- BoxPlaneParams &bpp=_abpp[iMaxPlane];
- CBrushPolygonTexture &bbpt0=bpo.bpo_abptTextures[0];
- CBrushPolygonTexture &bbpt1=bpo.bpo_abptTextures[1];
- CBrushPolygonTexture &bbpt2=bpo.bpo_abptTextures[2];
- try
- {
- bbpt0.CopyTextureProperties(CBrushPolygonTexture(),TRUE);
- bbpt0.bpt_toTexture.SetData_t(fnTex);
- bbpt1.bpt_toTexture.SetData(NULL);
- bbpt2.bpt_toTexture.SetData(NULL);
- // get the mapping in relative space of the brush polygon's entity
- CEntity *pen = bpo.bpo_pbscSector->bsc_pbmBrushMip->bm_pbrBrush->br_penEntity;
- CSimpleProjection3D pr;
- pr.ObjectPlacementL() = _plOrigin;
- pr.ViewerPlacementL() = pen->GetPlacement();
- pr.Prepare();
- FLOATplane3D plRelative;
- pr.Project(bpp.bpp_plPlane, plRelative);
- CMappingDefinition mdRelative = bpp.bpp_mdMappingDefinition;
- mdRelative.Transform(bpp.bpp_plPlane, _plOrigin, pen->GetPlacement());
- bbpt0.bpt_mdMapping.ProjectMapping(plRelative, mdRelative, plPlaneRel);
-
- bpo.bpo_ulFlags |= BPOF_FULLBRIGHT;
- bpo.bpo_smShadowMap.Uncache();
- bpo.DiscardShadows();
- }
- catch (char *strError)
- {
- WarningMessage(strError);
- }
- }
- void CWorldEditorView::AutoApplyTexture(FLOATaabbox3D boxBrush, CTFileName &fnTex)
- {
- if( !SetAutoTextureBoxParams(boxBrush, fnTex)) return;
- CWorldEditorDoc* pDoc = GetDocument();
- // textureize mip levels
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- CEntity *pen=&*iten;
- if( pen->GetRenderType() == CEntity::RT_BRUSH)
- {
- CBrush3D *pbrBrush=pen->GetBrush();
- // for each mip in the brush
- BOOL bFirstMip=TRUE;
- FOREACHINLIST(CBrushMip, bm_lnInBrush, pbrBrush->br_lhBrushMips, itbm)
- {
- if( bFirstMip)
- {
- bFirstMip=FALSE;
- continue;
- }
- // for all sectors in this mip
- FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc) {
- // for each polygon in sector
- FOREACHINSTATICARRAY(itbsc->bsc_abpoPolygons, CBrushPolygon, itbpo) {
- CBrushPolygon &bpo = *itbpo;
- AutoApplyTextureOntoPolygon(bpo, boxBrush, fnTex);
- }
- }
- }
- }
- }
- }
- void CWorldEditorView::OnAutotexturizeMips()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- FLOATaabbox3D boxBrush;
- // for each entity in the world
- {FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- CEntity *pen=&*iten;
- if( pen->GetRenderType() == CEntity::RT_BRUSH)
- {
- CBrush3D *pbrBrush=pen->GetBrush();
- CBrushMip *pbrMip=pbrBrush->GetFirstMip();
- boxBrush|=pbrMip->bm_boxBoundingBox;
- }
- }}
- CTFileName fnTex;
- BOOL bSuccess=SaveAutoTexture( boxBrush, fnTex);
- if( !bSuccess) return;
- AutoApplyTexture( boxBrush, fnTex);
- // mark that selections have been changed
- pDoc->UpdateAllViews( NULL);
- pDoc->SetModifiedFlag();
- }
- void CWorldEditorView::OnUpdateAutotexturizeMips(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pCmdUI->Enable(pDoc->m_selEntitySelection.Count()!=0);
- }
- void CWorldEditorView::OnRandomOffsetU()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // for each selected polygon
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- CTextureData *pTD = (CTextureData *) itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.GetData();
- if( pTD != NULL)
- {
- // add rnd offsets to mapping
- itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.md_fUOffset+=((FLOAT)rand())/RAND_MAX*pTD->GetWidth();
- }
- }
- }
- void CWorldEditorView::OnRandomOffsetV()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // for each selected polygon
- FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- CTextureData *pTD = (CTextureData *) itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.GetData();
- if( pTD != NULL)
- {
- // add rnd offsets to mapping
- itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.md_fVOffset+=((FLOAT)rand())/RAND_MAX*pTD->GetHeight();
- }
- }
- }
- void CWorldEditorView::OnStretchRelativeOffset()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if(m_penEntityHitOnContext==NULL) return;
- CDlgStretchChildOffset dlg;
- if( dlg.DoModal()!=IDOK) return;
- if( m_penEntityHitOnContext->IsSelected(ENF_SELECTED))
- {
- FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
- {
- if( iten->GetParent()!=NULL)
- {
- CPlacement3D pl=iten->GetPlacement();
- CPlacement3D plParent=iten->GetParent()->GetPlacement();
- pl.AbsoluteToRelative(plParent);
- FLOAT3D vRelPos=pl.pl_PositionVector;
- vRelPos*=dlg.m_fStretchValue;
- // set stretched offset
- pl.pl_PositionVector=vRelPos;
- pl.RelativeToAbsolute(plParent);
- iten->SetPlacement(pl);
- }
- }
- }
- else
- {
- if( m_penEntityHitOnContext->GetParent()!=NULL)
- {
- CPlacement3D pl=m_penEntityHitOnContext->GetPlacement();
- CPlacement3D plParent=m_penEntityHitOnContext->GetParent()->GetPlacement();
- pl.AbsoluteToRelative(plParent);
- FLOAT3D vRelPos=pl.pl_PositionVector;
- vRelPos*=dlg.m_fStretchValue;
- // set stretched offset
- pl.pl_PositionVector=vRelPos;
- pl.RelativeToAbsolute(plParent);
- m_penEntityHitOnContext->SetPlacement(pl);
- }
- }
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnDeselectHidden()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // for all of the world's entities
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- // if the entity is hidden and selected
- if (iten->en_ulFlags&ENF_HIDDEN && iten->IsSelected( ENF_SELECTED))
- {
- // deselect it
- pDoc->m_selEntitySelection.Deselect( *iten);
- }
- }
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnSelectHidden()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- // for all of the world's entities
- FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
- {
- // if the entity is hidden and selected
- if (iten->en_ulFlags&ENF_HIDDEN && !iten->IsSelected( ENF_SELECTED))
- {
- // select it
- pDoc->m_selEntitySelection.Select( *iten);
- }
- }
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnSectorsToBrush()
- {
- CBrushPolygonSelection selPolygons;
- CWorldEditorDoc* pDoc = GetDocument();
- if(pDoc->m_selSectorSelection.Count()==0) return;
- pDoc->RememberUndo();
- pDoc->ClearSelections(ST_SECTOR);
- // make polygon selection
- FOREACHINDYNAMICCONTAINER(pDoc->m_selSectorSelection, CBrushSector, itbsc)
- {
- FOREACHINSTATICARRAY(itbsc->bsc_abpoPolygons, CBrushPolygon, itbpo)
- {
- selPolygons.Select( *itbpo);
- }
- }
- PolygonsToBrush(selPolygons, FALSE, TRUE);
- selPolygons.CDynamicContainer<CBrushPolygon>::Clear();
- }
- void CWorldEditorView::PolygonsToBrush(CBrushPolygonSelection &selPolygons, BOOL bDeleteSectors, BOOL bZoning)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- FLOATaabbox3D boxPolygons;
- // get bbox of selected polygons
- FOREACHINDYNAMICCONTAINER(selPolygons, CBrushPolygon, itbpo)
- {
- boxPolygons |= itbpo->bpo_boxBoundingBox;
- }
- CPlacement3D plCenterDown=CPlacement3D(FLOAT3D(0,0,0), ANGLE3D(0,0,0));
- plCenterDown.pl_PositionVector=FLOAT3D(boxPolygons.Center()(1),boxPolygons.Min()(2),boxPolygons.Center()(3));
- CEntity *penwb=theApp.CreateWorldBaseEntity(pDoc->m_woWorld, bZoning, plCenterDown);
- if( penwb==NULL) return;
- pDoc->m_woWorld.CopyPolygonsToBrush(selPolygons, penwb);
- if(bDeleteSectors)
- {
- // delete old sectors
- pDoc->m_woWorld.DeleteSectors( pDoc->m_selSectorSelection, FALSE);
- }
- pDoc->ClearSelections();
- pDoc->m_chSelections.MarkChanged();
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnPolygonsToBrush()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->m_selPolygonSelection.Count()==0) return;
- pDoc->RememberUndo();
- CDynamicContainer<CBrushPolygon> dcPolygons;
- StorePolygonSelection( pDoc->m_selPolygonSelection, dcPolygons);
- PolygonsToBrush(pDoc->m_selPolygonSelection, FALSE, FALSE);
- pDoc->m_woWorld.DeletePolygons(dcPolygons);
- }
- void CWorldEditorView::OnClonePolygons()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->m_selPolygonSelection.Count()==0) return;
- pDoc->RememberUndo();
- PolygonsToBrush(pDoc->m_selPolygonSelection, FALSE, FALSE);
- }
- void CWorldEditorView::OnDeletePolygons()
- {
- CDynamicContainer<CBrushPolygon> dcPolygons;
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->m_selPolygonSelection.Count()==0) return;
- pDoc->RememberUndo();
- StorePolygonSelection( pDoc->m_selPolygonSelection, dcPolygons);
- pDoc->ClearSelections();
- pDoc->m_woWorld.DeletePolygons(dcPolygons);
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnKeyU()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- OnKeyPasteAsProjected();
- }
- else if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- theApp.m_iTerrainEditMode=TEM_HEIGHTMAP;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- }
- void CWorldEditorView::OnKeyD()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == ENTITY_MODE)
- {
- OnDropMarker();
- }
- if( (pDoc->GetEditingMode() == POLYGON_MODE) ||
- (pDoc->GetEditingMode() == VERTEX_MODE) )
- {
- OnFlipPolygon();
- }
- if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- theApp.m_iTerrainBrushMode=TBM_ERASE;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- pDoc->SetStatusLineModeInfoMessage();
- }
- }
- void CWorldEditorView::OnFlipPolygon()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- BOOL bSelection=TRUE;
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse, FALSE, FALSE, FALSE);
- CBrushPolygon *pbpoHit=crRayHit.cr_pbpoBrushPolygon;
- if( (pbpoHit!=NULL) && !pbpoHit->IsSelected( BPOF_SELECTED) )
- {
- bSelection=FALSE;
- }
- CDynamicContainer<CBrushPolygon> dcPolygons;
- CDynamicContainer<CBrushSector> dcSectors;
- if( bSelection)
- {
- FOREACHINDYNAMICCONTAINER( pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
- {
- dcPolygons.Add( itbpo);
- if( !dcSectors.IsMember(itbpo->bpo_pbscSector))
- {
- dcSectors.Add(itbpo->bpo_pbscSector);
- }
- }
- }
- else
- {
- pDoc->m_selPolygonSelection.Clear();
- dcPolygons.Add( pbpoHit);
- dcSectors.Add(pbpoHit->bpo_pbscSector);
- }
- pDoc->ClearSelections();
- FOREACHINDYNAMICCONTAINER(dcPolygons, CBrushPolygon, itbpo)
- {
- CBrushPolygon &bpo = *itbpo;
- pDoc->m_woWorld.FlipPolygon(bpo);
- }
- FOREACHINDYNAMICCONTAINER( dcSectors, CBrushSector, itbsc)
- {
- itbsc->UpdateSector();
- }
- {FOREACHINDYNAMICCONTAINER(dcPolygons, CBrushPolygon, itbpo)
- {
- CBrushPolygon &bpo = *itbpo;
- INDEX iTriVtx=bpo.bpo_aiTriangleElements.Count();
- INDEX tmpa=0;
- }}
- pDoc->SetModifiedFlag( TRUE);
- pDoc->UpdateAllViews( NULL);
- }
- void CWorldEditorView::OnKeyM()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == POLYGON_MODE)
- {
- // obtain information about where mouse points into the world
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- // if we hit brush entity
- if( (crRayHit.cr_penHit != NULL) &&
- (crRayHit.cr_pbpoBrushPolygon != NULL) )
- {
- CopyMapping(crRayHit.cr_pbpoBrushPolygon);
- }
- }
- else if( pDoc->GetEditingMode() == VERTEX_MODE)
- {
- OnMergeVertices();
- }
- else if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- theApp.m_iTerrainBrushMode=TBM_MINIMUM;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- pDoc->SetStatusLineModeInfoMessage();
- }
- }
- void CWorldEditorView::OnSelectBrush()
- {
- CPoint ptMouse;
- GetCursorPos( &ptMouse);
- InvokeTerrainBrushPalette( ptMouse.x-BRUSH_PALETTE_WIDTH/2, ptMouse.y+BRUSH_PALETTE_HEIGHT/2);
- }
- void CWorldEditorView::OnSelectTerrain()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CCastRay crRayHit = GetMouseHitInformation( m_ptMouse);
- if( (crRayHit.cr_penHit!=NULL) && (crRayHit.cr_penHit->GetRenderType() == CEntity::RT_TERRAIN) &&
- (crRayHit.cr_penHit!=GetTerrainEntity()) )
- {
- pDoc->m_ptrSelectedTerrain=crRayHit.cr_penHit->GetTerrain();
- theApp.m_ctTerrainPage.MarkChanged();
- }
- }
- void CWorldEditorView::OnAltitudeEditMode()
- {
- theApp.m_iTerrainEditMode=TEM_HEIGHTMAP;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnLayerTextureEditMode()
- {
- theApp.m_iTerrainEditMode=TEM_LAYER;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnOptimizeTerrain()
- {
- OptimizeLayers();
- }
- void CWorldEditorView::OnRecalculateTerrainShadows()
- {
- CTerrain *ptrTerrain=GetTerrain();
- if( ptrTerrain==NULL) return;
- ptrTerrain->UpdateShadowMap();
- }
- void CWorldEditorView::OnViewHeightmap()
- {
- POINT pt;
- GetCursorPos(&pt);
- pt.x-=32;
- pt.y+=32;
- DisplayHeightMapWindow(pt);
- }
- void CWorldEditorView::OnImportHeightmap()
- {
- ApplyImportExport(0);
- }
- void CWorldEditorView::OnImportHeightmap16()
- {
- ApplyImportExport(1);
- }
- void CWorldEditorView::OnExportHeightmap()
- {
- ApplyImportExport(2);
- }
- void CWorldEditorView::OnExportHeightmap16()
- {
- ApplyImportExport(3);
- }
- void CWorldEditorView::OnSelectLayer()
- {
- InvokeSelectLayerCombo();
- }
- void CWorldEditorView::OnPickLayer()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- CCastRay crRayHit=GetMouseHitInformation( m_ptMouse);
- if( (crRayHit.cr_penHit!=NULL) && (crRayHit.cr_penHit->GetRenderType() == CEntity::RT_TERRAIN))
- {
- CTerrain *ptrTerrain=crRayHit.cr_penHit->GetTerrain();
- Point pt=Calculate2dHitPoint(ptrTerrain, crRayHit.cr_vHit);
- // in altitude mode
- if(theApp.m_iTerrainEditMode==TEM_HEIGHTMAP)
- {
- // pick altitude
- INDEX iWidth=ptrTerrain->tr_pixHeightMapWidth;
- UWORD *puw=ptrTerrain->tr_auwHeightMap+iWidth*pt.pt_iY+pt.pt_iX;
- theApp.m_uwEditAltitude=*puw;
- }
- // in layer mode
- else
- {
- // pick layer
- INDEX ctLayers=ptrTerrain->tr_atlLayers.Count();
- for(INDEX iLayer=ctLayers-1; iLayer>=0; iLayer--)
- {
- UBYTE ubPower=GetValueFromMask(ptrTerrain, iLayer, crRayHit.cr_vHit);
- if(ubPower>0)
- {
- SelectLayer(iLayer);
- CTerrainLayer *ptlLayer=&ptrTerrain->tr_atlLayers[iLayer];
- if(ptlLayer->tl_ltType==LT_TILE)
- {
- CDynamicContainer<CTileInfo> dcTileInfo;
- INDEX ctTilesPerRaw=0;
- ObtainLayerTileInfo( &dcTileInfo, ptlLayer->tl_ptdTexture, ctTilesPerRaw);
- INDEX ctTiles=dcTileInfo.Count();
- for(INDEX iTile=0; iTile<ctTiles; iTile++)
- {
- CTileInfo &ti=dcTileInfo[iTile];
- if( ((ubPower&TL_TILE_INDEX)==(ti.ti_iy*ptlLayer->tl_ctTilesInRow+ti.ti_ix) ) &&
- (ubPower&TL_VISIBLE) &&
- (!(ubPower&TL_FLIPX) == !ti.ti_bFlipX) &&
- (!(ubPower&TL_FLIPY) == !ti.ti_bFlipY) &&
- (!(ubPower&TL_SWAPXY) == !ti.ti_bSwapXY) )
- {
- ptlLayer->tl_iSelectedTile=iTile;
- break;
- }
- }
- }
- else
- {
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- }
- break;
- }
- }
- }
- }
- }
- void CWorldEditorView::OnIdle(void)
- {
- POINT point;
- GetCursorPos(&point);
- HWND hwndUnderMouse = ::WindowFromPoint(point);
- if( ::GetParent(hwndUnderMouse)==m_hWnd)
- {
- UpdateCursor();
- }
-
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode()==TERRAIN_MODE && m_iaInputAction==IA_NONE)
- {
- UpdateLayerDistribution();
- }
- }
- void CWorldEditorView::OnPosterize()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- theApp.m_iTerrainBrushMode=TBM_POSTERIZE;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- }
- void CWorldEditorView::OnFlatten()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode() == TERRAIN_MODE)
- {
- theApp.m_iTerrainBrushMode=TBM_FLATTEN;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- }
- void CWorldEditorView::OnApplyFilter()
- {
- ApplyFilterOntoTerrain();
- }
- void CWorldEditorView::OnTeSmooth()
- {
- ApplySmoothOntoTerrain();
- }
- void CWorldEditorView::OnEditTerrainPrefs()
- {
- CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- CDlgTEOperationSettings dlg(pMainFrame);
- dlg.DoModal();
- }
- void CWorldEditorView::OnUpdateEditTerrainPrefs(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pCmdUI->Enable( pDoc->GetEditingMode()==TERRAIN_MODE);
- }
- void CWorldEditorView::OnKeyCtrlShiftG()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if(pDoc->GetEditingMode()==TERRAIN_MODE)
- {
- RandomizeWhiteNoise();
- ApplyGenerateTerrain();
- }
- else
- {
- GetChildFrame()->OnGridOnOff();
- }
- }
- void CWorldEditorView::OnUpdateKeyCtrlShiftG(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if(pDoc->GetEditingMode()==TERRAIN_MODE)
- {
- pCmdUI->Enable( TRUE);
- }
- else
- {
- GetChildFrame()->OnUpdateGridOnOff(pCmdUI);
- }
- }
- void CWorldEditorView::OnTerrainLayerOptions()
- {
- CTerrainLayer *ptlLayer=GetLayer();
- if(ptlLayer==NULL) return;
- CDlgEditTerrainLayer dlg;
- if( dlg.DoModal()==IDOK)
- {
- INDEX iLayer=GetLayerIndex();
- GenerateLayerDistribution(iLayer);
- }
- }
- void CWorldEditorView::OnUpdateTerrainLayerOptions(CCmdUI* pCmdUI)
- {
- CWorldEditorDoc* pDoc = GetDocument();
- pCmdUI->Enable( pDoc->GetEditingMode()==TERRAIN_MODE);
- }
- void CWorldEditorView::OnApplyContinousNoise()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode()==TERRAIN_MODE && GetTerrain()!=NULL)
- {
- ApplyContinousNoiseOntoTerrain();
- }
- }
- void CWorldEditorView::OnApplyMinimum()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode()==TERRAIN_MODE && GetTerrain()!=NULL)
- {
- ApplyMinimumOntoTerrain();
- }
- }
- void CWorldEditorView::OnApplyMaximum()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode()==TERRAIN_MODE && GetTerrain()!=NULL)
- {
- ApplyMaximumOntoTerrain();
- }
- }
- void CWorldEditorView::OnApplyFlatten()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode()==TERRAIN_MODE && GetTerrain()!=NULL)
- {
- ApplyFlattenOntoTerrain();
- }
- }
- void CWorldEditorView::OnApplyPosterize()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode()==TERRAIN_MODE && GetTerrain()!=NULL)
- {
- ApplyPosterizeOntoTerrain();
- }
- }
- void CWorldEditorView::OnOptimizeLayers()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode()==TERRAIN_MODE && GetTerrain()!=NULL)
- {
- OptimizeLayers();
- }
- }
- void CWorldEditorView::OnTbrushAltitude()
- {
- theApp.m_iTerrainBrushMode=TBM_PAINT;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnTbrushSmooth()
- {
- theApp.m_iTerrainBrushMode=TBM_SMOOTH;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnTbrushEquilaze()
- {
- theApp.m_iTerrainBrushMode=TBM_FLATTEN;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnTbrushErase()
- {
- theApp.m_iTerrainBrushMode=TBM_ERASE;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnTbrushNoise()
- {
- theApp.m_iTerrainBrushMode=TBM_RND_NOISE;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnTbrushContinousNoise()
- {
- theApp.m_iTerrainBrushMode=TBM_CONTINOUS_NOISE;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnTbrushFilter()
- {
- theApp.m_iTerrainBrushMode=TBM_FILTER;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnTbrushFlatten()
- {
- theApp.m_iTerrainBrushMode=TBM_FLATTEN;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnTbrushMaximum()
- {
- theApp.m_iTerrainBrushMode=TBM_MAXIMUM;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnTbrushMinimum()
- {
- theApp.m_iTerrainBrushMode=TBM_MINIMUM;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnTbrushPosterize()
- {
- theApp.m_iTerrainBrushMode=TBM_POSTERIZE;
- theApp.m_ctTerrainPageCanvas.MarkChanged();
- GetDocument()->SetStatusLineModeInfoMessage();
- }
- void CWorldEditorView::OnTerrainProperties()
- {
- CWorldEditorDoc* pDoc = GetDocument();
- if( pDoc->GetEditingMode()==TERRAIN_MODE && GetTerrain()!=NULL)
- {
- CDlgTerrainProperties dlg;
- dlg.DoModal();
- }
- }
|