123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789 |
- //
- // The graphics engine GXScene
- //
- unit Formatx.m3DSUtils;
- (*
- Utility functions for the universal 3DS file reader and writer (TFile3DS).
- Essentially, the functions here are the heart of the import library as
- they deal actually with the database and chunks.
- *)
- interface
- {$I Stage.Defines.inc}
- {$R-}
- uses
- System.Classes,
- System.SysUtils,
- Formatx.m3DS,
- Formatx.m3DSTypes,
- Formatx.m3DSConst,
- Stage.Strings;
- // functions to retrieve global settings of a specific 3DS database
- function GetAtmosphere(const Source: TFile3DS; var DB: TDatabase3DS): TAtmosphere3DS;
- function GetBackground(const Source: TFile3DS; var DB: TDatabase3DS): TBackground3DS;
- function GetMeshSet(const Source: TFile3DS; var DB: TDatabase3DS): TMeshSet3DS;
- function GetViewport(const Source: TFile3DS; var DB: TDatabase3DS): TViewport3DS;
- // functions to retrieve/modify data related to materials, lights and objects (meshs)
- procedure AddChild(Parent, Child: PChunk3DS);
- procedure AddChildOrdered(Parent, Child: PChunk3DS);
- function FindChunk(Top: PChunk3DS; Tag: word): PChunk3DS;
- function FindNextChunk(Local: PChunk3DS; Tag: word): PChunk3DS;
- procedure FreeChunkData(var Chunk: PChunk3DS);
- function GetCameraByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: integer): TCamera3DS;
- function GetCameraCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- function GetChunkValue(Tag: word): integer;
- function GetMaterialByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: integer): TMaterial3DS;
- function GetMaterialCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- function GetMeshByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: integer): TMesh3DS;
- function GetMeshCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- function GetOmnilightByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: integer): TLight3DS;
- function GetSpotlightByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: integer): TLight3DS;
- function GetOmnilightCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- function GetSpotlightCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- procedure InitChunk(var Chunk: PChunk3DS);
- procedure ReleaseCamera(Camera: PCamera3DS);
- procedure ReleaseChunk(var Chunk: PChunk3DS);
- procedure ReleaseChunkList(var List: PChunkList3DS);
- procedure ReleaseLight(Light: PLight3DS);
- procedure ReleaseMaterial(Mat: PMaterial3DS);
- procedure ReleaseMeshObj(Mesh: PMesh3DS);
- // functions to retrieve/modify keyframer (animation) data
- function GetKFSettings(const Source: TFile3DS; var DB: TDatabase3DS): TKFSets3DS;
- procedure ReleaseCameraMotion(Camera: PKFCamera3DS);
- procedure GetCameraNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
- List: TStringList);
- function GetCameraNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- function GetCameraMotion(const Source: TFile3DS;
- CamChunk, TargetChunk: PChunk3DS): TKFCamera3DS;
- function GetCameraMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: integer): TKFCamera3DS;
- procedure ReleaseAmbientLightMotion(Light: PKFAmbient3DS);
- function GetAmbientLightMotion(const Source: TFile3DS;
- var DB: TDatabase3DS): TKFAmbient3DS;
- procedure InitObjectMotion(var Obj: TKFMesh3DS;
- NewNPKeys, NewNRKeys, NewNSKeys, NewNMKeys, NewNHKeys: cardinal);
- procedure ReleaseObjectMotion(Obj: PKFMesh3DS);
- procedure GetObjectNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
- List: TStringList);
- function GetObjectNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- function GetObjectMotionByName(const Source: TFile3DS; var DB: TDatabase3DS;
- const Name: string): TKFMesh3DS;
- function GetObjectMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: cardinal): TKFMesh3DS;
- procedure ReleaseOmnilightMotion(Light: PKFOmni3DS);
- procedure GetOmnilightNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
- List: TStringList);
- function GetOmnilightNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): cardinal;
- function GetOmnilightMotionByName(const Source: TFile3DS; var DB: TDatabase3DS;
- const Name: string): TKFOmni3DS;
- function GetOmnilightMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: cardinal): TKFOmni3DS;
- procedure ReleaseSpotlightMotion(Spot: PKFSpot3DS);
- procedure GetSpotlightNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
- List: TStringList);
- function GetSpotlightNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): cardinal;
- function GetSpotlightMotionByName(const Source: TFile3DS; var DB: TDatabase3DS;
- const Name: string): TKFSpot3DS;
- function GetSpotlightMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: cardinal): TKFSpot3DS;
- // version information
- function GetM3dMagicRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
- function GetMeshRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
- function GetKfRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
- function GetDatabaseRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
- // support functions for text output of chunk and database contents
- procedure ChunkHeaderReport(var Strings: TStrings; Chunk: PChunk3DS;
- IndentLevel: integer);
- function ChunkTagToString(Tag: word): string;
- procedure DumpChunk(const Source: TFile3DS; var Strings: TStrings;
- Chunk: PChunk3DS; IndentLevel: integer; DumpLevel: TDumpLevel);
- procedure DumpKeyHeader(Strings: TStrings; const Key: TKeyHeader3DS; IndentLevel: integer);
- // support functions for chunk handling
- procedure DeleteChunk(var Chunk: PChunk3DS);
- function FindNamedObjectByIndex(Source: TFile3DS; DB: TDatabase3DS;
- AType: word; Index: integer): PChunk3DS;
- // error message routines
- procedure ShowError(const ErrorMessage: string);
- procedure ShowErrorFormatted(const ErrorMessage: string; const Args: array of const);
- implementation //--------------------------------------------------------------
- type
- E3DSError = class(Exception);
- //----------------- error handling --------------------------------------------
- procedure ShowError(const ErrorMessage: string);
- begin
- raise E3DSError.Create(ErrorMessage);
- end;
- //-----------------------------------------------------------------------------
- procedure ShowErrorFormatted(const ErrorMessage: string; const Args: array of const);
- begin
- raise E3DSError.CreateFmt(ErrorMessage, Args);
- end;
- //----------------- global settings functions ---------------------------------
- function InitMeshSet: TMeshSet3DS;
- // initializes a mesh settings structure
- begin
- FillChar(Result, SizeOf(Result), 0);
- with Result do
- begin
- MasterScale := 1;
- Shadow.Bias := 1;
- Shadow.RayBias := 1;
- Shadow.MapSize := 512;
- Shadow.Filter := 3;
- AmbientLight.R := 0.39216;
- AmbientLight.G := 0.39216;
- AmbientLight.B := 0.39216;
- end;
- end;
- //-----------------------------------------------------------------------------
- function GetMeshSet(const Source: TFile3DS; var DB: TDatabase3DS): TMeshSet3DS;
- // retrieves the mesh settings from the database
- var
- MDataChunk, ColorChunk, Chunk: PChunk3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- // find the mesh data chunk
- MDataChunk := FindChunk(DB.TopChunk, MDATA);
- // If the mesh data section is found
- if Assigned(MDataChunk) then
- begin
- Result := InitMeshSet;
- with Result do
- begin
- // Search for a master_scale chunk
- Chunk := FindNextChunk(MDataChunk^.Children, MASTER_SCALE);
- if Assigned(Chunk) then
- begin
- Source.ReadChunkData(Chunk);
- MasterScale := Chunk^.Data.MasterScale^;
- FreeChunkData(Chunk);
- end;
- // search for Lo_Shadow_Bias chunk
- Chunk := FindNextChunk(MDataChunk^.Children, LO_SHADOW_BIAS);
- if Assigned(Chunk) then
- begin
- Source.ReadChunkData(Chunk);
- Shadow.Bias := Chunk^.Data.LoShadowBias^;
- FreeChunkData(Chunk);
- end;
- // Search for ray_Bias Chunk
- Chunk := FindNextChunk(MDataChunk^.Children, RAY_BIAS);
- if Assigned(Chunk) then
- begin
- Source.ReadChunkData(Chunk);
- Shadow.RayBias := Chunk^.Data.RayBias^;
- FreeChunkData(Chunk);
- end;
- // search for MapSize Chunk
- Chunk := FindNextChunk(MDataChunk^.Children, SHADOW_MAP_SIZE);
- if Assigned(Chunk) then
- begin
- Source.ReadChunkData(Chunk);
- Shadow.MapSize := Chunk^.Data.ShadowMapSize^;
- FreeChunkData(Chunk);
- end;
- // search for Shadow_Filter Chunk
- Chunk := FindNextChunk(MDataChunk^.Children, SHADOW_FILTER);
- if Assigned(Chunk) then
- begin
- Source.ReadChunkData(Chunk);
- Shadow.Filter := Chunk^.Data.ShadowFilter^;
- FreeChunkData(Chunk);
- end;
- // search for ambient_light Chunk
- Chunk := FindNextChunk(MDataChunk^.Children, AMBIENT_LIGHT);
- if Assigned(Chunk) then
- begin
- // search for the old style Color chunk inside the ambient Light Chunk
- ColorChunk := FindChunk(Chunk, COLOR_F);
- if Assigned(ColorChunk) then
- begin
- Source.ReadChunkData(ColorChunk);
- AmbientLight.R := ColorChunk^.Data.ColorF^.Red;
- AmbientLight.G := ColorChunk^.Data.ColorF^.Green;
- AmbientLight.B := ColorChunk^.Data.ColorF^.Blue;
- FreeChunkData(ColorChunk);
- end
- else
- begin
- // just for robust completeness, search for the COLOR_24 chunk
- ColorChunk := FindChunk(Chunk, COLOR_24);
- if Assigned(ColorChunk) then
- begin
- Source.ReadChunkData(ColorChunk);
- AmbientLight.R := ColorChunk^.Data.Color24^.Red / 255;
- AmbientLight.G := ColorChunk^.Data.Color24^.Green / 255;
- AmbientLight.B := ColorChunk^.Data.Color24^.Blue / 255;
- FreeChunkData(ColorChunk);
- end;
- end;
- // search for the newer linear Color Chunk inside the ambient Light chunk
- ColorChunk := FindChunk(Chunk, LIN_COLOR_F);
- if Assigned(ColorChunk) then
- begin
- Source.ReadChunkData(ColorChunk);
- AmbientLight.R := ColorChunk^.Data.LinColorF^.Red;
- AmbientLight.G := ColorChunk^.Data.LinColorF^.Green;
- AmbientLight.B := ColorChunk^.Data.LinColorF^.Blue;
- FreeChunkData(ColorChunk);
- end
- else
- begin
- // just for completeness, search for the LIN_COLOR_24 chunk
- ColorChunk := FindChunk(Chunk, LIN_COLOR_24);
- if Assigned(ColorChunk) then
- begin
- Source.ReadChunkData(ColorChunk);
- AmbientLight.R := ColorChunk^.Data.LinColorF^.Red / 255;
- AmbientLight.G := ColorChunk^.Data.LinColorF^.Green / 255;
- AmbientLight.B := ColorChunk^.Data.LinColorF^.Blue / 255;
- FreeChunkData(ColorChunk);
- end;
- end;
- end;
- // Search for the oconst chunk
- Chunk := FindNextChunk(MDataChunk^.Children, O_CONSTS);
- if Assigned(Chunk) then
- begin
- Source.ReadChunkData(Chunk);
- oconsts.x := Chunk^.Data.OConsts^.X;
- oconsts.y := Chunk^.Data.OConsts^.Y;
- oconsts.z := Chunk^.Data.OConsts^.Z;
- FreeChunkData(Chunk);
- end;
- end;
- end;
- end;
- //-----------------------------------------------------------------------------
- function InitAtmosphere: TAtmosphere3DS;
- // initializes a atmosphere structure
- begin
- FillChar(Result, SizeOf(Result), 0);
- with Result do
- begin
- Fog.FarPlane := 1000;
- Fog.FarDensity := 100;
- Fog.FogBgnd := True;
- LayerFog.ZMax := 100;
- LayerFog.Density := 50;
- LayerFog.Falloff := lfNoFall;
- LayerFog.Fogbgnd := True;
- DCue.FarPlane := 1000;
- DCue.FarDim := 100;
- ActiveAtmo := atNoAtmo;
- end;
- end;
- //-----------------------------------------------------------------------------
- function GetAtmosphere(const Source: TFile3DS; var DB: TDatabase3DS): TAtmosphere3DS;
- // retrieves the atmospheric settings from database
- var
- MDataChunk, FogChunk, BgnChunk, ColorChunk, Chunk: PChunk3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- // find the MDATA chunk
- MDataChunk := FindChunk(DB.TopChunk, MDATA);
- // if the MDATA chunk was found, then search for the atmospheric chunks
- if Assigned(MDataChunk) then
- begin
- Result := InitAtmosphere;
- // Search for fog chunk
- FogChunk := FindChunk(MDataChunk, FOG);
- if Assigned(FogChunk) then
- with Result do
- begin
- // read the chunk information
- Source.ReadChunkData(FogChunk);
- // Copy the FogChunk data into the structure
- Fog.NearPlane := FogChunk^.Data.Fog^.NearPlaneDist;
- Fog.NearDensity := FogChunk^.Data.Fog^.NearPlaneDensity;
- Fog.FarPlane := FogChunk^.Data.Fog^.FarPlanedist;
- Fog.FarDensity := FogChunk^.Data.Fog^.FarPlaneDensity;
- // Search for fog Color chunk
- ColorChunk := FindChunk(FogChunk, COLOR_F);
- if Assigned(ColorChunk) then
- begin
- Source.ReadChunkData(ColorChunk);
- Fog.FogColor.R := ColorChunk^.Data.ColorF^.Red;
- Fog.Fogcolor.G := ColorChunk^.Data.ColorF^.Green;
- Fog.Fogcolor.B := ColorChunk^.Data.ColorF^.Blue;
- FreeChunkData(ColorChunk);
- end;
- // Search for FOG_BGND chunk
- BgnChunk := FindChunk(FogChunk, FOG_BGND);
- if Assigned(BgnChunk) then
- Fog.FogBgnd := True
- else
- Fog.FogBgnd := False;
- FreeChunkData(FogChunk);
- // search for LAYER_FOG chunk
- FogChunk := FindChunk(MDataChunk, LAYER_FOG);
- if Assigned(FogChunk) then
- begin
- Source.ReadChunkData(FogChunk);
- LayerFog.ZMin := FogChunk^.Data.LayerFog^.ZMin;
- LayerFog.ZMax := FogChunk^.Data.LayerFog^.ZMax;
- LayerFog.Density := FogChunk^.Data.LayerFog^.Density;
- if (FogChunk^.Data.LayerFog^.AType and LayerFogBgnd) <> 0 then
- LayerFog.FogBgnd := True
- else
- LayerFog.FogBgnd := False;
- if (FogChunk^.Data.LayerFog^.AType and TopFalloff) <> 0 then
- LayerFog.Falloff := lfTopFall
- else if (FogChunk^.Data.LayerFog^.AType and BottomFalloff) <> 0 then
- LayerFog.Falloff := lfBottomFall
- else
- LayerFog.Falloff := lfNoFall;
- ColorChunk := FindChunk(FogChunk, COLOR_F);
- if Assigned(ColorChunk) then
- begin
- Source.ReadChunkData(ColorChunk);
- LayerFog.FogColor.R := ColorChunk^.Data.ColorF^.Red;
- LayerFog.Fogcolor.G := ColorChunk^.Data.ColorF^.Green;
- LayerFog.Fogcolor.B := ColorChunk^.Data.ColorF^.Blue;
- FreeChunkData(ColorChunk);
- end;
- FreeChunkData(FogChunk);
- end;
- // search for DISTANCE_CUE chunk
- Chunk := FindChunk(MDataChunk, DISTANCE_CUE);
- if Assigned(Chunk) then
- begin
- Source.ReadChunkData(Chunk);
- DCue.NearPlane := Chunk^.Data.DistanceCue^.NearPlaneDist;
- DCue.neardim := Chunk^.Data.DistanceCue^.NearPlaneDimming;
- DCue.FarPlane := Chunk^.Data.DistanceCue^.FarPlaneDist;
- DCue.FarDim := Chunk^.Data.DistanceCue^.FarPlaneDimming;
- BgnChunk := FindChunk(Chunk, DCUE_BGND);
- if Assigned(BgnChunk) then
- DCue.DCueBgnd := True
- else
- DCue.DCueBgnd := False;
- FreeChunkData(Chunk);
- end;
- // search for USE_FOG, USE_LAYER_FOG or USE_DISTANCE_CUE chunk
- Chunk := FindChunk(MDataChunk, USE_FOG);
- if Assigned(Chunk) then
- ActiveAtmo := atUseFog
- else
- begin
- Chunk := FindChunk(MDataChunk, USE_LAYER_FOG);
- if Assigned(Chunk) then
- ActiveAtmo := atUseLayerFog
- else
- begin
- Chunk := FindChunk(MDataChunk, USE_DISTANCE_CUE);
- if Assigned(Chunk) then
- ActiveAtmo := atUseDistanceCue
- else
- ActiveAtmo := atNoAtmo;
- end;
- end;
- end; // with Result do
- end; // if Assigned(MDataChunk)
- end;
- //-----------------------------------------------------------------------------
- function InitBackground: TBackground3DS;
- // initializes the TBackground3DS structure
- begin
- FillChar(Result, SizeOf(Result), 0);
- Result.VGradient.GradPercent := 0.5;
- end;
- //-----------------------------------------------------------------------------
- function GetBackground(const Source: TFile3DS; var DB: TDatabase3DS): TBackground3DS;
- // retrieves the background settings from the database
- var
- MDataChunk, ColorChunk, TopColor, MidColor, BotColor, Chunk: PChunk3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- // Find the MDATA chunk
- MDataChunk := FindChunk(DB.TopChunk, MDATA);
- // only continue with structure filling if an MDATA chunk is found
- if Assigned(MDataChunk) then
- with Result do
- begin
- Result := InitBackground;
- // search for bitmap chunk
- Chunk := FindChunk(MDataChunk, BIT_MAP);
- if Assigned(Chunk) then
- begin
- // read the chunk information
- Source.ReadChunkData(Chunk);
- // copy the bitmap filename to the structure
- if Assigned(Chunk^.Data.BitmapName) then
- Bitmap := Chunk^.Data.BitmapName^
- else
- Bitmap := '';
- FreeChunkData(Chunk);
- end;
- Chunk := FindChunk(MDataChunk, SOLID_BGND);
- if Assigned(Chunk) then
- begin
- ColorChunk := FindChunk(Chunk, COLOR_F);
- if Assigned(ColorChunk) then
- begin
- Source.ReadChunkData(ColorChunk);
- Solid.R := ColorChunk^.Data.ColorF^.Red;
- Solid.G := ColorChunk^.Data.ColorF^.Green;
- Solid.B := ColorChunk^.Data.ColorF^.Blue;
- FreeChunkData(ColorChunk);
- end;
- ColorChunk := FindChunk(Chunk, LIN_COLOR_F);
- if Assigned(ColorChunk) then
- begin
- Source.ReadChunkData(ColorChunk);
- Solid.R := ColorChunk^.Data.ColorF^.Red;
- Solid.G := ColorChunk^.Data.ColorF^.Green;
- Solid.B := ColorChunk^.Data.ColorF^.Blue;
- FreeChunkData(ColorChunk);
- end;
- end;
- Chunk := FindChunk(MDataChunk, V_GRADIENT);
- if Assigned(Chunk) then
- begin
- // the COLOR_F chunks are the old, non-gamma corrected colors
- Source.ReadChunkData(Chunk);
- VGradient.GradPercent := Chunk^.Data.VGradient^;
- TopColor := FindChunk(Chunk, COLOR_F);
- if Assigned(TopColor) then
- begin
- Source.ReadChunkData(TopColor);
- VGradient.Top.R := TopColor^.Data.ColorF^.Red;
- VGradient.Top.G := TopColor^.Data.ColorF^.Green;
- VGradient.Top.B := TopColor^.Data.ColorF^.Blue;
- MidColor := FindNextChunk(TopColor^.Sibling, COLOR_F);
- if Assigned(MidColor) then
- begin
- Source.ReadChunkData(MidColor);
- VGradient.Mid.R := MidColor^.Data.ColorF^.Red;
- VGradient.Mid.G := MidColor^.Data.ColorF^.Green;
- VGradient.Mid.B := MidColor^.Data.ColorF^.Blue;
- BotColor := FindNextChunk(MidColor^.Sibling, COLOR_F);
- if Assigned(BotColor) then
- begin
- Source.ReadChunkData(BotColor);
- VGradient.Bottom.R := MidColor^.Data.ColorF^.Red;
- VGradient.Bottom.G := MidColor^.Data.ColorF^.Green;
- VGradient.Bottom.B := MidColor^.Data.ColorF^.Blue;
- FreeChunkData(BotColor);
- end;
- FreeChunkData(MidColor);
- end;
- FreeChunkData(TopColor);
- end;
- // If the newer, gamma correct colors are available, then use them instead
- TopColor := FindChunk(Chunk, LIN_COLOR_F);
- if Assigned(TopColor) then
- begin
- Source.ReadChunkData(TopColor);
- VGradient.Top.R := TopColor^.Data.ColorF^.Red;
- VGradient.Top.G := TopColor^.Data.ColorF^.Green;
- VGradient.Top.B := TopColor^.Data.ColorF^.Blue;
- MidColor := FindNextChunk(TopColor^.Sibling, LIN_COLOR_F);
- if Assigned(MidColor) then
- begin
- Source.ReadChunkData(MidColor);
- VGradient.Mid.R := MidColor^.Data.ColorF^.Red;
- VGradient.Mid.G := MidColor^.Data.ColorF^.Green;
- VGradient.Mid.B := MidColor^.Data.ColorF^.Blue;
- BotColor := FindNextChunk(MidColor^.Sibling, LIN_COLOR_F);
- if Assigned(BotColor) then
- begin
- Source.ReadChunkData(BotColor);
- VGradient.Bottom.R := MidColor^.Data.ColorF^.Red;
- VGradient.Bottom.G := MidColor^.Data.ColorF^.Green;
- VGradient.Bottom.B := MidColor^.Data.ColorF^.Blue;
- FreeChunkData(BotColor);
- end;
- FreeChunkData(MidColor);
- end;
- FreeChunkData(TopColor);
- end;
- FreeChunkData(Chunk);
- end;
- // Search for use_bitmap, use_solid_bgnd and use_v_gradient chunks
- Chunk := FindChunk(MDataChunk, USE_BIT_MAP);
- if Assigned(Chunk) then
- BgndUsed := btUseBitmapBgnd
- else
- begin
- Chunk := FindChunk(MDataChunk, USE_SOLID_BGND);
- if Assigned(Chunk) then
- BgndUsed := btUseSolidBgnd
- else
- begin
- Chunk := FindChunk(MDataChunk, USE_V_GRADIENT);
- if Assigned(Chunk) then
- BgndUsed := btUseVGradientBgnd
- else
- BgndUsed := btNoBgnd;
- end;
- end;
- end;
- end;
- //-----------------------------------------------------------------------------
- function InitViewport: TViewport3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- with Result do
- begin
- AType := vtTopView3DS;
- Ortho.Zoom := 0.7395;
- User.Zoom := 0.7395;
- User.HorAng := 20;
- User.VerAng := 30;
- CameraStr := '';
- Size.Width := 1000;
- Size.Height := 1000;
- end;
- end;
- //----------------------------------------------------------------------------
- function GetViewportEntry(Source: TFile3DS; Section: PChunk3DS): TViewport3DS;
- var
- Chunk, VLayout: PChunk3DS;
- PortIndex: integer;
- foundV3: boolean;
- begin
- Result := InitViewport;
- VLayout := FindNextChunk(Section^.Children, VIEWPORT_LAYOUT);
- if Assigned(VLayout) then
- with Result do
- begin
- Source.ReadChunkData(VLayout);
- Chunk := VLayout^.Children;
- foundV3 := False;
- PortIndex := 0;
- while Assigned(Chunk) do
- begin
- case Chunk^.Tag of
- VIEWPORT_SIZE:
- begin
- Source.ReadChunkData(Chunk);
- Size.XPos := Chunk^.Data.ViewportSize^.XPos;
- Size.YPos := Chunk^.Data.ViewportSize^.YPos;
- Size.Width := Chunk^.Data.ViewportSize^.Width;
- Size.Height := Chunk^.Data.ViewportSize^.Height;
- FreeChunkData(Chunk);
- end;
- VIEWPORT_DATA_3:
- begin
- foundV3 := True;
- if PortIndex = VLayout^.Data.ViewportLayout^.Top then
- begin
- Source.ReadChunkData(Chunk);
- case Chunk^.Data.ViewportData^.View of
- 1:
- AType := vtTopView3DS;
- 2:
- AType := vtBottomView3DS;
- 3:
- AType := vtLeftView3DS;
- 4:
- AType := vtRightView3DS;
- 5:
- AType := vtFrontView3DS;
- 6:
- AType := vtBackView3DS;
- 7:
- AType := vtUserView3DS;
- 18:
- AType := vtSpotlightView3DS;
- $FFFF:
- AType := vtCameraView3DS;
- else
- AType := vtNoView3DS;
- end;
- Ortho.Zoom := Chunk^.Data.ViewportData^.ZoomFactor;
- User.Zoom := Chunk^.Data.ViewportData^.ZoomFactor;
- Ortho.Center.X := Chunk^.Data.ViewportData^.Center.X;
- User.Center.X := Chunk^.Data.ViewportData^.Center.X;
- Ortho.Center.Y := Chunk^.Data.ViewportData^.Center.Y;
- User.Center.y := Chunk^.Data.ViewportData^.Center.Y;
- Ortho.Center.Z := Chunk^.Data.ViewportData^.Center.Z;
- User.Center.z := Chunk^.Data.ViewportData^.Center.Z;
- User.HorAng := Chunk^.Data.ViewportData^.HorizAng;
- User.VerAng := Chunk^.Data.ViewportData^.VertAng;
- CameraStr := string(Chunk^.Data.ViewportData^.CamNameStr);
- end;
- Inc(PortIndex);
- end;
- VIEWPORT_DATA:
- if not foundV3 then
- begin
- if PortIndex = VLayout^.Data.ViewportLayout^.Top then
- begin
- Source.ReadChunkData(Chunk);
- case Chunk^.Data.ViewportData^.View of
- 1:
- AType := vtTopView3DS;
- 2:
- AType := vtBottomView3DS;
- 3:
- AType := vtLeftView3DS;
- 4:
- AType := vtRightView3DS;
- 5:
- AType := vtFrontView3DS;
- 6:
- AType := vtBackView3DS;
- 7:
- AType := vtUserView3DS;
- 18:
- AType := vtSpotlightView3DS;
- $FFFF:
- AType := vtCameraView3DS;
- else
- AType := vtNoView3DS;
- end;
- Ortho.Zoom := Chunk^.Data.ViewportData^.ZoomFactor;
- User.Zoom := Chunk^.Data.ViewportData^.ZoomFactor;
- Ortho.Center.X := Chunk^.Data.ViewportData^.Center.X;
- User.Center.X := Chunk^.Data.ViewportData^.Center.X;
- Ortho.Center.Y := Chunk^.Data.ViewportData^.Center.Y;
- User.Center.y := Chunk^.Data.ViewportData^.Center.Y;
- Ortho.Center.Z := Chunk^.Data.ViewportData^.Center.Z;
- User.Center.z := Chunk^.Data.ViewportData^.Center.Z;
- User.HorAng := Chunk^.Data.ViewportData^.HorizAng;
- User.VerAng := Chunk^.Data.ViewportData^.VertAng;
- CameraStr := string(Chunk^.Data.ViewportData^.CamNameStr);
- end;
- Inc(PortIndex);
- end;
- end;
- Chunk := Chunk^.Sibling;
- end;
- end;
- end;
- //---------------------------------------------------------------------------
- function GetViewport(const Source: TFile3DS; var DB: TDatabase3DS): TViewport3DS;
- var
- Data: PChunk3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- if (DB.TopChunk^.Tag = M3DMAGIC) or (DB.TopChunk^.Tag = CMAGIC) then
- begin
- Data := FindNextChunk(DB.TopChunk^.Children, KFDATA);
- if Assigned(Data) then
- Result := GetViewportEntry(Source, Data)
- else
- begin
- Data := FindChunk(DB.TopChunk^.Children, MDATA);
- if Assigned(Data) then
- Result := GetViewportEntry(Source, Data);
- end;
- end;
- end;
- //----------------- helper funcs for text output ------------------------------
- function ChunkTagToString(Tag: word): string;
- begin
- case Tag of
- NULL_CHUNK: Result := 'NULL_CHUNK';
- ChunkType: Result := 'ChunkType';
- ChunkUnique: Result := 'ChunkUnique';
- NotChunk: Result := 'NotChunk';
- Container: Result := 'Container';
- IsChunk: Result := 'IsChunk';
- // Dummy Chunk that sometimes appears in 3DS files created by prerelease 3D Studio R2
- DUMMY: Result := 'DUMMY';
- // Trick Chunk Types
- POINT_ARRAY_ENTRY: Result := 'POINT_ARRAY_ENTRY';
- POINT_FLAG_ARRAY_ENTRY: Result := 'POINT_FLAG_ARRAY_ENTRY';
- FACE_ARRAY_ENTRY: Result := 'FACE_ARRAY_ENTRY';
- MSH_MAT_GROUP_ENTRY: Result := 'MSH_MAT_GROUP_ENTRY';
- TEX_VERTS_ENTRY: Result := 'TEX_VERTS_ENTRY';
- SMOOTH_GROUP_ENTRY: Result := 'SMOOTH_GROUP_ENTRY';
- POS_TRACK_TAG_KEY: Result := 'POS_TRACK_TAG_KEY';
- ROT_TRACK_TAG_KEY: Result := 'ROT_TRACK_TAG_KEY';
- SCL_TRACK_TAG_KEY: Result := 'SCL_TRACK_TAG_KEY';
- FOV_TRACK_TAG_KEY: Result := 'FOV_TRACK_TAG_KEY';
- ROLL_TRACK_TAG_KEY: Result := 'ROLL_TRACK_TAG_KEY';
- COL_TRACK_TAG_KEY: Result := 'COL_TRACK_TAG_KEY';
- MORPH_TRACK_TAG_KEY: Result := 'MORPH_TRACK_TAG_KEY';
- HOT_TRACK_TAG_KEY: Result := 'HOT_TRACK_TAG_KEY';
- FALL_TRACK_TAG_KEY: Result := 'FALL_TRACK_TAG_KEY';
- // 3DS File Chunk IDs
- M3DMAGIC: Result := 'M3DMAGIC';
- SMAGIC: Result := 'SMAGIC';
- LMAGIC: Result := 'LMAGIC';
- MLIBMAGIC: Result := 'MLIBMAGIC';
- MATMAGIC: Result := 'MATMAGIC';
- M3D_VERSION: Result := 'M3D_VERSION';
- M3D_KFVERSION: Result := 'M3D_KFVERSION';
- // Mesh Chunk Ids
- MDATA: Result := 'MDATA';
- MESH_VERSION: Result := 'MESH_VERSION';
- COLOR_F: Result := 'COLOR_F';
- COLOR_24: Result := 'COLOR_24';
- LIN_COLOR_24: Result := 'LIN_COLOR_24';
- LIN_COLOR_F: Result := 'LIN_COLOR_F';
- INT_PERCENTAGE: Result := 'INT_PERCENTAGE';
- FLOAT_PERCENTAGE: Result := 'FLOAT_PERCENTAGE';
- MASTER_SCALE: Result := 'MASTER_SCALE';
- BIT_MAP: Result := 'BIT_MAP';
- USE_BIT_MAP: Result := 'USE_BIT_MAP';
- SOLID_BGND: Result := 'SOLID_BGND';
- USE_SOLID_BGND: Result := 'USE_SOLID_BGND';
- V_GRADIENT: Result := 'V_GRADIENT';
- USE_V_GRADIENT: Result := 'USE_V_GRADIENT';
- LO_SHADOW_BIAS: Result := 'LO_SHADOW_BIAS';
- HI_SHADOW_BIAS: Result := 'HI_SHADOW_BIAS';
- SHADOW_MAP_SIZE: Result := 'SHADOW_MAP_SIZE';
- SHADOW_SAMPLES: Result := 'SHADOW_SAMPLES';
- SHADOW_RANGE: Result := 'SHADOW_RANGE';
- SHADOW_FILTER: Result := 'SHADOW_FILTER';
- RAY_BIAS: Result := 'RAY_BIAS';
- O_CONSTS: Result := 'O_CONSTS';
- AMBIENT_LIGHT: Result := 'AMBIENT_LIGHT';
- FOG: Result := 'FOG';
- USE_FOG: Result := 'USE_FOG';
- FOG_BGND: Result := 'FOG_BGND';
- DISTANCE_CUE: Result := 'DISTANCE_CUE';
- USE_DISTANCE_CUE: Result := 'USE_DISTANCE_CUE';
- LAYER_FOG: Result := 'LAYER_FOG';
- USE_LAYER_FOG: Result := 'USE_LAYER_FOG';
- DCUE_BGND: Result := 'DCUE_BGND';
- DEFAULT_VIEW: Result := 'DEFAULT_VIEW';
- VIEW_TOP: Result := 'VIEW_TOP';
- VIEW_BOTTOM: Result := 'VIEW_BOTTOM';
- VIEW_LEFT: Result := 'VIEW_LEFT';
- VIEW_RIGHT: Result := 'VIEW_RIGHT';
- VIEW_FRONT: Result := 'VIEW_FRONT';
- VIEW_BACK: Result := 'VIEW_BACK';
- VIEW_USER: Result := 'VIEW_USER';
- VIEW_CAMERA: Result := 'VIEW_CAMERA';
- VIEW_WINDOW: Result := 'VIEW_WINDOW';
- NAMED_OBJECT: Result := 'NAMED_OBJECT';
- OBJ_HIDDEN: Result := 'OBJ_HIDDEN';
- OBJ_VIS_LOFTER: Result := 'OBJ_VIS_LOFTER';
- OBJ_DOESNT_CAST: Result := 'OBJ_DOESNT_CAST';
- OBJ_MATTE: Result := 'OBJ_MATTE';
- OBJ_FAST: Result := 'OBJ_FAST';
- OBJ_PROCEDURAL: Result := 'OBJ_PROCEDURAL';
- OBJ_FROZEN: Result := 'OBJ_FROZEN';
- OBJ_DONT_RCVSHADOW: Result := 'OBJ_DONT_RCVSHADOW';
- N_TRI_OBJECT: Result := 'N_TRI_OBJECT';
- POINT_ARRAY: Result := 'POINT_ARRAY';
- POINT_FLAG_ARRAY: Result := 'POINT_FLAG_ARRAY';
- FACE_ARRAY: Result := 'FACE_ARRAY';
- MSH_MAT_GROUP: Result := 'MSH_MAT_GROUP';
- OLD_MAT_GROUP: Result := 'OLD_MAT_GROUP';
- TEX_VERTS: Result := 'TEX_VERTS';
- SMOOTH_GROUP: Result := 'SMOOTH_GROUP';
- MESH_MATRIX: Result := 'MESH_MATRIX';
- MESH_COLOR: Result := 'MESH_COLOR';
- MESH_TEXTURE_INFO: Result := 'MESH_TEXTURE_INFO';
- PROC_NAME: Result := 'PROC_NAME';
- PROC_DATA: Result := 'PROC_DATA';
- MSH_BOXMAP: Result := 'MSH_BOXMAP';
- N_D_L_OLD: Result := 'N_D_L_OLD';
- N_CAM_OLD: Result := 'N_CAM_OLD';
- N_DIRECT_LIGHT: Result := 'N_DIRECT_LIGHT';
- DL_SPOTLIGHT: Result := 'DL_SPOTLIGHT';
- DL_OFF: Result := 'DL_OFF';
- DL_ATTENUATE: Result := 'DL_ATTENUATE';
- DL_RAYSHAD: Result := 'DL_RAYSHAD';
- DL_SHADOWED: Result := 'DL_SHADOWED';
- DL_LOCAL_SHADOW: Result := 'DL_LOCAL_SHADOW';
- DL_LOCAL_SHADOW2: Result := 'DL_LOCAL_SHADOW2';
- DL_SEE_CONE: Result := 'DL_SEE_CONE';
- DL_SPOT_RECTANGULAR: Result := 'DL_SPOT_RECTANGULAR';
- DL_SPOT_OVERSHOOT: Result := 'DL_SPOT_OVERSHOOT';
- DL_SPOT_PROJECTOR: Result := 'DL_SPOT_PROJECTOR';
- DL_EXCLUDE: Result := 'DL_EXCLUDE';
- DL_RANGE: Result := 'DL_RANGE';
- DL_SPOT_ROLL: Result := 'DL_SPOT_ROLL';
- DL_SPOT_ASPECT: Result := 'DL_SPOT_ASPECT';
- DL_RAY_BIAS: Result := 'DL_RAY_BIAS';
- DL_INNER_RANGE: Result := 'DL_INNER_RANGE';
- DL_OUTER_RANGE: Result := 'DL_OUTER_RANGE';
- DL_MULTIPLIER: Result := 'DL_MULTIPLIER';
- N_AMBIENT_LIGHT: Result := 'N_AMBIENT_LIGHT';
- N_CAMERA: Result := 'N_CAMERA';
- CAM_SEE_CONE: Result := 'CAM_SEE_CONE';
- CAM_RANGES: Result := 'CAM_RANGES';
- HIERARCHY: Result := 'HIERARCHY';
- PARENT_OBJECT: Result := 'PARENT_OBJECT';
- PIVOT_OBJECT: Result := 'PIVOT_OBJECT';
- PIVOT_LIMITS: Result := 'PIVOT_LIMITS';
- PIVOT_ORDER: Result := 'PIVOT_ORDER';
- XLATE_RANGE: Result := 'XLATE_RANGE';
- POLY_2D: Result := 'POLY_2D';
- // Flags in shaper file that tell whether polys make up an ok shape
- SHAPE_OK: Result := 'SHAPE_OK';
- SHAPE_NOT_OK: Result := 'SHAPE_NOT_OK';
- SHAPE_HOOK: Result := 'SHAPE_HOOK';
- PATH_3D: Result := 'PATH_3D';
- PATH_MATRIX: Result := 'PATH_MATRIX';
- SHAPE_2D: Result := 'SHAPE_2D';
- M_SCALE: Result := 'M_SCALE';
- M_TWIST: Result := 'M_TWIST';
- M_TEETER: Result := 'M_TEETER';
- M_FIT: Result := 'M_FIT';
- M_BEVEL: Result := 'M_BEVEL';
- XZ_CURVE: Result := 'XZ_CURVE';
- YZ_CURVE: Result := 'YZ_CURVE';
- INTERPCT: Result := 'INTERPCT';
- DEFORM_LIMIT: Result := 'DEFORM_LIMIT';
- // Flags for Modeler options
- USE_CONTOUR: Result := 'USE_CONTOUR';
- USE_TWEEN: Result := 'USE_TWEEN';
- USE_SCALE: Result := 'USE_SCALE';
- USE_TWIST: Result := 'USE_TWIST';
- USE_TEETER: Result := 'USE_TEETER';
- USE_FIT: Result := 'USE_FIT';
- USE_BEVEL: Result := 'USE_BEVEL';
- // Viewport description chunks
- VIEWPORT_LAYOUT_OLD: Result := 'VIEWPORT_LAYOUT_OLD';
- VIEWPORT_DATA_OLD: Result := 'VIEWPORT_DATA_OLD';
- VIEWPORT_LAYOUT: Result := 'VIEWPORT_LAYOUT';
- VIEWPORT_DATA: Result := 'VIEWPORT_DATA';
- VIEWPORT_DATA_3: Result := 'VIEWPORT_DATA_3';
- VIEWPORT_SIZE: Result := 'VIEWPORT_SIZE';
- NETWORK_VIEW: Result := 'NETWORK_VIEW';
- // External Application Data
- XDATA_SECTION: Result := 'XDATA_SECTION';
- XDATA_ENTRY: Result := 'XDATA_ENTRY';
- XDATA_APPNAME: Result := 'XDATA_APPNAME';
- XDATA_STRING: Result := 'XDATA_STRING';
- XDATA_FLOAT: Result := 'XDATA_FLOAT';
- XDATA_DOUBLE: Result := 'XDATA_DOUBLE';
- XDATA_SHORT: Result := 'XDATA_SHORT';
- XDATA_LONG: Result := 'XDATA_LONG';
- XDATA_VOID: Result := 'XDATA_procedure';
- XDATA_GROUP: Result := 'XDATA_GROUP';
- XDATA_RFU6: Result := 'XDATA_RFU6';
- XDATA_RFU5: Result := 'XDATA_RFU5';
- XDATA_RFU4: Result := 'XDATA_RFU4';
- XDATA_RFU3: Result := 'XDATA_RFU3';
- XDATA_RFU2: Result := 'XDATA_RFU2';
- XDATA_RFU1: Result := 'XDATA_RFU1';
- // Material Chunk IDs
- MAT_ENTRY: Result := 'MAT_ENTRY';
- MAT_NAME: Result := 'MAT_NAME';
- MAT_AMBIENT: Result := 'MAT_AMBIENT';
- MAT_DIFFUSE: Result := 'MAT_DIFFUSE';
- MAT_SPECULAR: Result := 'MAT_SPECULAR';
- MAT_SHININESS: Result := 'MAT_SHININESS';
- MAT_SHIN2PCT: Result := 'MAT_SHIN2PCT';
- MAT_SHIN3PCT: Result := 'MAT_SHIN3PCT';
- MAT_TRANSPARENCY: Result := 'MAT_TRANSPARENCY';
- MAT_XPFALL: Result := 'MAT_XPFALL';
- MAT_REFBLUR: Result := 'MAT_REFBLUR';
- MAT_SELF_ILLUM: Result := 'MAT_SELF_ILLUM';
- MAT_TWO_SIDE: Result := 'MAT_TWO_SIDE';
- MAT_DECAL: Result := 'MAT_DECAL';
- MAT_ADDITIVE: Result := 'MAT_ADDITIVE';
- MAT_SELF_ILPCT: Result := 'MAT_SELF_ILPCT';
- MAT_WIRE: Result := 'MAT_WIRE';
- MAT_SUPERSMP: Result := 'MAT_SUPERSMP';
- MAT_WIRESIZE: Result := 'MAT_WIRESIZE';
- MAT_FACEMAP: Result := 'MAT_FACEMAP';
- MAT_XPFALLIN: Result := 'MAT_XPFALLIN';
- MAT_PHONGSOFT: Result := 'MAT_PHONGSOFT';
- MAT_WIREABS: Result := 'MAT_WIREABS';
- MAT_SHADING: Result := 'MAT_SHADING';
- MAT_TEXMAP: Result := 'MAT_TEXMAP';
- MAT_OPACMAP: Result := 'MAT_OPACMAP';
- MAT_REFLMAP: Result := 'MAT_REFLMAP';
- MAT_BUMPMAP: Result := 'MAT_BUMPMAP';
- MAT_SPECMAP: Result := 'MAT_SPECMAP';
- MAT_USE_XPFALL: Result := 'MAT_USE_XPFALL';
- MAT_USE_REFBLUR: Result := 'MAT_USE_REFBLUR';
- MAT_BUMP_PERCENT: Result := 'MAT_BUMP_PERCENT';
- MAT_MAPNAME: Result := 'MAT_MAPNAME';
- MAT_ACUBIC: Result := 'MAT_ACUBIC';
- MAT_SXP_TEXT_DATA: Result := 'MAT_SXP_TEXT_DATA';
- MAT_SXP_TEXT2_DATA: Result := 'MAT_SXP_TEXT2_DATA';
- MAT_SXP_OPAC_DATA: Result := 'MAT_SXP_OPAC_DATA';
- MAT_SXP_BUMP_DATA: Result := 'MAT_SXP_BUMP_DATA';
- MAT_SXP_SPEC_DATA: Result := 'MAT_SXP_SPEC_DATA';
- MAT_SXP_SHIN_DATA: Result := 'MAT_SXP_SHIN_DATA';
- MAT_SXP_SELFI_DATA: Result := 'MAT_SXP_SELFI_DATA';
- MAT_SXP_TEXT_MASKDATA: Result := 'MAT_SXP_TEXT_MASKDATA';
- MAT_SXP_TEXT2_MASKDATA: Result := 'MAT_SXP_TEXT2_MASKDATA';
- MAT_SXP_OPAC_MASKDATA: Result := 'MAT_SXP_OPAC_MASKDATA';
- MAT_SXP_BUMP_MASKDATA: Result := 'MAT_SXP_BUMP_MASKDATA';
- MAT_SXP_SPEC_MASKDATA: Result := 'MAT_SXP_SPEC_MASKDATA';
- MAT_SXP_SHIN_MASKDATA: Result := 'MAT_SXP_SHIN_MASKDATA';
- MAT_SXP_SELFI_MASKDATA: Result := 'MAT_SXP_SELFI_MASKDATA';
- MAT_SXP_REFL_MASKDATA: Result := 'MAT_SXP_REFL_MASKDATA';
- MAT_TEX2MAP: Result := 'MAT_TEX2MAP';
- MAT_SHINMAP: Result := 'MAT_SHINMAP';
- MAT_SELFIMAP: Result := 'MAT_SELFIMAP';
- MAT_TEXMASK: Result := 'MAT_TEXMASK';
- MAT_TEX2MASK: Result := 'MAT_TEX2MASK';
- MAT_OPACMASK: Result := 'MAT_OPACMASK';
- MAT_BUMPMASK: Result := 'MAT_BUMPMASK';
- MAT_SHINMASK: Result := 'MAT_SHINMASK';
- MAT_SPECMASK: Result := 'MAT_SPECMASK';
- MAT_SELFIMASK: Result := 'MAT_SELFIMASK';
- MAT_REFLMASK: Result := 'MAT_REFLMASK';
- MAT_MAP_TILINGOLD: Result := 'MAT_MAP_TILINGOLD';
- MAT_MAP_TILING: Result := 'MAT_MAP_TILING';
- MAT_MAP_TEXBLUR_OLD: Result := 'MAT_MAP_TEXBLUR_OLD';
- MAT_MAP_TEXBLUR: Result := 'MAT_MAP_TEXBLUR';
- MAT_MAP_USCALE: Result := 'MAT_MAP_USCALE';
- MAT_MAP_VSCALE: Result := 'MAT_MAP_VSCALE';
- MAT_MAP_UOFFSET: Result := 'MAT_MAP_UOFFSET';
- MAT_MAP_VOFFSET: Result := 'MAT_MAP_VOFFSET';
- MAT_MAP_ANG: Result := 'MAT_MAP_ANG';
- MAT_MAP_COL1: Result := 'MAT_MAP_COL1';
- MAT_MAP_COL2: Result := 'MAT_MAP_COL2';
- MAT_MAP_RCOL: Result := 'MAT_MAP_RCOL';
- MAT_MAP_GCOL: Result := 'MAT_MAP_GCOL';
- MAT_MAP_BCOL: Result := 'MAT_MAP_BCOL';
- // Keyframe Chunk IDs
- KFDATA: Result := 'KFDATA';
- KFHDR: Result := 'KFHDR';
- AMBIENT_NODE_TAG: Result := 'AMBIENT_NODE_TAG';
- OBJECT_NODE_TAG: Result := 'OBJECT_NODE_TAG';
- CAMERA_NODE_TAG: Result := 'CAMERA_NODE_TAG';
- TARGET_NODE_TAG: Result := 'TARGET_NODE_TAG';
- LIGHT_NODE_TAG: Result := 'LIGHT_NODE_TAG';
- L_TARGET_NODE_TAG: Result := 'L_TARGET_NODE_TAG';
- SPOTLIGHT_NODE_TAG: Result := 'SPOTLIGHT_NODE_TAG';
- KFSEG: Result := 'KFSEG';
- KFCURTIME: Result := 'KFCURTIME';
- NODE_HDR: Result := 'NODE_HDR';
- PARENT_NAME: Result := 'PARENT_NAME';
- INSTANCE_NAME: Result := 'INSTANCE_NAME';
- PRESCALE: Result := 'PRESCALE';
- PIVOT: Result := 'PIVOT';
- BOUNDBOX: Result := 'BOUNDBOX';
- MORPH_SMOOTH: Result := 'MORPH_SMOOTH';
- POS_TRACK_TAG: Result := 'POS_TRACK_TAG';
- ROT_TRACK_TAG: Result := 'ROT_TRACK_TAG';
- SCL_TRACK_TAG: Result := 'SCL_TRACK_TAG';
- FOV_TRACK_TAG: Result := 'FOV_TRACK_TAG';
- ROLL_TRACK_TAG: Result := 'ROLL_TRACK_TAG';
- COL_TRACK_TAG: Result := 'COL_TRACK_TAG';
- MORPH_TRACK_TAG: Result := 'MORPH_TRACK_TAG';
- HOT_TRACK_TAG: Result := 'HOT_TRACK_TAG';
- FALL_TRACK_TAG: Result := 'FALL_TRACK_TAG';
- HIDE_TRACK_TAG: Result := 'HIDE_TRACK_TAG';
- NODE_ID: Result := 'NODE_ID';
- CMAGIC: Result := 'CMAGIC';
- C_MDRAWER: Result := 'C_MDRAWER';
- C_TDRAWER: Result := 'C_TDRAWER';
- C_SHPDRAWER: Result := 'C_SHPDRAWER';
- C_MODDRAWER: Result := 'C_MODDRAWER';
- C_RIPDRAWER: Result := 'C_RIPDRAWER';
- C_TXDRAWER: Result := 'C_TXDRAWER';
- C_PDRAWER: Result := 'C_PDRAWER';
- C_MTLDRAWER: Result := 'C_MTLDRAWER';
- C_FLIDRAWER: Result := 'C_FLIDRAWER';
- C_CUBDRAWER: Result := 'C_CUBDRAWER';
- C_MFILE: Result := 'C_MFILE';
- C_SHPFILE: Result := 'C_SHPFILE';
- C_MODFILE: Result := 'C_MODFILE';
- C_RIPFILE: Result := 'C_RIPFILE';
- C_TXFILE: Result := 'C_TXFILE';
- C_PFILE: Result := 'C_PFILE';
- C_MTLFILE: Result := 'C_MTLFILE';
- C_FLIFILE: Result := 'C_FLIFILE';
- C_PALFILE: Result := 'C_PALFILE';
- C_TX_STRING: Result := 'C_TX_STRING';
- C_CONSTS: Result := 'C_CONSTS';
- C_SNAPS: Result := 'C_SNAPS';
- C_GRIDS: Result := 'C_GRIDS';
- C_ASNAPS: Result := 'C_ASNAPS';
- C_GRID_RANGE: Result := 'C_GRID_RANGE';
- C_RENDTYPE: Result := 'C_RENDTYPE';
- C_PROGMODE: Result := 'C_PROGMODE';
- C_PREVMODE: Result := 'C_PREVMODE';
- C_MODWMODE: Result := 'C_MODWMODE';
- C_MODMODEL: Result := 'C_MODMODEL';
- C_ALL_LINES: Result := 'C_ALL_LINES';
- C_BACK_TYPE: Result := 'C_BACK_TYPE';
- C_MD_CS: Result := 'C_MD_CS';
- C_MD_CE: Result := 'C_MD_CE';
- C_MD_SML: Result := 'C_MD_SML';
- C_MD_SMW: Result := 'C_MD_SMW';
- C_LOFT_WITH_TEXTURE: Result := 'C_LOFT_WITH_TEXTURE';
- C_LOFT_L_REPEAT: Result := 'C_LOFT_L_REPEAT';
- C_LOFT_W_REPEAT: Result := 'C_LOFT_W_REPEAT';
- C_LOFT_UV_NORMALIZE: Result := 'C_LOFT_UV_NORMALIZE';
- C_WELD_LOFT: Result := 'C_WELD_LOFT';
- C_MD_PDET: Result := 'C_MD_PDET';
- C_MD_SDET: Result := 'C_MD_SDET';
- C_RGB_RMODE: Result := 'C_RGB_RMODE';
- C_RGB_HIDE: Result := 'C_RGB_HIDE';
- C_RGB_MAPSW: Result := 'C_RGB_MAPSW';
- C_RGB_TWOSIDE: Result := 'C_RGB_TWOSIDE';
- C_RGB_SHADOW: Result := 'C_RGB_SHADOW';
- C_RGB_AA: Result := 'C_RGB_AA';
- C_RGB_OVW: Result := 'C_RGB_OVW';
- C_RGB_OVH: Result := 'C_RGB_OVH';
- C_RGB_PICTYPE: Result := 'C_RGB_PICTYPE';
- C_RGB_OUTPUT: Result := 'C_RGB_OUTPUT';
- C_RGB_TODISK: Result := 'C_RGB_TODISK';
- C_RGB_COMPRESS: Result := 'C_RGB_COMPRESS';
- C_JPEG_COMPRESSION: Result := 'C_JPEG_COMPRESSION';
- C_RGB_DISPDEV: Result := 'C_RGB_DISPDEV';
- C_RGB_HARDDEV: Result := 'C_RGB_HARDDEV';
- C_RGB_PATH: Result := 'C_RGB_PATH';
- C_BITMAP_DRAWER: Result := 'C_BITMAP_DRAWER';
- C_RGB_FILE: Result := 'C_RGB_FILE';
- C_RGB_OVASPECT: Result := 'C_RGB_OVASPECT';
- C_RGB_ANIMTYPE: Result := 'C_RGB_ANIMTYPE';
- C_RENDER_ALL: Result := 'C_RENDER_ALL';
- C_REND_FROM: Result := 'C_REND_FROM';
- C_REND_TO: Result := 'C_REND_TO';
- C_REND_NTH: Result := 'C_REND_NTH';
- C_REND_TSTEP: Result := 'C_REND_TSTEP';
- C_VP_TSTEP: Result := 'C_VP_TSTEP';
- C_PAL_TYPE: Result := 'C_PAL_TYPE';
- C_RND_TURBO: Result := 'C_RND_TURBO';
- C_RND_MIP: Result := 'C_RND_MIP';
- C_BGND_METHOD: Result := 'C_BGND_METHOD';
- C_AUTO_REFLECT: Result := 'C_AUTO_REFLECT';
- C_VP_FROM: Result := 'C_VP_FROM';
- C_VP_TO: Result := 'C_VP_TO';
- C_VP_NTH: Result := 'C_VP_NTH';
- C_SRDIAM: Result := 'C_SRDIAM';
- C_SRDEG: Result := 'C_SRDEG';
- C_SRSEG: Result := 'C_SRSEG';
- C_SRDIR: Result := 'C_SRDIR';
- C_HETOP: Result := 'C_HETOP';
- C_HEBOT: Result := 'C_HEBOT';
- C_HEHT: Result := 'C_HEHT';
- C_HETURNS: Result := 'C_HETURNS';
- C_HEDEG: Result := 'C_HEDEG';
- C_HESEG: Result := 'C_HESEG';
- C_HEDIR: Result := 'C_HEDIR';
- C_QUIKSTUFF: Result := 'C_QUIKSTUFF';
- C_SEE_LIGHTS: Result := 'C_SEE_LIGHTS';
- C_SEE_CAMERAS: Result := 'C_SEE_CAMERAS';
- C_SEE_3D: Result := 'C_SEE_3D';
- C_MESHSEL: Result := 'C_MESHSEL';
- C_MESHUNSEL: Result := 'C_MESHUNSEL';
- C_POLYSEL: Result := 'C_POLYSEL';
- C_POLYUNSEL: Result := 'C_POLYUNSEL';
- C_SHPLOCAL: Result := 'C_SHPLOCAL';
- C_MSHLOCAL: Result := 'C_MSHLOCAL';
- C_NUM_FORMAT: Result := 'C_NUM_FORMAT';
- C_ARCH_DENOM: Result := 'C_ARCH_DENOM';
- C_IN_DEVICE: Result := 'C_IN_DEVICE';
- C_MSCALE: Result := 'C_MSCALE';
- C_COMM_PORT: Result := 'C_COMM_PORT';
- C_TAB_BASES: Result := 'C_TAB_BASES';
- C_TAB_DIVS: Result := 'C_TAB_DIVS';
- C_MASTER_SCALES: Result := 'C_MASTER_SCALES';
- C_SHOW_1STVERT: Result := 'C_SHOW_1STVERT';
- C_SHAPER_OK: Result := 'C_SHAPER_OK';
- C_LOFTER_OK: Result := 'C_LOFTER_OK';
- C_EDITOR_OK: Result := 'C_EDITOR_OK';
- C_KEYFRAMER_OK: Result := 'C_KEYFRAMER_OK';
- C_PICKSIZE: Result := 'C_PICKSIZE';
- C_MAPTYPE: Result := 'C_MAPTYPE';
- C_MAP_DISPLAY: Result := 'C_MAP_DISPLAY';
- C_TILE_XY: Result := 'C_TILE_XY';
- C_MAP_XYZ: Result := 'C_MAP_XYZ';
- C_MAP_SCALE: Result := 'C_MAP_SCALE';
- C_MAP_MATRIX_OLD: Result := 'C_MAP_MATRIX_OLD';
- C_MAP_MATRIX: Result := 'C_MAP_MATRIX';
- C_MAP_WID_HT: Result := 'C_MAP_WID_HT';
- C_OBNAME: Result := 'C_OBNAME';
- C_CAMNAME: Result := 'C_CAMNAME';
- C_LTNAME: Result := 'C_LTNAME';
- C_CUR_MNAME: Result := 'C_CUR_MNAME';
- C_CURMTL_FROM_MESH: Result := 'C_CURMTL_FROM_MESH';
- C_GET_SHAPE_MAKE_FACES: Result := 'C_GET_SHAPE_MAKE_FACES';
- C_DETAIL: Result := 'C_DETAIL';
- C_VERTMARK: Result := 'C_VERTMARK';
- C_MSHAX: Result := 'C_MSHAX';
- C_MSHCP: Result := 'C_MSHCP';
- C_USERAX: Result := 'C_USERAX';
- C_SHOOK: Result := 'C_SHOOK';
- C_RAX: Result := 'C_RAX';
- C_STAPE: Result := 'C_STAPE';
- C_LTAPE: Result := 'C_LTAPE';
- C_ETAPE: Result := 'C_ETAPE';
- C_KTAPE: Result := 'C_KTAPE';
- C_SPHSEGS: Result := 'C_SPHSEGS';
- C_GEOSMOOTH: Result := 'C_GEOSMOOTH';
- C_HEMISEGS: Result := 'C_HEMISEGS';
- C_PRISMSEGS: Result := 'C_PRISMSEGS';
- C_PRISMSIDES: Result := 'C_PRISMSIDES';
- C_TUBESEGS: Result := 'C_TUBESEGS';
- C_TUBESIDES: Result := 'C_TUBESIDES';
- C_TORSEGS: Result := 'C_TORSEGS';
- C_TORSIDES: Result := 'C_TORSIDES';
- C_CONESIDES: Result := 'C_CONESIDES';
- C_CONESEGS: Result := 'C_CONESEGS';
- C_NGPARMS: Result := 'C_NGPARMS';
- C_PTHLEVEL: Result := 'C_PTHLEVEL';
- C_MSCSYM: Result := 'C_MSCSYM';
- C_MFTSYM: Result := 'C_MFTSYM';
- C_MTTSYM: Result := 'C_MTTSYM';
- C_SMOOTHING: Result := 'C_SMOOTHING';
- C_MODICOUNT: Result := 'C_MODICOUNT';
- C_FONTSEL: Result := 'C_FONTSEL';
- C_TESS_TYPE: Result := 'C_TESS_TYPE';
- C_TESS_TENSION: Result := 'C_TESS_TENSION';
- C_SEG_START: Result := 'C_SEG_START';
- C_SEG_END: Result := 'C_SEG_END';
- C_CURTIME: Result := 'C_CURTIME';
- C_ANIMLENGTH: Result := 'C_ANIMLENGTH';
- C_PV_FROM: Result := 'C_PV_FROM';
- C_PV_TO: Result := 'C_PV_TO';
- C_PV_DOFNUM: Result := 'C_PV_DOFNUM';
- C_PV_RNG: Result := 'C_PV_RNG';
- C_PV_NTH: Result := 'C_PV_NTH';
- C_PV_TYPE: Result := 'C_PV_TYPE';
- C_PV_METHOD: Result := 'C_PV_METHOD';
- C_PV_FPS: Result := 'C_PV_FPS';
- C_VTR_FRAMES: Result := 'C_VTR_FRAMES';
- C_VTR_HDTL: Result := 'C_VTR_HDTL';
- C_VTR_HD: Result := 'C_VTR_HD';
- C_VTR_TL: Result := 'C_VTR_TL';
- C_VTR_IN: Result := 'C_VTR_IN';
- C_VTR_PK: Result := 'C_VTR_PK';
- C_VTR_SH: Result := 'C_VTR_SH';
- // Material chunks
- C_WORK_MTLS: Result := 'C_WORK_MTLS';
- C_WORK_MTLS_2: Result := 'C_WORK_MTLS_2';
- C_WORK_MTLS_3: Result := 'C_WORK_MTLS_3';
- C_WORK_MTLS_4: Result := 'C_WORK_MTLS_4';
- C_WORK_MTLS_5: Result := 'C_WORK_MTLS_5';
- C_WORK_MTLS_6: Result := 'C_WORK_MTLS_6';
- C_WORK_MTLS_7: Result := 'C_WORK_MTLS_7';
- C_WORK_MTLS_8: Result := 'C_WORK_MTLS_8';
- C_WORKMTL: Result := 'C_WORKMTL';
- C_SXP_TEXT_DATA: Result := 'C_SXP_TEXT_DATA';
- C_SXP_TEXT2_DATA: Result := 'C_SXP_TEXT2_DATA';
- C_SXP_OPAC_DATA: Result := 'C_SXP_OPAC_DATA';
- C_SXP_BUMP_DATA: Result := 'C_SXP_BUMP_DATA';
- C_SXP_SPEC_DATA: Result := 'C_SXP_SPEC_DATA';
- C_SXP_SHIN_DATA: Result := 'C_SXP_SHIN_DATA';
- C_SXP_SELFI_DATA: Result := 'C_SXP_SELFI_DATA';
- C_SXP_TEXT_MASKDATA: Result := 'C_SXP_TEXT_MASKDATA';
- C_SXP_TEXT2_MASKDATA: Result := 'C_SXP_TEXT2_MASKDATA';
- C_SXP_OPAC_MASKDATA: Result := 'C_SXP_OPAC_MASKDATA';
- C_SXP_BUMP_MASKDATA: Result := 'C_SXP_BUMP_MASKDATA';
- C_SXP_SPEC_MASKDATA: Result := 'C_SXP_SPEC_MASKDATA';
- C_SXP_SHIN_MASKDATA: Result := 'C_SXP_SHIN_MASKDATA';
- C_SXP_SELFI_MASKDATA: Result := 'C_SXP_SELFI_MASKDATA';
- C_SXP_REFL_MASKDATA: Result := 'C_SXP_REFL_MASKDATA';
- C_BGTYPE: Result := 'C_BGTYPE';
- C_MEDTILE: Result := 'C_MEDTILE';
- // Contrast
- C_LO_CONTRAST: Result := 'C_LO_CONTRAST';
- C_HI_CONTRAST: Result := 'C_HI_CONTRAST';
- // 3D frozen display
- C_FROZ_DISPLAY: Result := 'C_FROZ_DISPLAY';
- // Booleans
- C_BOOLWELD: Result := 'C_BOOLWELD';
- C_BOOLTYPE: Result := 'C_BOOLTYPE';
- C_ANG_THRESH: Result := 'C_ANG_THRESH';
- C_SS_THRESH: Result := 'C_SS_THRESH';
- C_TEXTURE_BLUR_DEFAULT: Result := 'C_TEXTURE_BLUR_DEFAULT';
- C_MAPDRAWER: Result := 'C_MAPDRAWER';
- C_MAPDRAWER1: Result := 'C_MAPDRAWER1';
- C_MAPDRAWER2: Result := 'C_MAPDRAWER2';
- C_MAPDRAWER3: Result := 'C_MAPDRAWER3';
- C_MAPDRAWER4: Result := 'C_MAPDRAWER4';
- C_MAPDRAWER5: Result := 'C_MAPDRAWER5';
- C_MAPDRAWER6: Result := 'C_MAPDRAWER6';
- C_MAPDRAWER7: Result := 'C_MAPDRAWER7';
- C_MAPDRAWER8: Result := 'C_MAPDRAWER8';
- C_MAPDRAWER9: Result := 'C_MAPDRAWER9';
- C_MAPDRAWER_ENTRY: Result := 'C_MAPDRAWER_ENTRY';
- // system options
- C_BACKUP_FILE: Result := 'C_BACKUP_FILE';
- C_DITHER_256: Result := 'C_DITHER_256';
- C_SAVE_LAST: Result := 'C_SAVE_LAST';
- C_USE_ALPHA: Result := 'C_USE_ALPHA';
- C_TGA_DEPTH: Result := 'C_TGA_DEPTH';
- C_REND_FIELDS: Result := 'C_REND_FIELDS';
- C_REFLIP: Result := 'C_REFLIP';
- C_SEL_ITEMTOG: Result := 'C_SEL_ITEMTOG';
- C_SEL_RESET: Result := 'C_SEL_RESET';
- C_STICKY_KEYINF: Result := 'C_STICKY_KEYINF';
- C_WELD_THRESHOLD: Result := 'C_WELD_THRESHOLD';
- C_ZCLIP_POINT: Result := 'C_ZCLIP_POINT';
- C_ALPHA_SPLIT: Result := 'C_ALPHA_SPLIT';
- C_KF_SHOW_BACKFACE: Result := 'C_KF_SHOW_BACKFACE';
- C_OPTIMIZE_LOFT: Result := 'C_OPTIMIZE_LOFT';
- C_TENS_DEFAULT: Result := 'C_TENS_DEFAULT';
- C_CONT_DEFAULT: Result := 'C_CONT_DEFAULT';
- C_BIAS_DEFAULT: Result := 'C_BIAS_DEFAULT';
- C_DXFNAME_SRC: Result := 'C_DXFNAME_SRC ';
- C_AUTO_WELD: Result := 'C_AUTO_WELD ';
- C_AUTO_UNIFY: Result := 'C_AUTO_UNIFY ';
- C_AUTO_SMOOTH: Result := 'C_AUTO_SMOOTH ';
- C_DXF_SMOOTH_ANG: Result := 'C_DXF_SMOOTH_ANG ';
- C_SMOOTH_ANG: Result := 'C_SMOOTH_ANG ';
- // Special network-use chunks
- C_NET_USE_VPOST: Result := 'C_NET_USE_VPOST';
- C_NET_USE_GAMMA: Result := 'C_NET_USE_GAMMA';
- C_NET_FIELD_ORDER: Result := 'C_NET_FIELD_ORDER';
- C_BLUR_FRAMES: Result := 'C_BLUR_FRAMES';
- C_BLUR_SAMPLES: Result := 'C_BLUR_SAMPLES';
- C_BLUR_DUR: Result := 'C_BLUR_DUR';
- C_HOT_METHOD: Result := 'C_HOT_METHOD';
- C_HOT_CHECK: Result := 'C_HOT_CHECK';
- C_PIXEL_SIZE: Result := 'C_PIXEL_SIZE';
- C_DISP_GAMMA: Result := 'C_DISP_GAMMA';
- C_FBUF_GAMMA: Result := 'C_FBUF_GAMMA';
- C_FILE_OUT_GAMMA: Result := 'C_FILE_OUT_GAMMA';
- C_FILE_IN_GAMMA: Result := 'C_FILE_IN_GAMMA';
- C_GAMMA_CORRECT: Result := 'C_GAMMA_CORRECT';
- C_APPLY_DISP_GAMMA: Result := 'C_APPLY_DISP_GAMMA';
- C_APPLY_FBUF_GAMMA: Result := 'C_APPLY_FBUF_GAMMA';
- C_APPLY_FILE_GAMMA: Result := 'C_APPLY_FILE_GAMMA';
- C_FORCE_WIRE: Result := 'C_FORCE_WIRE';
- C_RAY_SHADOWS: Result := 'C_RAY_SHADOWS';
- C_MASTER_AMBIENT: Result := 'C_MASTER_AMBIENT';
- C_SUPER_SAMPLE: Result := 'C_SUPER_SAMPLE';
- C_OBJECT_MBLUR: Result := 'C_OBJECT_MBLUR';
- C_MBLUR_DITHER: Result := 'C_MBLUR_DITHER';
- C_DITHER_24: Result := 'C_DITHER_24';
- C_SUPER_BLACK: Result := 'C_SUPER_BLACK';
- C_SAFE_FRAME: Result := 'C_SAFE_FRAME';
- C_VIEW_PRES_RATIO: Result := 'C_VIEW_PRES_RATIO';
- C_BGND_PRES_RATIO: Result := 'C_BGND_PRES_RATIO';
- C_NTH_SERIAL_NUM: Result := 'C_NTH_SERIAL_NUM';
- VPDATA: Result := 'VPDATA';
- P_QUEUE_ENTRY: Result := 'P_QUEUE_ENTRY';
- P_QUEUE_IMAGE: Result := 'P_QUEUE_IMAGE';
- P_QUEUE_USEIGAMMA: Result := 'P_QUEUE_USEIGAMMA';
- P_QUEUE_PROC: Result := 'P_QUEUE_PROC';
- P_QUEUE_SOLID: Result := 'P_QUEUE_SOLID';
- P_QUEUE_GRADIENT: Result := 'P_QUEUE_GRADIENT';
- P_QUEUE_KF: Result := 'P_QUEUE_KF';
- P_QUEUE_MOTBLUR: Result := 'P_QUEUE_MOTBLUR';
- P_QUEUE_MB_REPEAT: Result := 'P_QUEUE_MB_REPEAT';
- P_QUEUE_NONE: Result := 'P_QUEUE_NONE';
- P_QUEUE_RESIZE: Result := 'P_QUEUE_RESIZE';
- P_QUEUE_OFFSET: Result := 'P_QUEUE_OFFSET';
- P_QUEUE_ALIGN: Result := 'P_QUEUE_ALIGN';
- P_CUSTOM_SIZE: Result := 'P_CUSTOM_SIZE';
- P_ALPH_NONE: Result := 'P_ALPH_NONE';
- P_ALPH_PSEUDO: Result := 'P_ALPH_PSEUDO';
- P_ALPH_OP_PSEUDO: Result := 'P_ALPH_OP_PSEUDO';
- P_ALPH_BLUR: Result := 'P_ALPH_BLUR';
- P_ALPH_PCOL: Result := 'P_ALPH_PCOL';
- P_ALPH_C0: Result := 'P_ALPH_C0';
- P_ALPH_OP_KEY: Result := 'P_ALPH_OP_KEY';
- P_ALPH_KCOL: Result := 'P_ALPH_KCOL';
- P_ALPH_OP_NOCONV: Result := 'P_ALPH_OP_NOCONV';
- P_ALPH_IMAGE: Result := 'P_ALPH_IMAGE';
- P_ALPH_ALPHA: Result := 'P_ALPH_ALPHA';
- P_ALPH_QUES: Result := 'P_ALPH_QUES';
- P_ALPH_QUEIMG: Result := 'P_ALPH_QUEIMG';
- P_ALPH_CUTOFF: Result := 'P_ALPH_CUTOFF';
- P_ALPHANEG: Result := 'P_ALPHANEG';
- P_TRAN_NONE: Result := 'P_TRAN_NONE';
- P_TRAN_IMAGE: Result := 'P_TRAN_IMAGE';
- P_TRAN_FRAMES: Result := 'P_TRAN_FRAMES';
- P_TRAN_FADEIN: Result := 'P_TRAN_FADEIN';
- P_TRAN_FADEOUT: Result := 'P_TRAN_FADEOUT';
- P_TRANNEG: Result := 'P_TRANNEG';
- P_RANGES: Result := 'P_RANGES';
- P_PROC_DATA: Result := 'P_PROC_DATA'
- else
- Result := 'UNKNOWN_CHUNK';
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- const
- IndentString: string = #9#9#9#9#9#9#9#9#9#9#9#9;
- function Indent(Level: integer): string;
- begin
- Result := Copy(IndentString, 1, Level);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure ChunkHeaderReport(var Strings: TStrings; Chunk: PChunk3DS;
- IndentLevel: integer);
- var
- OutString: string;
- begin
- OutString := Format('%sChunk %s ($%x), Length is %d ($%3:x)',
- [Indent(IndentLevel), ChunkTagToString(Chunk^.Tag), Chunk^.Tag, Chunk^.Size]);
- Strings.Add(OutString);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure DumpKeyHeader(Strings: TStrings; const Key: TKeyHeader3DS; IndentLevel: integer);
- var
- Output: string;
- begin
- Output := Format('%sFrame %d', [Indent(IndentLevel), Key.Time]);
- if (Key.rflags and KeyUsesTension3DS) <> 0 then
- Output := Output + Format(', Tens %.2f', [Key.Tension]);
- if (Key.rflags and KeyUsesCont3DS) <> 0 then
- Output := Output + Format(', Cont %.2f', [Key.Continuity]);
- if (Key.rflags and KeyUsesBias3DS) <> 0 then
- Output := Output + Format(', Bias %.2f', [Key.Bias]);
- if (Key.rflags and KeyUsesEaseTo3DS) <> 0 then
- Output := Output + Format(', Ease to %.2f', [Key.EaseTo]);
- if (Key.rflags and KeyUsesEaseFrom3DS) <> 0 then
- Output := Output + Format(', Ease from %.2f', [Key.EaseFrom]);
- Strings.Add(Output);
- end;
- //-----------------------------------------------------------------------------
- procedure DumpChunk(const Source: TFile3DS; var Strings: TStrings;
- Chunk: PChunk3DS; IndentLevel: integer; DumpLevel: TDumpLevel);
- // retrieves the Data for a Chunk from the given Source, formats the Data into
- // one or more lines of text and puts the lines into the given Strings parameter
- var
- Child: PChunk3DS;
- Output: string;
- ID: string;
- I: integer;
- begin
- ChunkHeaderReport(Strings, Chunk, IndentLevel);
- ID := Indent(IndentLevel) + #9;
- if DumpLevel <> dlTerseDump then
- begin
- case Chunk^.Tag of
- MESH_VERSION:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sVersion %d', [ID, Chunk^.Data.MeshVersion^]);
- Strings.Add(Output);
- end;
- M3D_VERSION:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sVersion %d', [ID, Chunk^.Data.M3DVersion^]);
- Strings.Add(Output);
- end;
- COLOR_F:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sColor R: %f, ', [ID, Chunk^.Data.ColorF^.Red]);
- Output := Output + Format(' G: %f, ', [Chunk^.Data.ColorF^.Green]);
- Output := Output + Format(' B: %f', [Chunk^.Data.ColorF^.Blue]);
- Strings.Add(Output);
- end;
- LIN_COLOR_F:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sColor R: %f, ', [ID, Chunk^.Data.LinColorF^.Red]);
- Output := Output + Format(' G: %f, ', [Chunk^.Data.LinColorF^.Green]);
- Output := Output + Format(' B: %f', [Chunk^.Data.LinColorF^.Blue]);
- Strings.Add(Output);
- end;
- COLOR_24:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.Color24^.Red]);
- Output := Output + Format(' G: %d, ', [Chunk^.Data.Color24^.Green]);
- Output := Output + Format(' B: %d', [Chunk^.Data.Color24^.Blue]);
- Strings.Add(Output);
- end;
- LIN_COLOR_24:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.LinColor24^.Red]);
- Output := Output + Format(' G: %d, ', [Chunk^.Data.LinColor24^.Green]);
- Output := Output + Format(' B: %d', [Chunk^.Data.LinColor24^.Blue]);
- Strings.Add(Output);
- end;
- INT_PERCENTAGE:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sPercentage of %d%%', [ID, Chunk^.Data.IntPercentage^]);
- Strings.Add(Output);
- end;
- FLOAT_PERCENTAGE:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sPercentage of %f%%', [ID, Chunk^.Data.FloatPercentage^]);
- Strings.Add(Output);
- end;
- MASTER_SCALE:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMaster Scale %f', [ID, Chunk^.Data.MasterScale^]);
- Strings.Add(Output);
- end;
- BIT_MAP:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sBitmap Name %s', [ID, Chunk^.Data.BitMapName^]);
- Strings.Add(Output);
- end;
- V_GRADIENT:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMidpoint %f', [ID, Chunk^.Data.VGradient^]);
- Strings.Add(Output);
- end;
- LO_SHADOW_BIAS:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sBias of %f', [ID, Chunk^.Data.LoShadowBias^]);
- Strings.Add(Output);
- end;
- HI_SHADOW_BIAS:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sBias of %f', [ID, Chunk^.Data.HiShadowBias^]);
- Strings.Add(Output);
- end;
- RAY_BIAS:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sBias of %f', [ID, Chunk^.Data.RayBias^]);
- Strings.Add(Output);
- end;
- SHADOW_MAP_SIZE:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sSize of %d', [ID, Chunk^.Data.ShadowMapSize^]);
- Strings.Add(Output);
- end;
- SHADOW_SAMPLES:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sSize of %d', [ID, Chunk^.Data.ShadowSamples^]);
- Strings.Add(Output);
- end;
- SHADOW_RANGE:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sRange of %d', [ID, Chunk^.Data.ShadowRange^]);
- Strings.Add(Output);
- end;
- SHADOW_FILTER:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sFilter of %f', [ID, Chunk^.Data.ShadowFilter^]);
- Strings.Add(Output);
- end;
- O_CONSTS:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sPlane at %f, %f, %f',
- [ID, Chunk^.Data.OConsts^.X, Chunk^.Data.OConsts^.Y, Chunk^.Data.OConsts^.Z]);
- Strings.Add(Output);
- end;
- FOG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sNear plane at %f', [ID, Chunk^.Data.Fog^.NearPlaneDist]);
- Strings.Add(Output);
- Output := Format('%sNear Density of %f',
- [ID, Chunk^.Data.Fog^.NearPlaneDensity]);
- Strings.Add(Output);
- Output := Format('%sFar plane at %f', [ID, Chunk^.Data.Fog^.FarPlaneDist]);
- Strings.Add(Output);
- Output := Format('%sFar Density of %f',
- [ID, Chunk^.Data.Fog^.FarPlaneDensity]);
- Strings.Add(Output);
- end;
- LAYER_FOG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sFog Z range is %f to %f',
- [ID, Chunk^.Data.LayerFog^.ZMin, Chunk^.Data.LayerFog^.ZMax]);
- Strings.Add(Output);
- Output := Format('%sFog Density is %f', [ID, Chunk^.Data.LayerFog^.Density]);
- Strings.Add(Output);
- Output := Format('%sFog type of $%x', [ID, Chunk^.Data.LayerFog^.AType]);
- Strings.Add(Output);
- end;
- DISTANCE_CUE:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sNear plane at %f',
- [ID, Chunk^.Data.DistanceCue^.NearPlaneDist]);
- Strings.Add(Output);
- Output := Format('%sNear Density of %f',
- [ID, Chunk^.Data.DistanceCue^.NearPlaneDimming]);
- Strings.Add(Output);
- Output := Format('%sFar plane at %f',
- [ID, Chunk^.Data.DistanceCue^.FarPlaneDist]);
- Strings.Add(Output);
- Output := Format('%sFar Density of %f',
- [ID, Chunk^.Data.DistanceCue^.FarPlaneDimming]);
- Strings.Add(Output);
- end;
- VIEW_TOP,
- VIEW_BOTTOM,
- VIEW_LEFT,
- VIEW_RIGHT,
- VIEW_FRONT,
- VIEW_BACK:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sTarget at %f, %f, %f',
- [ID, Chunk^.Data.ViewStandard^.ViewTargetCoord.X,
- Chunk^.Data.ViewStandard^.ViewTargetCoord.Y,
- Chunk^.Data.ViewStandard^.ViewTargetCoord.Z]);
- Strings.Add(Output);
- Output := Format('%sView Width of %f',
- [ID, Chunk^.Data.ViewStandard^.ViewWidth]);
- Strings.Add(Output);
- end;
- VIEW_USER:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sTarget at %f, %f, %f',
- [ID, Chunk^.Data.ViewUser^.ViewTargetCoord.X,
- Chunk^.Data.ViewUser^.ViewTargetCoord.Y,
- Chunk^.Data.ViewUser^.ViewTargetCoord.Z]);
- Strings.Add(Output);
- Output := Format('%sView Width of %f', [ID, Chunk^.Data.ViewUser^.ViewWidth]);
- Strings.Add(Output);
- Output := Format('%sHorizontal View angle of %f',
- [ID, Chunk^.Data.ViewUser^.XYViewAngle]);
- Strings.Add(Output);
- Output := Format('%sVertical View angle of %f',
- [ID, Chunk^.Data.ViewUser^.YZViewAngle]);
- Strings.Add(Output);
- Output := Format('%sBank angle of %f', [ID, Chunk^.Data.ViewUser^.BankAngle]);
- Strings.Add(Output);
- end;
- VIEW_CAMERA:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sCamera Name %s', [ID, Chunk^.Data.ViewCamera^]);
- Strings.Add(Output);
- end;
- NAMED_OBJECT:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sName: %s', [ID, Chunk^.Data.NamedObject^]);
- Strings.Add(Output);
- end;
- POINT_ARRAY:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Vertices', [ID, Chunk^.Data.PointArray^.Vertices]);
- Strings.Add(Output);
- if DumpLevel = dlMaximumDump then
- for I := 0 to Chunk^.Data.PointArray^.Vertices - 1 do
- begin
- Output := Format('%sVertex %d at %f, %f, %f',
- [ID, I, Chunk^.Data.PointArray^.PointList^[I].X,
- Chunk^.Data.PointArray^.PointList^[I].Y,
- Chunk^.Data.PointArray^.PointList^[I].Z]);
- Strings.Add(Output);
- end;
- end;
- POINT_FLAG_ARRAY:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sFlags: %d', [ID, Chunk^.Data.PointFlagArray^.Flags]);
- Strings.Add(Output);
- if DumpLevel = dlMaximumDump then
- for I := 0 to Chunk^.Data.PointFlagArray^.Flags - 1 do
- begin
- Output := Format('%sFlag %d is %d',
- [ID, I, Chunk^.Data.PointFlagArray^.FlagList^[I]]);
- Strings.Add(Output);
- end;
- end;
- FACE_ARRAY:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Faces', [ID, Chunk^.Data.FaceArray^.Faces]);
- Strings.Add(Output);
- if DumpLevel = dlMaximumDump then
- for I := 0 to Chunk^.Data.FaceArray^.Faces - 1 do
- begin
- Output := Format('%sFace %d Vertices %d, %d, %d and flag $%x',
- [ID, I, Chunk^.Data.FaceArray^.FaceList^[I].V1,
- Chunk^.Data.FaceArray^.FaceList^[I].V2,
- Chunk^.Data.FaceArray^.FaceList^[I].V3,
- Chunk^.Data.FaceArray^.FaceList^[I].Flag]);
- Strings.Add(Output);
- end;
- end;
- MSH_MAT_GROUP:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMaterial Name of %s',
- [ID, Chunk^.Data.MshMatGroup^.MatNameStr]);
- Strings.Add(Output);
- Output := Format('%sAssigned to %d Faces',
- [ID, Chunk^.Data.MshMatGroup^.Faces]);
- Strings.Add(Output);
- end;
- MSH_BOXMAP:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sBoxmap consists of the following materials:', [ID]);
- Strings.Add(Output);
- for I := 0 to 5 do
- begin
- Output := Format('%s%s', [ID, Chunk^.Data.MshBoxmap^[I]]);
- Strings.Add(Output);
- end;
- end;
- TEX_VERTS:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Vertices', [ID, Chunk^.Data.TexVerts^.NumCoords]);
- Strings.Add(Output);
- if DumpLevel = dlMaximumDump then
- begin
- for I := 0 to Chunk^.Data.TexVerts^.NumCoords - 1 do
- begin
- Output := Format('%sVertex %d with tex vert of %f, %f',
- [ID, I, Chunk^.Data.TexVerts^.TextVertList^[I].U,
- Chunk^.Data.TexVerts^.TextVertList^[I].V]);
- Strings.Add(Output);
- end;
- end;
- end;
- MESH_TEXTURE_INFO:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMap Type of %d',
- [ID, Chunk^.Data.MeshTextureInfo^.MapType]);
- Strings.Add(Output);
- Output := Format('%sX Tiling of %f',
- [ID, Chunk^.Data.MeshTextureInfo^.XTiling]);
- Strings.Add(Output);
- Output := Format('%sY Tiling of %f',
- [ID, Chunk^.Data.MeshTextureInfo^.YTiling]);
- Strings.Add(Output);
- Output := Format('%sIcon position of %f, %f, %f',
- [ID, Chunk^.Data.MeshTextureInfo^.IconPos.X,
- Chunk^.Data.MeshTextureInfo^.IconPos.Y,
- Chunk^.Data.MeshTextureInfo^.IconPos.Z]);
- Strings.Add(Output);
- I := 0;
- while I < 12 do
- begin
- Output := Format('%s[%d] %f [%d] %f [%d] %f',
- [ID, I, Chunk^.Data.MeshTextureInfo^.XMatrix[I], I +
- 1, Chunk^.Data.MeshTextureInfo^.XMatrix[I + 1], I +
- 2, Chunk^.Data.MeshTextureInfo^.XMatrix[I + 2]]);
- Strings.Add(Output);
- Inc(I, 3);
- end;
- Output := Format('%sScaling Value of %f',
- [ID, Chunk^.Data.MeshTextureInfo^.IconScaling]);
- Strings.Add(Output);
- Output := Format('%sPlanar Icon Width of %f',
- [ID, Chunk^.Data.MeshTextureInfo^.IconWidth]);
- Strings.Add(Output);
- Output := Format('%sPlanar Icon Height of %f',
- [ID, Chunk^.Data.MeshTextureInfo^.IconHeight]);
- Strings.Add(Output);
- Output := Format('%sCylinder Icon Height of %f',
- [ID, Chunk^.Data.MeshTextureInfo^.CylIconHeight]);
- Strings.Add(Output);
- end;
- MESH_MATRIX:
- begin
- Source.ReadChunkData(Chunk);
- I := 0;
- while I < 12 do
- begin
- Output := Format('%s[%d] %f [%d] %f [%d] %f',
- [ID, I, Chunk^.Data.MeshMatrix^[I], I + 1,
- Chunk^.Data.MeshMatrix^[I + 1], I + 2, Chunk^.Data.MeshMatrix^[I + 2]]);
- Strings.Add(Output);
- Inc(I, 3);
- end;
- end;
- PROC_NAME:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sProcedure Name of %s', [ID, Chunk^.Data.ProcName^]);
- Strings.Add(Output);
- end;
- MESH_COLOR:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sColor index of %d', [ID, Chunk^.Data.MeshColor^]);
- Strings.Add(Output);
- end;
- N_DIRECT_LIGHT:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sLight at %f, %f, %f',
- [ID, Chunk^.Data.NDirectLight^.X, Chunk^.Data.NDirectLight^.Y,
- Chunk^.Data.NDirectLight^.Z]);
- Strings.Add(Output);
- end;
- DL_EXCLUDE:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sExclude %s', [ID, Chunk^.Data.DLExclude^]);
- Strings.Add(Output);
- end;
- DL_OUTER_RANGE,
- DL_INNER_RANGE:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sRange of %f', [ID, Chunk^.Data.DlOuterRange^]);
- Strings.Add(Output);
- end;
- DL_MULTIPLIER:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMultiple of %f', [ID, Chunk^.Data.DlMultiplier^]);
- Strings.Add(Output);
- end;
- DL_SPOT_ROLL:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sRoll angle of %f', [ID, Chunk^.Data.DlSpotRoll^]);
- Strings.Add(Output);
- end;
- DL_SPOT_ASPECT:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sSpot aspect of %f', [ID, Chunk^.Data.DlSpotAspect^]);
- Strings.Add(Output);
- end;
- DL_SPOT_PROJECTOR:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sFilename of projector is %s',
- [ID, Chunk^.Data.DlSpotProjector^]);
- Strings.Add(Output);
- end;
- DL_RAY_BIAS:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sBias of %f', [ID, Chunk^.Data.DlRayBias^]);
- Strings.Add(Output);
- end;
- DL_SPOTLIGHT:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sTarget at %f, %f, %f',
- [ID, Chunk^.Data.DlSpotlight^.SpotlightTarg.X,
- Chunk^.Data.DlSpotlight^.SpotlightTarg.Y,
- Chunk^.Data.DlSpotlight^.SpotlightTarg.Z]);
- Strings.Add(Output);
- Output := Format('%sHotspot cone of %f, ',
- [ID, Chunk^.Data.DlSpotlight^.HotspotAngle]);
- Output := Output + Format(' Falloff cone of %f',
- [Chunk^.Data.DlSpotlight^.FalloffAngle]);
- Strings.Add(Output);
- end;
- DL_LOCAL_SHADOW2:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sShadow bias of %f',
- [ID, Chunk^.Data.DlLocalShadow2^.LocalShadowBias]);
- Strings.Add(Output);
- Output := Format('%sShadow filter of %f',
- [ID, Chunk^.Data.DlLocalShadow2^.LocalShadowFilter]);
- Strings.Add(Output);
- Output := Format('%sShadow Map Size of %f',
- [ID, Chunk^.Data.DlLocalShadow2^.LocalShadowMapSize]);
- Strings.Add(Output);
- end;
- N_CAMERA:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sCamera at %f, %f, %f',
- [ID, Chunk^.Data.NCamera^.CameraPos.X, Chunk^.Data.NCamera^.CameraPos.Y,
- Chunk^.Data.NCamera^.CameraPos.Z]);
- Strings.Add(Output);
- Output := Format('%sTarget at %f, %f, %f',
- [ID, Chunk^.Data.NCamera^.TargetPos.X, Chunk^.Data.NCamera^.TargetPos.Y,
- Chunk^.Data.NCamera^.TargetPos.Z]);
- Strings.Add(Output);
- Output := Format('%sBank angle of %f', [ID, Chunk^.Data.NCamera^.CameraBank]);
- Output := Output + Format(' and a foc of %f',
- [Chunk^.Data.NCamera^.CameraFocalLength]);
- Strings.Add(Output);
- end;
- CAM_RANGES:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sCamera near range is %f and far range is %f',
- [ID, Chunk^.Data.CamRanges^.NearPlane, Chunk^.Data.CamRanges^.FarPlane]);
- Strings.Add(Output);
- end;
- VIEWPORT_LAYOUT:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sForm of %d', [ID, Chunk^.Data.ViewportLayout^.Form]);
- Strings.Add(Output);
- Output := Format('%sTop of %d', [ID, Chunk^.Data.ViewportLayout^.Top]);
- Strings.Add(Output);
- Output := Format('%sReady of %d', [ID, Chunk^.Data.ViewportLayout^.Ready]);
- Strings.Add(Output);
- Output := Format('%sWState of %d', [ID, Chunk^.Data.ViewportLayout^.WState]);
- Strings.Add(Output);
- Output := Format('%sSwap WS of %d', [ID, Chunk^.Data.ViewportLayout^.SwapWS]);
- Strings.Add(Output);
- Output := Format('%sSwap Port of %d',
- [ID, Chunk^.Data.ViewportLayout^.SwapPort]);
- Strings.Add(Output);
- Output := Format('%sSwap Cur of %d',
- [ID, Chunk^.Data.ViewportLayout^.SwapCur]);
- Strings.Add(Output);
- end;
- VIEWPORT_SIZE:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sWork Area X: %d Y: %d W: %d H: %d',
- [ID, Chunk^.Data.ViewportSize^.XPos, Chunk^.Data.ViewportSize^.YPos,
- Chunk^.Data.ViewportSize^.Width,
- Chunk^.Data.ViewportSize^.Height]);
- Strings.Add(Output);
- end;
- VIEWPORT_DATA_3,
- VIEWPORT_DATA:
- begin
- Source.ReadChunkData(Chunk);
- with Chunk^.Data.ViewportData^ do
- begin
- Output := Format('%sFlags: $%x', [ID, Flags]);
- Strings.Add(Output);
- Output := Format('%sAxis Lockouts of $%x', [ID, AxisLockout]);
- Strings.Add(Output);
- Output := Format('%sWindow Position of %d, %d', [ID, WinXPos, WinYPos]);
- Strings.Add(Output);
- Output := Format('%sWindow Size of %d, %d', [ID, WinWidth, WinHeight]);
- Strings.Add(Output);
- Output := Format('%sWindow View of %d', [ID, View]);
- Strings.Add(Output);
- Output := Format('%sZoom Factor of %f', [ID, ZoomFactor]);
- Strings.Add(Output);
- Output := Format('%sWorld Center of %f, %f, %f',
- [ID, Center.X, Center.Y, Center.Z]);
- Strings.Add(Output);
- Output := Format('%sHorizontal Angle of %f', [ID, HorizAng]);
- Strings.Add(Output);
- Output := Format('%sVertical Angle of %f', [ID, VertAng]);
- Strings.Add(Output);
- Output := Format('%sCamera Name of %s', [ID, CamNameStr]);
- Strings.Add(Output);
- end;
- end;
- XDATA_APPNAME:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sApplication Name %s', [ID, Chunk^.Data.XDataAppName^]);
- Strings.Add(Output);
- end;
- XDATA_STRING:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sString value of %s', [ID, Chunk^.Data.XDataString^]);
- Strings.Add(Output);
- end;
- MAT_NAME:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMaterial Name %s', [ID, Chunk^.Data.MatName^]);
- Strings.Add(Output);
- end;
- MAT_SHADING:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sShading value of %d', [ID, Chunk^.Data.MatShading^]);
- Strings.Add(Output);
- end;
- MAT_ACUBIC:
- begin
- Source.ReadChunkData(Chunk);
- with Chunk^.Data.MatAcubic^ do
- begin
- Output := Format('%sShade level of %d', [ID, ShadeLevel]);
- Strings.Add(Output);
- Output := Format('%sAntialias level of %d', [ID, AntiAlias]);
- Strings.Add(Output);
- Output := Format('%sFlags: %d', [ID, Flags]);
- Strings.Add(Output);
- Output := Format('%sMap Size of %d', [ID, MapSize]);
- Strings.Add(Output);
- Output := Format('%sFrame skip of %d', [ID, FrameInterval]);
- Strings.Add(Output);
- end;
- end;
- MAT_MAPNAME:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMap Name %s', [ID, Chunk^.Data.MatMapname^]);
- Strings.Add(Output);
- end;
- MAT_WIRESIZE:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sWire frame Size of %f', [ID, Chunk^.Data.MatWireSize^]);
- Strings.Add(Output);
- end;
- MAT_MAP_TILING:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMap Flags: ', [ID]);
- if (Chunk^.Data.MatMapTiling^ = 0) then
- Output := Output + ' NONE'
- else
- begin
- if (Chunk^.Data.MatMapTiling^ and TEX_DECAL) <> 0 then
- Output := Output + ' TEX_DECAL, ';
- if (Chunk^.Data.MatMapTiling^ and TEX_MIRROR) <> 0 then
- Output := Output + ' TEX_MIRROR, ';
- if (Chunk^.Data.MatMapTiling^ and TEX_UNUSED1) <> 0 then
- Output := Output + ' TEX_UNUSED1, ';
- if (Chunk^.Data.MatMapTiling^ and TEX_INVERT) <> 0 then
- Output := Output + ' TEX_INVERT, ';
- if (Chunk^.Data.MatMapTiling^ and TEX_NOWRAP) <> 0 then
- Output := Output + ' TEX_NOWRAP, ';
- if (Chunk^.Data.MatMapTiling^ and TEX_SAT) <> 0 then
- Output := Output + ' TEX_SAT, ';
- if (Chunk^.Data.MatMapTiling^ and TEX_ALPHA_SOURCE) <> 0 then
- Output := Output + ' TEX_ALPHA_SOURCE, ';
- if (Chunk^.Data.MatMapTiling^ and TEX_TINT) <> 0 then
- Output := Output + ' TEX_TINT, ';
- if (Chunk^.Data.MatMapTiling^ and TEX_DONT_USE_ALPHA) <> 0 then
- Output := Output + ' TEX_DONT_USE_ALPHA, ';
- if (Chunk^.Data.MatMapTiling^ and TEX_RGB_TINT) <> 0 then
- Output := Output + ' TEX_RGB_TINT, ';
- Delete(Output, Length(Output) - 1, 2); // take the last comma out
- end;
- Strings.Add(Output);
- end;
- MAT_MAP_COL1:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.MatMapCol1^.Red]);
- Output := Output + Format(' G: %d, ', [Chunk^.Data.MatMapCol1^.Green]);
- Output := Output + Format(' B: %d', [Chunk^.Data.MatMapCol1^.Blue]);
- Strings.Add(Output);
- end;
- MAT_MAP_COL2:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.MatMapCol2^.Red]);
- Output := Output + Format(' G: %d, ', [Chunk^.Data.MatMapCol2^.Green]);
- Output := Output + Format(' B: %d', [Chunk^.Data.MatMapCol2^.Blue]);
- Strings.Add(Output);
- end;
- MAT_MAP_RCOL:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.MatMapRCol^.Red]);
- Output := Output + Format(' G: %d, ', [Chunk^.Data.MatMapRCol^.Green]);
- Output := Output + Format(' B: %d', [Chunk^.Data.MatMapRCol^.Blue]);
- Strings.Add(Output);
- end;
- MAT_MAP_GCOL:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.MatMapGCol^.Red]);
- Output := Output + Format(' G: %d, ', [Chunk^.Data.MatMapGCol^.Green]);
- Output := Output + Format(' B: %d', [Chunk^.Data.MatMapGCol^.Blue]);
- Strings.Add(Output);
- end;
- MAT_MAP_BCOL:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.MatMapBCol^.Red]);
- Output := Output + Format(' G: %d, ', [Chunk^.Data.MatMapBCol^.Green]);
- Output := Output + Format(' B: %d', [Chunk^.Data.MatMapBCol^.Blue]);
- Strings.Add(Output);
- end;
- MAT_MAP_TEXBLUR:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMap bluring of %f', [ID, Chunk^.Data.MatMapTexblur^]);
- Strings.Add(Output);
- end;
- MAT_MAP_USCALE:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMap U scale of %f', [ID, Chunk^.Data.MatMapUScale^]);
- Strings.Add(Output);
- end;
- MAT_MAP_VSCALE:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMap V scale of %f', [ID, Chunk^.Data.MatMapVScale^]);
- Strings.Add(Output);
- end;
- MAT_MAP_UOFFSET:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMap U offset of %f', [ID, Chunk^.Data.MatMapUOffset^]);
- Strings.Add(Output);
- end;
- MAT_MAP_VOFFSET:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMap V offset of %f', [ID, Chunk^.Data.MatMapVOffset^]);
- Strings.Add(Output);
- end;
- MAT_MAP_ANG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMap rotation angle of %f', [ID, Chunk^.Data.MatMapAng^]);
- Strings.Add(Output);
- end;
- MAT_BUMP_PERCENT:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sPercentage of %d%%', [ID, Chunk^.Data.MatBumpPercent^]);
- Strings.Add(Output);
- end;
- KFHDR:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sRevision level of $%x', [ID, Chunk^.Data.KFHdr^.Revision]);
- Strings.Add(Output);
- Output := Format('%sFilename %s', [ID, Chunk^.Data.KFHdr^.FileName]);
- Strings.Add(Output);
- Output := Format('%sAnimation length of %d',
- [ID, Chunk^.Data.KFHdr^.AnimLength]);
- Strings.Add(Output);
- end;
- KFSEG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sSegment starts at %d and ends at %d',
- [ID, Chunk^.Data.KFSeg^.First, Chunk^.Data.KFSeg^.Last]);
- Strings.Add(Output);
- end;
- KFCURTIME:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sCurrent frame is %d', [ID, Chunk^.Data.KFCurtime^]);
- Strings.Add(Output);
- end;
- NODE_ID:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sNode ID: %d', [ID, Chunk^.Data.KFID^]);
- Strings.Add(Output);
- end;
- NODE_HDR:
- begin
- Source.ReadChunkData(Chunk);
- Strings.Add(Format('%sObject Name: %s',
- [ID, Chunk^.Data.NodeHdr^.ObjNameStr]));
- //--- Flags 1
- Strings.Add(Format('%sFlags 1: $%x', [ID, Chunk^.Data.NodeHdr^.Flags1]));
- if DumpLevel = dlMaximumDump then
- with Chunk^.Data.NodeHdr^ do
- begin
- if (Flags1 and NODE_RENDOB_HIDE) <> 0 then
- Strings.Add(Format('%sNODE_RENDOB_HIDE', [ID]));
- if (Flags1 and NODE_OFF) <> 0 then
- Strings.Add(Format('%sNODE_OFF', [ID]));
- if (Flags1 and ATKEY1) <> 0 then
- Strings.Add(Format('%sATKEY1', [ID]));
- if (Flags1 and ATKEY2) <> 0 then
- Strings.Add(Format('%sATKEY2', [ID]));
- if (Flags1 and ATKEY3) <> 0 then
- Strings.Add(Format('%sATKEY3', [ID]));
- if (Flags1 and ATKEY4) <> 0 then
- Strings.Add(Format('%sATKEY4', [ID]));
- if (Flags1 and ATKEY5) <> 0 then
- Strings.Add(Format('%sATKEY5', [ID]));
- if (Flags1 and ATKEYFLAGS) <> 0 then
- Strings.Add(Format('%sATKEYFLAGS', [ID]));
- if (Flags1 and MARK_NODE) <> 0 then
- Strings.Add(Format('%sMARK_NODE', [ID]));
- if (Flags1 and DISABLE_NODE) <> 0 then
- Strings.Add(Format('%sDISABLE_NODE', [ID]));
- if (Flags1 and HIDE_NODE) <> 0 then
- Strings.Add(Format('%sHIDE_NODE', [ID]));
- if (Flags1 and FAST_NODE) <> 0 then
- Strings.Add(Format('%sFAST_NODE', [ID]));
- if (Flags1 and PRIMARY_NODE) <> 0 then
- Strings.Add(Format('%sPRIMARY_NODE', [ID]));
- if (Flags1 and NODE_CALC_PATH) <> 0 then
- Strings.Add(Format('%sNODE_CALC_PATH', [ID]));
- end;
- //--- Flags 2
- Strings.Add(Format('%sFlags 2: $%x', [ID, Chunk^.Data.NodeHdr^.Flags2]));
- if DumpLevel = dlMaximumDump then
- with Chunk^.Data.NodeHdr^ do
- begin
- if (Flags2 and NODE_HAS_PATH) <> 0 then
- Strings.Add(Format('%sNODE_HAS_PATH', [ID]));
- if (Flags2 and NODE_AUTO_SMOOTH) <> 0 then
- Strings.Add(Format('%sNODE_AUTO_SMOOTH', [ID]));
- if (Flags2 and NODE_FROZEN) <> 0 then
- Strings.Add(Format('%sNODE_FROZEN', [ID]));
- if (Flags2 and NODE_ANI_HIDDEN) <> 0 then
- Strings.Add(Format('%sNODE_ANI_HIDDEN', [ID]));
- if (Flags2 and NODE_MOTION_BLUR) <> 0 then
- Strings.Add(Format('%sNODE_MOTION_BLUR', [ID]));
- if (Flags2 and NODE_BLUR_BRANCH) <> 0 then
- Strings.Add(Format('%sNODE_BLUR_BRANCH', [ID]));
- if (Flags2 and NODE_MORPH_MTL) <> 0 then
- Strings.Add(Format('%sNODE_MORPH_MTL', [ID]));
- if (Flags2 and NODE_MORPH_OB) <> 0 then
- Strings.Add(Format('%sNODE_MORPH_OB', [ID]));
- end;
- if Chunk^.Data.NodeHdr^.ParentIndex = -1 then
- Strings.Add(Format('%sNo Parent', [ID]))
- else
- Strings.Add(Format('%sParent %d', [ID, Chunk^.Data.NodeHdr^.ParentIndex]));
- end;
- INSTANCE_NAME:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sInstance Name: %s', [ID, Chunk^.Data.InstanceName^]);
- Strings.Add(Output);
- end;
- PARENT_NAME:
- begin
- Source.ReadChunkData(Chunk);
- if Chunk^.Data.InstanceName = nil then
- Strings.Add(Format('%sNo Parent', [ID]))
- else
- Strings.Add(Format('%sParent Name: %s', [ID, Chunk^.Data.InstanceName^]));
- end;
- PIVOT:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sPivot at %f, %f, %f',
- [ID, Chunk^.Data.Pivot^.X, Chunk^.Data.Pivot^.Y,
- Chunk^.Data.Pivot^.Z]);
- Strings.Add(Output);
- end;
- BOUNDBOX:
- if Assigned(Chunk^.Data.Dummy) then
- begin
- Output := Format('%sMinimum at %f, %f, %f',
- [ID, Chunk^.Data.BoundBox^.Min.X, Chunk^.Data.BoundBox^.Min.Y,
- Chunk^.Data.BoundBox^.Min.Z]);
- Strings.Add(Output);
- Output := Format('%sMaximum at %f, %f, %f',
- [ID, Chunk^.Data.BoundBox^.Max.X, Chunk^.Data.BoundBox^.Max.Y,
- Chunk^.Data.BoundBox^.Max.Z]);
- Strings.Add(Output);
- end;
- MORPH_SMOOTH:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%sMorph Smoothing Angle of %f',
- [ID, Chunk^.Data.MorphSmooth^]);
- Strings.Add(Output);
- end;
- POS_TRACK_TAG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Keys, Flags: $%x',
- [ID, Chunk^.Data.PosTrackTag^.TrackHdr.KeyCount,
- Chunk^.Data.PosTrackTag^.TrackHdr.Flags]);
- Strings.Add(Output);
- for I := 0 to Chunk^.Data.PosTrackTag^.TrackHdr.KeyCount - 1 do
- begin
- DumpKeyHeader(Strings, Chunk^.Data.PosTrackTag^.KeyHdrList^[I],
- IndentLevel + 1);
- Output := Format('%sObject at %f, %f, %f',
- [ID, Chunk^.Data.PosTrackTag^.PositionList^[I].X,
- Chunk^.Data.PosTrackTag^.PositionList^[I].Y,
- Chunk^.Data.PosTrackTag^.PositionList^[I].Z]);
- Strings.Add(Output);
- end;
- end;
- ROT_TRACK_TAG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Keys, Flags: $%x',
- [ID, Chunk^.Data.RotTrackTag^.TrackHdr.KeyCount,
- Chunk^.Data.RotTrackTag^.TrackHdr.Flags]);
- Strings.Add(Output);
- for I := 0 to Chunk^.Data.RotTrackTag^.TrackHdr.KeyCount - 1 do
- begin
- DumpKeyHeader(Strings, Chunk^.Data.RotTrackTag^.KeyHdrList^[I],
- IndentLevel + 1);
- Output := Format('%sRotation of %f',
- [ID, Chunk^.Data.RotTrackTag^.RotationList^[I].Angle]);
- Strings.Add(Output);
- Output := Format('%sAxis of %f, %f, %f',
- [ID, Chunk^.Data.RotTrackTag^.RotationList^[I].X,
- Chunk^.Data.RotTrackTag^.RotationList^[I].Y,
- Chunk^.Data.RotTrackTag^.RotationList^[I].Z]);
- Strings.Add(Output);
- end;
- end;
- SCL_TRACK_TAG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Keys, Flags: $%x',
- [ID, Chunk^.Data.ScaleTrackTag^.TrackHdr.KeyCount,
- Chunk^.Data.ScaleTrackTag^.TrackHdr.Flags]);
- Strings.Add(Output);
- for I := 0 to Chunk^.Data.ScaleTrackTag^.TrackHdr.KeyCount - 1 do
- begin
- DumpKeyHeader(Strings, Chunk^.Data.ScaleTrackTag^.KeyHdrList^[I],
- IndentLevel + 1);
- Output := Format('%sScale of %f, %f, %f',
- [ID, Chunk^.Data.ScaleTrackTag^.ScaleList^[I].X,
- Chunk^.Data.ScaleTrackTag^.ScaleList^[I].Y,
- Chunk^.Data.ScaleTrackTag^.ScaleList^[I].Z]);
- Strings.Add(Output);
- end;
- end;
- FOV_TRACK_TAG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Keys, Flags: $%x',
- [ID, Chunk^.Data.FovTrackTag^.TrackHdr.KeyCount,
- Chunk^.Data.FovTrackTag^.TrackHdr.Flags]);
- Strings.Add(Output);
- for I := 0 to Chunk^.Data.FovTrackTag^.TrackHdr.KeyCount - 1 do
- begin
- DumpKeyHeader(Strings, Chunk^.Data.FovTrackTag^.KeyHdrList^[I],
- IndentLevel + 1);
- Output := Format('%sCamera FOV of %f',
- [ID, Chunk^.Data.FovTrackTag^.FOVAngleList^[I]]);
- Strings.Add(Output);
- end;
- end;
- ROLL_TRACK_TAG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Keys, Flags: $%x',
- [ID, Chunk^.Data.RollTrackTag^.TrackHdr.KeyCount,
- Chunk^.Data.RollTrackTag^.TrackHdr.Flags]);
- Strings.Add(Output);
- for I := 0 to Chunk^.Data.RollTrackTag^.TrackHdr.KeyCount - 1 do
- begin
- DumpKeyHeader(Strings, Chunk^.Data.RollTrackTag^.KeyHdrList^[I],
- IndentLevel + 1);
- Output := Format('%sCamera Roll of %f',
- [ID, Chunk^.Data.RollTrackTag^.RollAngleList^[I]]);
- Strings.Add(Output);
- end;
- end;
- COL_TRACK_TAG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Keys, Flags: $%x',
- [ID, Chunk^.Data.ColTrackTag^.TrackHdr.KeyCount,
- Chunk^.Data.ColTrackTag^.TrackHdr.Flags]);
- Strings.Add(Output);
- for I := 0 to Chunk^.Data.ColTrackTag^.TrackHdr.KeyCount - 1 do
- begin
- DumpKeyHeader(Strings, Chunk^.Data.ColTrackTag^.KeyHdrList^[I],
- IndentLevel + 1);
- Output := Format('%sColor R: %f, ',
- [ID, Chunk^.Data.ColTrackTag^.ColorList^[I].B]);
- Output := Output + Format(' G: %f, ',
- [Chunk^.Data.ColTrackTag^.ColorList^[I].G]);
- Output := Output + Format(' B: %f',
- [Chunk^.Data.ColTrackTag^.ColorList^[I].B]);
- Strings.Add(Output);
- end;
- end;
- MORPH_TRACK_TAG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Keys, Flags: $%x',
- [ID, Chunk^.Data.MorphTrackTag^.TrackHdr.KeyCount,
- Chunk^.Data.MorphTrackTag^.TrackHdr.Flags]);
- Strings.Add(Output);
- for I := 0 to Chunk^.Data.MorphTrackTag^.TrackHdr.KeyCount - 1 do
- begin
- DumpKeyHeader(Strings, Chunk^.Data.MorphTrackTag^.KeyHdrList^[I],
- IndentLevel + 1);
- Output := Format('%sMorph to %s',
- [ID, Chunk^.Data.MorphTrackTag^.MorphList^[I]]);
- Strings.Add(Output);
- end;
- end;
- HOT_TRACK_TAG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Keys, Flags: $%x',
- [ID, Chunk^.Data.HotTrackTag^.TrackHdr.KeyCount,
- Chunk^.Data.HotTrackTag^.TrackHdr.Flags]);
- Strings.Add(Output);
- for I := 0 to Chunk^.Data.HotTrackTag^.TrackHdr.KeyCount - 1 do
- begin
- DumpKeyHeader(Strings, Chunk^.Data.HotTrackTag^.KeyHdrList^[I],
- IndentLevel + 1);
- Output := Format('%sHotspot angle of %f',
- [ID, Chunk^.Data.HotTrackTag^.HotspotAngleList^[I]]);
- Strings.Add(Output);
- end;
- end;
- FALL_TRACK_TAG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Keys, Flags: $%x',
- [ID, Chunk^.Data.FallTrackTag^.TrackHdr.KeyCount,
- Chunk^.Data.FallTrackTag^.TrackHdr.Flags]);
- Strings.Add(Output);
- for I := 0 to Chunk^.Data.FallTrackTag^.TrackHdr.KeyCount - 1 do
- begin
- DumpKeyHeader(Strings, Chunk^.Data.FallTrackTag^.KeyHdrList^[I],
- IndentLevel + 1);
- Output := Format('%sFalloff Angle of %f',
- [ID, Chunk^.Data.FallTrackTag^.FalloffAngleList^[I]]);
- Strings.Add(Output);
- end;
- end;
- HIDE_TRACK_TAG:
- begin
- Source.ReadChunkData(Chunk);
- Output := Format('%s%d Keys, Flags: $%x',
- [ID, Chunk^.Data.HideTrackTag^.TrackHdr.KeyCount,
- Chunk^.Data.HideTrackTag^.TrackHdr.Flags]);
- Strings.Add(Output);
- for I := 0 to Chunk^.Data.HideTrackTag^.TrackHdr.KeyCount - 1 do
- DumpKeyHeader(Strings, Chunk^.Data.HideTrackTag^.KeyHdrList^[I],
- IndentLevel + 1);
- end;
- end; // end case
- end;
- Child := Chunk^.Children;
- while Assigned(Child) do
- begin
- DumpChunk(Source, Strings, Child, IndentLevel + 1, DumpLevel);
- Child := Child^.Sibling;
- end;
- end;
- //----------------- common support function ---------------------------------------------------------------------------
- procedure AddChild(Parent, Child: PChunk3DS);
- // AddChild puts the chunk at the end of the Sibling list
- var
- Current: PChunk3DS;
- begin
- if Parent^.Children = nil then
- Parent^.Children := Child
- else
- begin
- Current := Parent^.Children;
- while Assigned(Current^.Sibling) do
- Current := Current^.Sibling;
- Current^.Sibling := Child;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure AddChildOrdered(Parent, Child: PChunk3DS);
- // AddChildOrdered will insert the child among its siblings depending
- // on the order of occurance set by the 3DS file.
- var
- Current, Prev: PChunk3DS;
- ChildValue: integer;
- begin
- ChildValue := GetChunkValue(Child^.Tag);
- if Parent^.Children = nil then
- Parent^.Children := Child
- else
- begin
- Current := Parent^.Children;
- Prev := nil;
- while Assigned(Current^.Sibling) do
- begin
- if ChildValue > GetChunkValue(Current^.Tag) then
- break;
- Prev := Current;
- Current := Current^.Sibling;
- end;
- if ChildValue > GetChunkValue(Current^.Tag) then
- begin
- Child^.Sibling := Current;
- if Assigned(Prev) then
- Prev^.Sibling := Child
- else
- Parent^.Children := Child;
- end
- else
- begin
- Child^.Sibling := Current^.Sibling;
- Current^.Sibling := Child;
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function FindChunk(Top: PChunk3DS; Tag: word): PChunk3DS;
- // searchs the given top Chunk and its children for a match
- var
- Child, Match: PChunk3DS;
- begin
- Result := nil;
- if Assigned(Top) then
- if Top^.Tag = Tag then
- Result := Top
- else
- begin
- Child := Top^.Children;
- while Assigned(Child) do
- begin
- Match := FindChunk(Child, Tag);
- if Assigned(Match) then
- begin
- Result := Match;
- Break;
- end;
- Child := Child^.Sibling;
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function FindNextChunk(Local: PChunk3DS; Tag: word): PChunk3DS;
- var
- Current: PChunk3DS;
- begin
- Result := nil;
- Current := Local;
- while Assigned(Current) and (Result = nil) do
- begin
- if Current^.Tag = Tag then
- Result := Current;
- Current := Current^.Sibling;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure FreeChunkData(var Chunk: PChunk3DS);
- begin
- if Assigned(Chunk^.Data.Dummy) then
- begin
- // do only care about Chunk^.Data fields that contain other pointers
- // that need to be free
- case Chunk^.Tag of
- MAT_SXP_TEXT_DATA,
- MAT_SXP_TEXT2_DATA,
- MAT_SXP_OPAC_DATA,
- MAT_SXP_BUMP_DATA,
- MAT_SXP_SPEC_DATA,
- MAT_SXP_SHIN_DATA,
- MAT_SXP_SELFI_DATA,
- MAT_SXP_TEXT_MASKDATA,
- MAT_SXP_TEXT2_MASKDATA,
- MAT_SXP_OPAC_MASKDATA,
- MAT_SXP_BUMP_MASKDATA,
- MAT_SXP_SPEC_MASKDATA,
- MAT_SXP_SHIN_MASKDATA,
- MAT_SXP_SELFI_MASKDATA,
- MAT_SXP_REFL_MASKDATA,
- PROC_DATA:
- FreeMem(Chunk^.Data.IpasData^.Data);
- POINT_ARRAY:
- FreeMem(Chunk^.Data.PointArray^.PointList);
- POINT_FLAG_ARRAY:
- FreeMem(Chunk^.Data.PointFlagArray^.FlagList);
- FACE_ARRAY:
- Freemem(Chunk^.Data.FaceArray^.FaceList);
- MSH_MAT_GROUP:
- begin
- Dispose(Chunk^.Data.MshMatGroup);
- Chunk^.Data.MshMatGroup := nil;
- end;
- SMOOTH_GROUP:
- FreeMem(Chunk^.Data.SmoothGroup^.GroupList);
- TEX_VERTS:
- FreeMem(Chunk^.Data.TexVerts^.TextVertList);
- XDATA_ENTRY:
- FreeMem(Chunk^.Data.XDataEntry^.Data);
- POS_TRACK_TAG:
- begin
- FreeMem(Chunk^.Data.PosTrackTag^.KeyHdrList);
- Freemem(Chunk^.Data.PosTrackTag^.PositionList);
- end;
- COL_TRACK_TAG:
- begin
- FreeMem(Chunk^.Data.ColTrackTag^.KeyHdrList);
- FreeMem(Chunk^.Data.ColTrackTag^.ColorList);
- end;
- ROT_TRACK_TAG:
- begin
- FreeMem(Chunk^.Data.RotTrackTag^.KeyHdrList);
- FreeMem(Chunk^.Data.RotTrackTag^.RotationList);
- end;
- SCL_TRACK_TAG:
- begin
- FreeMem(Chunk^.Data.ScaleTrackTag^.KeyHdrList);
- FreeMem(Chunk^.Data.ScaleTrackTag^.ScaleList);
- end;
- MORPH_TRACK_TAG:
- begin
- FreeMem(Chunk^.Data.MorphTrackTag^.KeyHdrList);
- FreeMem(Chunk^.Data.MorphTrackTag^.MorphList);
- end;
- FOV_TRACK_TAG:
- begin
- FreeMem(Chunk^.Data.FovTrackTag^.KeyHdrList);
- FreeMem(Chunk^.Data.FovTrackTag^.FOVAngleList);
- end;
- ROLL_TRACK_TAG:
- begin
- FreeMem(Chunk^.Data.RollTrackTag^.KeyHdrList);
- FreeMem(Chunk^.Data.RollTrackTag^.RollAngleList);
- end;
- HOT_TRACK_TAG:
- begin
- FreeMem(Chunk^.Data.HotTrackTag^.KeyHdrList);
- FreeMem(Chunk^.Data.HotTrackTag^.HotspotAngleList);
- end;
- FALL_TRACK_TAG:
- begin
- FreeMem(Chunk^.Data.FallTrackTag^.KeyHdrList);
- FreeMem(Chunk^.Data.FallTrackTag^.FalloffAngleList);
- end;
- KFHDR:
- begin
- Dispose(Chunk^.Data.KFHdr);
- Chunk^.Data.KFHdr := nil;
- end;
- NODE_HDR:
- begin
- Dispose(Chunk^.Data.NodeHdr);
- Chunk^.Data.NodeHdr := nil;
- end;
- HIDE_TRACK_TAG:
- FreeMem(Chunk^.Data.HideTrackTag^.KeyHdrList);
- end; // case end
- // finally free the data chunk
- FreeMem(Chunk^.Data.Dummy);
- Chunk^.Data.Dummy := nil;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure InitChunk(var Chunk: PChunk3DS);
- // initializes and allocates memory for a chunk
- begin
- New(Chunk);
- if Chunk = nil then
- ShowError(strError3DS_NO_MEM);
- // set default values
- with Chunk^ do
- begin
- Tag := NULL_CHUNK;
- Size := 0;
- Position := 0;
- Data.Dummy := nil;
- Sibling := nil;
- Children := nil;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure InitChunkList(var List: PChunklist3DS; Count: integer);
- begin
- if List = nil then
- begin
- List := AllocMem(SizeOf(TChunklist3DS));
- if List = nil then
- ShowError(strError3DS_NO_MEM);
- end;
- List^.Count := Count;
- if Count > 0 then
- begin
- List^.List := AllocMem(Count * SizeOf(TChunkListEntry3DS));
- if List^.List = nil then
- ShowError(strError3DS_NO_MEM);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function PutGenericNode(TagID: word; ParentChunk: PChunk3DS): PChunk3DS;
- // put a tag into database as a child of ParentChunk
- begin
- InitChunk(Result);
- Result^.Tag := TagID;
- AddChildOrdered(ParentChunk, Result);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure ReleaseChunk(var Chunk: PChunk3DS);
- var
- Sibling: PChunk3DS;
- begin
- // free memory associated with chunk and substructure
- while Assigned(Chunk) do
- begin
- Sibling := Chunk^.Sibling;
- ReleaseChunk(Chunk^.Children);
- FreeChunkData(Chunk);
- FreeMem(Chunk);
- Chunk := Sibling;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure ReleaseChunkList(var List: PChunkList3DS);
- var
- I: integer;
- begin
- if Assigned(List) then
- begin
- // tell the string management that we don't need these strings any longer
- for I := 0 to List^.Count - 1 do
- List^.List^[I].NameStr := '';
- if Assigned(List^.List) then
- FreeMem(List^.List);
- FreeMem(List);
- List := nil;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function CopyChunk(Chunk: PChunk3DS): PChunk3DS;
- // copies the structure of Chunk to Result, assigned data of Chunk will not be copied, but
- // moved to Result (actually references will be moved)
- var
- ChildIn: PChunk3DS;
- ChildOut: ^PChunk3DS;
- begin
- if Chunk = nil then
- ShowError(strERROR3DS_INVALID_ARG);
- InitChunk(Result);
- with Result^ do
- begin
- Tag := Chunk^.Tag;
- Size := Chunk^.Size;
- Position := Chunk^.Position;
- if Assigned(Chunk^.Data.Dummy) then
- begin
- Data.Dummy := Chunk^.Data.Dummy;
- Chunk^.Data.Dummy := nil;
- end;
- ChildIn := Chunk^.Children;
- ChildOut := @Children;
- while Assigned(ChildIn) do
- begin
- ChildOut^ := CopyChunk(ChildIn);
- ChildIn := ChildIn^.Sibling;
- ChildOut := @ChildOut^.Sibling;
- end;
- end;
- end;
- //----------------- list update routines ------------------------------------------------------------------------------
- procedure UpdateMatEntryList(const Source: TFile3DS; var DB: TDatabase3DS);
- var
- Parent, MatName, MatEntry: PChunk3DS;
- I, MatCount: integer;
- begin
- if DB.MatlistDirty then
- begin
- ReleaseChunkList(DB.MatList);
- Parent := FindChunk(DB.TopChunk, MDATA);
- if Parent = nil then
- Parent := FindChunk(DB.TopChunk, MLIBMAGIC);
- MatCount := 0;
- if Assigned(Parent) then
- begin
- MatEntry := FindChunk(Parent, MAT_ENTRY);
- while Assigned(MatEntry) do
- begin
- MatEntry := FindNextChunk(MatEntry^.Sibling, MAT_ENTRY);
- Inc(MatCount);
- end;
- end;
- InitChunkList(DB.MatList, MatCount);
- if Parent = nil then
- Exit;
- I := 0;
- MatEntry := FindChunk(Parent, MAT_ENTRY);
- while Assigned(MatEntry) do
- begin
- MatName := FindChunk(MatEntry, MAT_NAME);
- Source.ReadChunkData(MatName);
- DB.MatList^.List^[I].Chunk := MatEntry;
- DB.MatList^.List^[I].NameStr := string(MatName^.Data.MatName);
- MatEntry := FindNextChunk(MatEntry^.Sibling, MAT_ENTRY);
- Inc(I);
- end;
- DB.MatlistDirty := False;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure UpdateNamedObjectList(Source: TFile3DS; var DB: TDatabase3DS);
- var
- MDataChunk, Current: PChunk3DS;
- I: integer;
- begin
- if DB.ObjListDirty then
- begin
- ReleaseChunkList(DB.ObjList);
- MDataChunk := FindChunk(DB.TopChunk, MDATA);
- I := 0;
- if Assigned(MDataChunk) then
- begin
- Current := FindChunk(MDataChunk, NAMED_OBJECT);
- while Assigned(Current) do
- begin
- Inc(I);
- Current := FindNextChunk(Current^.Sibling, NAMED_OBJECT);
- end;
- end;
- InitChunkList(DB.ObjList, I);
- if MDataChunk = nil then
- Exit;
- I := 0;
- Current := FindChunk(MDataChunk, NAMED_OBJECT);
- while Assigned(Current) do
- begin
- Source.ReadChunkData(Current);
- DB.ObjList^.List^[I].Chunk := Current;
- DB.ObjList^.List^[I].NameStr := string(Current^.Data.NamedObject);
- Current := FindNextChunk(Current^.Sibling, NAMED_OBJECT);
- Inc(I);
- end;
- DB.ObjListDirty := False;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure UpdateNodeTagList(Source: TFile3DS; var DB: TDatabase3DS);
- var
- KFDataChunk, Chunk, Current: PChunk3DS;
- I: integer;
- begin
- if DB.NodeListDirty then
- begin
- ReleaseChunkList(DB.NodeList);
- KFDataChunk := FindChunk(DB.TopChunk, KFDATA);
- I := 0;
- // if there is a keyframe section then count the number of node tags
- if Assigned(KFDataChunk) then
- begin
- Current := KFDataChunk^.Children;
- while Assigned(Current) do
- begin
- case Current^.Tag of
- AMBIENT_NODE_TAG,
- OBJECT_NODE_TAG,
- CAMERA_NODE_TAG,
- TARGET_NODE_TAG,
- LIGHT_NODE_TAG,
- L_TARGET_NODE_TAG,
- SPOTLIGHT_NODE_TAG:
- Inc(I);
- end;
- Current := Current^.Sibling;
- end;
- end;
- InitChunkList(DB.NodeList, I);
- if I = 0 then
- Exit;
- I := 0;
- Current := KFDataChunk^.Children;
- while Assigned(Current) do
- begin
- case Current^.Tag of
- AMBIENT_NODE_TAG,
- OBJECT_NODE_TAG,
- CAMERA_NODE_TAG,
- TARGET_NODE_TAG,
- LIGHT_NODE_TAG,
- L_TARGET_NODE_TAG,
- SPOTLIGHT_NODE_TAG:
- begin
- Chunk := FindNextChunk(Current^.Children, NODE_HDR);
- if Assigned(Chunk) then
- begin
- Source.ReadChunkData(Chunk);
- DB.NodeList^.List^[I].Chunk := Current;
- DB.NodeList^.List^[I].NameStr := Chunk^.Data.NodeHdr^.ObjNameStr;
- FreeChunkData(Chunk);
- end;
- // Object tags may have an instance name as well, which gets appended to
- // the object name with a "." seperator
- if Current^.Tag = OBJECT_NODE_TAG then
- begin
- Chunk := FindNextChunk(Current^.Children, INSTANCE_NAME);
- if Assigned(Chunk) then
- begin
- Source.ReadChunkData(Chunk);
- DB.NodeList^.List^[I].NameStr :=
- DB.NodeList^.List^[I].NameStr + '.' + string(Chunk^.Data.InstanceName);
- FreeChunkData(Chunk);
- end;
- end;
- Inc(I); // Increment index counter
- end;
- end;
- Current := Current^.Sibling;
- end;
- DB.NodeListDirty := False;
- end;
- end;
- //----------------- other support function ----------------------------------------------------------------------------
- function GetGenericNodeCount(const Source: TFile3DS; var DB: TDatabase3DS;
- Tag: word): integer;
- var
- I: integer;
- begin
- UpdateNodeTagList(Source, DB);
- Result := 0;
- for I := 0 to DB.NodeList^.Count - 1 do
- if DB.NodeList^.List^[I].Chunk^.Tag = Tag then
- Inc(Result);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure GetGenericNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
- TagID: word; List: TStringList);
- var
- I: cardinal;
- begin
- UpdateNodeTagList(Source, DB);
- List.Clear;
- for I := 0 to DB.NodeList^.Count - 1 do
- if DB.NodeList^.List^[I].Chunk^.Tag = TagID then
- List.Add(DB.NodeList^.List^[I].NameStr);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function FindNamedAndTaggedChunk(const Source: TFile3DS; var DB: TDatabase3DS;
- const Name: string; TagID: word): PChunk3DS;
- // Look through the keyframer stuff and find named chunk of the tag type TagID.
- // Has to be a chunk that has a node header: CAMERA_NODE, LIGHT_NODE, , .
- var
- KfChunk, NodeHdrChunk: PChunk3DS;
- begin
- // find Keyframe Chunk
- KfChunk := FindChunk(DB.TopChunk, KFDATA);
- // look for the target tag
- Result := FindChunk(KfChunk, TagID);
- while Assigned(Result) do
- begin
- NodeHdrChunk := FindNextChunk(Result^.Children, NODE_HDR);
- if Assigned(NodeHdrChunk) then
- begin
- Source.ReadChunkData(NodeHdrChunk);
- // match name, set pointer (case sensitive comparation!)
- if CompareStr(Name, NodeHdrChunk^.Data.NodeHdr^.ObjNameStr) = 0 then
- begin
- FreeChunkData(NodeHdrChunk);
- Break;
- end;
- FreeChunkData(NodeHdrChunk);
- end;
- Result := FindNextChunk(Result^.Sibling, TagID);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function FindNodeTagByIndexAndType(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: cardinal; AType: word): PChunk3DS;
- var
- I, Count: cardinal;
- begin
- Result := nil;
- Count := 0;
- UpdateNodeTagList(Source, DB);
- for I := 0 to DB.NodeList^.Count - 1 do
- if DB.NodeList^.List^[I].Chunk^.Tag = AType then
- begin
- if Count = Index then
- begin
- Result := DB.NodeList^.List^[I].Chunk;
- Break;
- end;
- Inc(Count);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function FindNodeTagByNameAndType(const Source: TFile3DS; DB: TDatabase3DS;
- const Name: string; AType: word): PChunk3DS;
- var
- I: integer;
- begin
- Result := nil;
- UpdateNodeTagList(Source, DB);
- for I := 0 to DB.NodeList^.Count - 1 do
- if (DB.NodeList^.List^[I].Chunk^.Tag = AType) and
- (CompareStr(Name, DB.NodeList^.List^[I].NameStr) = 0) then
- begin
- Result := DB.NodeList^.List^[I].Chunk;
- Exit;
- end;
- end;
- //----------------- material handling ---------------------------------------------------------------------------------
- function GetMaterialCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- begin
- UpdateMatEntryList(Source, DB);
- if DB.MatList = nil then
- Result := 0
- else
- Result := DB.MatList^.Count;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function FindMatEntryByIndex(Source: TFile3DS; DB: TDatabase3DS;
- Index: integer): PChunk3DS;
- begin
- if DB.TopChunk = nil then
- ShowError(strError3DS_INVALID_DATABASE);
- if (DB.TopChunk^.Tag <> MLIBMAGIC) and (DB.TopChunk^.Tag <> M3DMAGIC) and
- (DB.TopChunk^.Tag <> CMAGIC) then
- ShowError(strError3DS_WRONG_DATABASE);
- UpdateMatEntryList(Source, DB);
- if Index < DB.MatList^.Count then
- Result := DB.MatList^.List^[Index].Chunk
- else
- Result := nil;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure InitBitmap(var Map: TBitmap3DS);
- begin
- FillChar(Map, SizeOf(Map), 0);
- with Map do
- begin
- UScale := 1;
- VScale := 1;
- Tint2.R := 1;
- Tint2.G := 1;
- Tint2.B := 1;
- RedTint.R := 1;
- GreenTint.G := 1;
- BlueTint.B := 1;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure InitMaterial(var Mat: TMaterial3DS);
- begin
- FillChar(Mat, SizeOf(Mat), 0);
- with Mat do
- begin
- WireSize := 1;
- Shading := stPhong;
- Reflect.AutoMap.Size := 100;
- Reflect.AutoMap.nthFrame := 1;
- InitBitmap(Texture.Map);
- InitBitmap(Texture.Mask);
- InitBitmap(Texture2.Map);
- InitBitmap(Texture2.Mask);
- InitBitmap(Opacity.Map);
- InitBitmap(Opacity.Mask);
- InitBitmap(Reflect.Map);
- InitBitmap(Reflect.Mask);
- InitBitmap(Bump.Map);
- InitBitmap(Bump.Mask);
- InitBitmap(SpecMap.Map);
- InitBitmap(SpecMap.Mask);
- InitBitmap(ShinMap.Map);
- InitBitmap(ShinMap.Mask);
- InitBitmap(IllumMap.Map);
- InitBitmap(IllumMap.Mask);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure ReleaseMaterial(Mat: PMaterial3DS);
- begin
- if Assigned(Mat) then
- begin
- FreeMem(Mat^.Texture.Map.Data);
- FreeMem(Mat^.Texture.Mask.Data);
- FreeMem(Mat^.Texture2.Map.Data);
- FreeMem(Mat^.Texture2.Mask.Data);
- FreeMem(Mat^.Opacity.Map.Data);
- FreeMem(Mat^.Opacity.Mask.Data);
- FreeMem(Mat^.Reflect.Mask.Data);
- FreeMem(Mat^.Bump.Map.Data);
- FreeMem(Mat^.Bump.Mask.Data);
- FreeMem(Mat^.Specmap.Map.Data);
- FreeMem(Mat^.SpecMap.Mask.Data);
- FreeMem(Mat^.ShinMap.Map.Data);
- FreeMem(Mat^.ShinMap.Mask.Data);
- FreeMem(Mat^.IllumMap.Map.Data);
- FreeMem(Mat^.IllumMap.Mask.Data);
- Dispose(Mat);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function FindNamedObjectByIndex(Source: TFile3DS; DB: TDatabase3DS;
- AType: word; Index: integer): PChunk3DS;
- // searches the database for a named object by index position and object type
- // returns the NAMED_OBJECT chunk if found, nil otherwise
- var
- Chunk: PChunk3DS;
- I, Count: integer;
- begin
- UpdateNamedObjectList(Source, DB);
- Count := 0;
- Result := nil;
- for I := 0 to DB.ObjList^.Count - 1 do
- begin
- if AType = DL_SPOTLIGHT then
- begin
- Chunk := FindChunk(DB.ObjList^.List^[I].Chunk, N_DIRECT_LIGHT);
- if Assigned(Chunk) then
- Chunk := FindChunk(Chunk, AType);
- end
- else
- Chunk := FindChunk(DB.ObjList^.List^[I].Chunk, AType);
- if Assigned(Chunk) then
- begin
- if Count = Index then
- begin
- Result := DB.ObjList^.List^[I].Chunk;
- Break;
- end
- else
- Inc(Count);
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure DeleteChunk(var Chunk: PChunk3DS);
- // returns a chunk to its untagged state state, but leaves it
- // connected to any siblings it might have
- begin
- if Assigned(Chunk) then
- begin
- // release any children
- if Assigned(Chunk^.Children) then
- ReleaseChunk(Chunk^.Children);
- // release any data
- if Assigned(Chunk^.Data.Dummy) then
- FreeChunkData(Chunk);
- // return to a semi-uninitialized state
- Chunk^.Tag := NULL_CHUNK;
- Chunk^.Size := 0;
- Chunk^.Position := 0;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function ReadPercentageChunk(Source: TFile3DS; Chunk: PChunk3DS): single;
- var
- DataChunk: PChunk3DS;
- begin
- DataChunk := FindChunk(Chunk, INT_PERCENTAGE);
- if Assigned(DataChunk) then
- begin
- Source.ReadChunkData(DataChunk);
- Result := DataChunk^.Data.IntPercentage^ / 100;
- FreeChunkData(DataChunk);
- end
- else
- begin
- DataChunk := FindChunk(Chunk, FLOAT_PERCENTAGE);
- if Assigned(DataChunk) then
- begin
- Source.ReadChunkData(DataChunk);
- Result := DataChunk^.Data.FloatPercentage^;
- FreeChunkData(DataChunk);
- end
- else
- Result := 0;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure GetBitmapChunk(const DataSource: TFile3DS; Chunk: PChunk3DS;
- var Bitmap: TBitmap3DS);
- var
- Current: PChunk3DS;
- begin
- Current := Chunk^.Children;
- while Assigned(Current) do
- begin
- with Bitmap do
- begin
- case Current^.Tag of
- INT_PERCENTAGE:
- begin
- DataSource.ReadChunkData(Current);
- Percent := Current^.Data.IntPercentage^ / 100;
- FreeChunkData(Current);
- end;
- FLOAT_PERCENTAGE:
- begin
- DataSource.ReadChunkData(Current);
- Percent := Current^.Data.FloatPercentage^;
- FreeChunkData(Current);
- end;
- MAT_MAPNAME:
- begin
- DataSource.ReadChunkData(Current);
- NameStr := StrPas(Current^.Data.MatMapname);
- FreeChunkData(Current);
- end;
- MAT_MAP_TILING:
- begin
- DataSource.ReadChunkData(Current);
- if (Current^.Data.MatMapTiling^ and TEX_DECAL) <> 0 then
- if (Current^.Data.MatMapTiling^ and TEX_NOWRAP) <> 0 then
- Tiling := ttDecal
- else
- Tiling := ttBoth
- else
- tiling := ttTile;
- IgnoreAlpha := (Current^.Data.MatMapTiling^ and TEX_DONT_USE_ALPHA) <> 0;
- if (Current^.Data.MatMapTiling^ and TEX_SAT) <> 0 then
- Filter := ftSummedArea
- else
- Filter := ftPyramidal;
- Mirror := (Current^.Data.MatMapTiling^ and TEX_MIRROR) <> 0;
- Negative := (Current^.Data.MatMapTiling^ and TEX_INVERT) <> 0;
- if (Current^.Data.MatMapTiling^ and TEX_TINT) <> 0 then
- if (Current^.Data.MatMapTiling^ and TEX_ALPHA_SOURCE) <> 0 then
- Source := ttAlphaTint
- else
- Source := ttRGBLumaTint
- else if (Current^.Data.MatMapTiling^ and TEX_RGB_TINT) <> 0 then
- Source := ttRGBTint
- else if (Current^.Data.MatMapTiling^ and TEX_ALPHA_SOURCE) <> 0 then
- Source := ttAlpha
- else
- Source := ttRGB;
- FreeChunkData(Current);
- end;
- MAT_MAP_USCALE:
- begin
- DataSource.ReadChunkData(Current);
- UScale := Current^.Data.MatMapUScale^;
- FreeChunkData(Current);
- end;
- MAT_MAP_VSCALE:
- begin
- DataSource.ReadChunkData(Current);
- VScale := Current^.Data.MatMapVScale^;
- FreeChunkData(Current);
- end;
- MAT_MAP_UOFFSET:
- begin
- DataSource.ReadChunkData(Current);
- UOffset := Current^.Data.MatMapUOffset^;
- FreeChunkData(Current);
- end;
- MAT_MAP_VOFFSET:
- begin
- DataSource.ReadChunkData(Current);
- VOffset := Current^.Data.MatMapVOffset^;
- FreeChunkData(Current);
- end;
- MAT_MAP_ANG:
- begin
- DataSource.ReadChunkData(Current);
- Rotation := Current^.Data.MatMapAng^;
- FreeChunkData(Current);
- end;
- MAT_BUMP_PERCENT:
- ; // value is really stored in TMaterial3DS structure
- MAT_MAP_COL1:
- begin
- DataSource.ReadChunkData(Current);
- Tint1.R := Current^.Data.MatMapCol1^.Red / 255;
- Tint1.G := Current^.Data.MatMapCol1^.Green / 255;
- Tint1.B := Current^.Data.MatMapCol1^.Blue / 255;
- FreeChunkData(Current);
- end;
- MAT_MAP_COL2:
- begin
- DataSource.ReadChunkData(Current);
- Tint2.R := Current^.Data.MatMapCol2^.Red / 255;
- Tint2.G := Current^.Data.MatMapCol2^.Green / 255;
- Tint2.B := Current^.Data.MatMapCol2^.Blue / 255;
- FreeChunkData(Current);
- end;
- MAT_MAP_RCOL:
- begin
- DataSource.ReadChunkData(Current);
- RedTint.R := Current^.Data.MatMapRCol^.Red / 255;
- RedTint.G := Current^.Data.MatMapRCol^.Green / 255;
- RedTint.B := Current^.Data.MatMapRCol^.Blue / 255;
- FreeChunkData(Current);
- end;
- MAT_MAP_GCOL:
- begin
- DataSource.ReadChunkData(Current);
- GreenTint.R := Current^.Data.MatMapGCol^.Red / 255;
- GreenTint.G := Current^.Data.MatMapGCol^.Green / 255;
- GreenTint.B := Current^.Data.MatMapGCol^.Blue / 255;
- FreeChunkData(Current);
- end;
- MAT_MAP_BCOL:
- begin
- DataSource.ReadChunkData(Current);
- BlueTint.R := Current^.Data.MatMapBCol^.Red / 255;
- BlueTint.G := Current^.Data.MatMapBCol^.Green / 255;
- BlueTint.B := Current^.Data.MatMapBCol^.Blue / 255;
- FreeChunkData(Current);
- end;
- MAT_MAP_TEXBLUR:
- begin
- DataSource.ReadChunkData(Current);
- Blur := Current^.Data.MatMapTexBlur^; // float percents
- FreeChunkData(Current);
- end;
- end; // case Current^.Tag of
- Current := Current^.Sibling;
- end; // with Bitmap do
- end; // while Assigned(Current) do
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function ReadMatEntryChunk(Source: TFile3DS; MatEntry: PChunk3DS): TMaterial3DS;
- var
- Current, DataChunk, Color: PChunk3DS;
- MatColor: PFColor3DS;
- begin
- if MatEntry^.Tag <> MAT_ENTRY then
- ShowError(strError3DS_INVALID_CHUNK);
- InitMaterial(Result);
- with Result do
- begin
- Current := MatEntry^.Children;
- while Assigned(Current) do
- begin
- if (Current^.Tag and $FF00) <> $8000 then // ignore xdata
- case Current^.Tag of
- MAT_NAME:
- begin
- Source.ReadChunkData(Current);
- NameStr := StrPas(Current^.Data.MatName);
- FreeChunkData(Current);
- end;
- MAT_AMBIENT,
- MAT_DIFFUSE,
- MAT_SPECULAR:
- begin
- case Current^.Tag of
- MAT_DIFFUSE:
- MatColor := @Diffuse;
- MAT_SPECULAR:
- MatColor := @Specular;
- else
- MatColor := @Ambient; // MAT_AMBIENT
- end;
- Color := FindChunk(Current, COLOR_24);
- if Assigned(color) then
- begin
- Source.ReadChunkData(Color);
- MatColor^.R := Color^.Data.Color24^.Red / 255;
- MatColor^.G := Color^.Data.Color24^.Green / 255;
- MatColor^.B := Color^.Data.Color24^.Blue / 255;
- FreeChunkData(Color);
- end;
- Color := FindChunk(Current, COLOR_F);
- if Assigned(Color) then
- begin
- Source.ReadChunkData(Color);
- MatColor^.R := Color^.Data.ColorF^.Red;
- MatColor^.G := Color^.Data.ColorF^.Green;
- MatColor^.B := Color^.Data.ColorF^.Blue;
- FreeChunkData(Color);
- end;
- Color := FindChunk(Current, LIN_COLOR_24);
- if Assigned(Color) then
- begin
- Source.ReadChunkData(Color);
- MatColor^.R := Color^.Data.LinColor24^.Red / 255;
- MatColor^.G := Color^.Data.LinColor24^.Green / 255;
- MatColor^.B := Color^.Data.LinColor24^.Blue / 255;
- FreeChunkData(Color);
- end;
- end;
- MAT_SHININESS:
- Shininess := ReadPercentageChunk(Source, Current);
- MAT_SHIN2PCT:
- ShinStrength := ReadPercentageChunk(Source, Current);
- MAT_SHIN3PCT:
- ; // just skip for now
- MAT_REFBLUR:
- Blur := ReadPercentageChunk(Source, Current);
- MAT_TRANSPARENCY:
- Transparency := ReadPercentageChunk(Source, Current);
- MAT_XPFALL:
- TransFalloff := ReadPercentageChunk(Source, Current);
- MAT_SELF_ILPCT:
- SelfIllumPct := ReadPercentageChunk(Source, Current);
- MAT_WIRE:
- Shading := stWire;
- MAT_WIREABS:
- UseWireAbs := True;
- MAT_XPFALLIN:
- Transparency := -Transparency;
- MAT_WIRESIZE:
- begin
- Source.ReadChunkData(Current);
- WireSize := Current^.Data.MatWireSize^;
- FreeChunkData(Current);
- end;
- MAT_USE_XPFALL:
- UseFall := True;
- MAT_USE_REFBLUR:
- Useblur := True;
- MAT_SELF_ILLUM:
- SelfIllum := True;
- MAT_TWO_SIDE:
- TwoSided := True;
- MAT_ADDITIVE:
- Additive := True;
- MAT_SHADING:
- begin
- Source.ReadChunkData(Current);
- Shading := TShadeType3DS(Current^.Data.MatShading^);
- FreeChunkData(Current);
- end;
- MAT_FACEMAP:
- FaceMap := True;
- MAT_PHONGSOFT:
- Soften := True;
- MAT_TEXMAP:
- GetBitmapChunk(Source, Current, Texture.Map);
- MAT_TEXMASK:
- GetBitmapChunk(Source, Current, Texture.Mask);
- MAT_TEX2MAP:
- GetBitmapChunk(Source, Current, Texture2.Map);
- MAT_TEX2MASK:
- GetBitmapChunk(Source, Current, Texture2.Mask);
- MAT_OPACMAP:
- GetBitmapChunk(Source, Current, Opacity.Map);
- MAT_OPACMASK:
- GetBitmapChunk(Source, Current, Opacity.Mask);
- MAT_REFLMAP:
- GetBitmapChunk(Source, Current, Reflect.Map);
- MAT_ACUBIC:
- begin
- Source.ReadChunkData(Current);
- Reflect.UseAuto := True;
- Reflect.AutoMap.FirstFrame :=
- (Current^.Data.MatAcubic^.Flags and ACubicFirst3DS) <> 0;
- Reflect.AutoMap.Flat :=
- (Current^.Data.MatAcubic^.Flags and ACubicFlat3DS) <> 0;
- Reflect.AutoMap.Size := Current^.Data.MatAcubic^.MapSize;
- Reflect.AutoMap.nthFrame := Current^.Data.MatAcubic^.FrameInterval;
- FreeChunkData(Current);
- end;
- MAT_REFLMASK:
- GetBitmapChunk(Source, Current, Reflect.Mask);
- MAT_BUMPMAP:
- begin
- GetBitmapChunk(Source, Current, Bump.Map);
- DataChunk := FindChunk(Current, MAT_BUMP_PERCENT);
- if Assigned(DataChunk) then
- begin
- Source.ReadChunkData(DataChunk);
- Bump.Map.Percent := DataChunk^.Data.MatBumpPercent^ / 100;
- FreeChunkData(DataChunk);
- end;
- end;
- MAT_BUMPMASK:
- GetBitmapChunk(Source, Current, Bump.Mask);
- MAT_SPECMAP:
- GetBitmapChunk(Source, Current, SpecMap.Map);
- MAT_SPECMASK:
- GetBitmapChunk(Source, Current, SpecMap.Mask);
- MAT_SHINMAP:
- GetBitmapChunk(Source, Current, ShinMap.Map);
- MAT_SHINMASK:
- GetBitmapChunk(Source, Current, Shinmap.Mask);
- MAT_SELFIMAP:
- GetBitmapChunk(Source, Current, IllumMap.Map);
- MAT_SELFIMASK:
- GetBitmapChunk(Source, Current, IllumMap.Mask);
- MAT_SXP_TEXT_DATA:
- begin
- Source.ReadChunkData(Current);
- Texture.Map.DataSize := Current^.Data.IpasData^.Size;
- Texture.Map.Data := Current^.Data.IpasData^.Data;
- // avoid releasing the data memory
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_TEXT_MASKDATA:
- begin
- Source.ReadChunkData(Current);
- Texture.Mask.DataSize := Current^.Data.IpasData^.Size;
- Texture.Mask.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_TEXT2_DATA:
- begin
- Source.ReadChunkData(Current);
- Texture2.Map.DataSize := Current^.Data.IpasData^.Size;
- Texture2.Map.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_TEXT2_MASKDATA:
- begin
- Source.ReadChunkData(Current);
- Texture2.Mask.DataSize := Current^.Data.IpasData^.Size;
- Texture2.Mask.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_OPAC_DATA:
- begin
- Source.ReadChunkData(Current);
- Opacity.Map.DataSize := Current^.Data.IpasData^.Size;
- Opacity.Map.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_OPAC_MASKDATA:
- begin
- Source.ReadChunkData(Current);
- Opacity.Mask.DataSize := Current^.Data.IpasData^.Size;
- Opacity.Mask.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_REFL_MASKDATA:
- begin
- Source.ReadChunkData(Current);
- Reflect.Mask.DataSize := Current^.Data.IpasData^.Size;
- Reflect.Mask.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_BUMP_DATA:
- begin
- Source.ReadChunkData(Current);
- Bump.Map.DataSize := Current^.Data.IpasData^.Size;
- Bump.Map.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_BUMP_MASKDATA:
- begin
- Source.ReadChunkData(Current);
- Bump.Mask.DataSize := Current^.Data.IpasData^.Size;
- Bump.Mask.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_SPEC_DATA:
- begin
- Source.ReadChunkData(Current);
- SpecMap.Map.DataSize := Current^.Data.IpasData^.Size;
- SpecMap.Map.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_SPEC_MASKDATA:
- begin
- Source.ReadChunkData(Current);
- Specmap.Mask.DataSize := Current^.Data.IpasData^.Size;
- Specmap.Mask.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_SHIN_DATA:
- begin
- Source.ReadChunkData(Current);
- ShinMap.Map.DataSize := Current^.Data.IpasData^.Size;
- ShinMap.Map.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_SHIN_MASKDATA:
- begin
- Source.ReadChunkData(Current);
- ShinMap.Mask.DataSize := Current^.Data.IpasData^.Size;
- ShinMap.Mask.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_SELFI_DATA:
- begin
- Source.ReadChunkData(Current);
- IllumMap.Map.DataSize := Current^.Data.IpasData^.Size;
- IllumMap.Map.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_SXP_SELFI_MASKDATA:
- begin
- Source.ReadChunkData(Current);
- IllumMap.Mask.DataSize := Current^.Data.IpasData^.Size;
- IllumMap.Mask.Data := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MAT_DECAL:
- ; // don't know what do to with it
- else
- ShowError(strError3DS_INVALID_CHUNK)
- end;
- Current := Current^.Sibling;
- end; // while Assigned(Current) do
- end; // with Result do
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetChunkValue(Tag: word): integer;
- // Computes a chunk weighting used to determine proper chunk order,
- // higher values appear earlier in the parent than lower values
- begin
- // only chunks where an explicit order matters are handled
- Result := 0;
- case Tag of
- NULL_CHUNK:
- Inc(Result); // These should just be ignored
- SMAGIC:
- Inc(Result, 2);
- LMAGIC:
- Inc(Result, 3);
- M3DMAGIC:
- Inc(Result, 4);
- M3D_VERSION:
- Inc(Result, 5);
- MDATA:
- Inc(Result, 6);
- KFDATA:
- Inc(Result, 7);
- COLOR_24:
- Inc(Result, 8);
- LIN_COLOR_24:
- Inc(Result, 9);
- MESH_VERSION:
- Inc(Result, 10);
- MAT_ENTRY:
- Inc(Result, 11);
- KFHDR:
- Inc(Result, 12);
- MASTER_SCALE:
- Inc(Result, 13);
- VIEWPORT_LAYOUT:
- Inc(Result, 14);
- LO_SHADOW_BIAS:
- Inc(Result, 15);
- SHADOW_MAP_SIZE:
- Inc(Result, 16);
- SHADOW_FILTER:
- Inc(Result, 17);
- RAY_BIAS:
- Inc(Result, 18);
- O_CONSTS:
- Inc(Result, 19);
- AMBIENT_LIGHT:
- Inc(Result, 20);
- SOLID_BGND:
- Inc(Result, 21);
- BIT_MAP:
- Inc(Result, 22);
- V_GRADIENT:
- Inc(Result, 23);
- USE_BIT_MAP:
- Inc(Result, 24);
- USE_SOLID_BGND:
- Inc(Result, 25);
- USE_V_GRADIENT:
- Inc(Result, 26);
- FOG:
- Inc(Result, 27);
- LAYER_FOG:
- Inc(Result, 28);
- DISTANCE_CUE:
- Inc(Result, 29);
- DEFAULT_VIEW:
- Inc(Result, 30);
- NAMED_OBJECT:
- Inc(Result, 31);
- KFSEG:
- Inc(Result, 32);
- KFCURTIME:
- Inc(Result, 33);
- TARGET_NODE_TAG,
- L_TARGET_NODE_TAG,
- OBJECT_NODE_TAG,
- CAMERA_NODE_TAG,
- SPOTLIGHT_NODE_TAG:
- Inc(Result, 34);
- AMBIENT_NODE_TAG:
- Inc(Result, 35);
- N_TRI_OBJECT,
- N_CAMERA,
- N_DIRECT_LIGHT:
- Inc(Result);
- OBJ_HIDDEN:
- Inc(Result);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetMaterialByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: integer): TMaterial3DS;
- var
- Chunk: PChunk3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- Chunk := FindMatEntryByIndex(Source, DB, Index);
- if Assigned(Chunk) then
- Result := ReadMatEntryChunk(Source, Chunk)
- else
- ShowErrorFormatted(strError3DS_INVALID_INDEX, [Index]);
- end;
- //----------------- mesh object handling ------------------------------------------------------------------------------
- function GetMeshCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- // returns the number of mesh objects referenced in the chunk list
- var
- I: integer;
- Chunk: PChunk3DS;
- begin
- // update the index to named objects if the list has changed recently
- UpdateNamedObjectList(Source, DB);
- Result := 0;
- if DB.ObjList = nil then
- Exit;
- // scan through the list of named objects
- for I := 0 to DB.ObjList^.Count - 1 do
- begin
- Chunk := FindChunk(DB.ObjList^.List^[I].Chunk, N_TRI_OBJECT);
- if Assigned(Chunk) then
- Inc(Result);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetMeshMatCount(Current: PChunk3DS): integer;
- // aids the GetMeshEntryChunk3DS in determining
- // how many materials are defined within the mesh object
- var
- Chunk: PChunk3DS;
- begin
- Result := 0;
- Chunk := FindChunk(Current, MSH_MAT_GROUP);
- while Assigned(Chunk) do
- begin
- Chunk := FindNextChunk(Chunk^.Sibling, MSH_MAT_GROUP);
- Inc(Result);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure RelMeshObjField(var Mesh: TMesh3DS; Field: integer);
- var
- I: integer;
- begin
- if ((Field and RelVertexArray3DS) <> 0) and Assigned(Mesh.VertexArray) then
- begin
- FreeMem(Mesh.VertexArray);
- Mesh.VertexArray := nil;
- end;
- if ((Field and RelTextArray3DS) <> 0) and Assigned(Mesh.TextArray) then
- begin
- FreeMem(Mesh.TextArray);
- Mesh.TextArray := nil;
- end;
- if ((Field and RelFaceArray3DS) <> 0) and Assigned(Mesh.FaceArray) then
- begin
- FreeMem(Mesh.FaceArray);
- Mesh.FaceArray := nil;
- end;
- if ((Field and RelMatArray3DS) <> 0) and Assigned(Mesh.MatArray) then
- begin
- for I := 0 to Mesh.NMats - 1 do
- begin
- // name is always assigned
- Mesh.MatArray^[I].NameStr := '';
- if Assigned(Mesh.MatArray^[I].FaceIndex) then
- begin
- FreeMem(Mesh.MatArray^[I].FaceIndex);
- Mesh.MatArray^[I].FaceIndex := nil;
- end;
- end;
- FreeMem(Mesh.MatArray);
- Mesh.MatArray := nil;
- end;
- if ((Field and RelSmoothArray3DS) <> 0) and Assigned(Mesh.SmoothArray) then
- begin
- FreeMem(Mesh.SmoothArray);
- Mesh.SmoothArray := nil;
- end;
- if ((Field and RelProcData3DS) <> 0) and Assigned(Mesh.ProcData) then
- begin
- FreeMem(Mesh.ProcData);
- Mesh.ProcData := nil;
- end;
- if ((Field and RelVFlagArray3DS) <> 0) and Assigned(Mesh.VFlagArray) then
- begin
- FreeMem(Mesh.VFlagArray);
- Mesh.VFlagArray := nil;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure InitMeshObjField(var aMesh: TMesh3DS; Field: integer);
- var
- I: integer;
- begin
- with aMesh do
- begin
- // test to see if Vertices are being allocated
- if (Field and InitVertexArray3DS) <> 0 then
- begin
- // if the vertex count is 0 then free the array
- if NVertices = 0 then
- RelMeshObjField(aMesh, RelVertexArray3DS)
- else
- begin
- // if this is the very first allocation
- if VertexArray = nil then
- begin
- // allocate the new block of memory
- VertexArray := AllocMem(NVertices * SizeOf(TPoint3DS));
- if VertexArray = nil then
- ShowError(strError3DS_NO_MEM);
- // this is done by AllocMem already
- // initialize the new block
- //for I := 0 to NVertices - 1 do VertexArray[I] := DefPoint3DS;
- end
- else // else this is an existing block
- begin
- // just resize it
- ReallocMem(VertexArray, SizeOf(TPoint3DS) * NVertices);
- if VertexArray = nil then
- ShowError(strError3DS_NO_MEM);
- end;
- end;
- end;
- if (Field and InitTextArray3DS) <> 0 then
- begin
- if NTextVerts = 0 then
- RelMeshObjField(aMesh, RelTextArray3DS)
- else
- begin
- if TextArray = nil then
- begin
- TextArray := Allocmem(NTextVerts * SizeOf(TTexVert3DS));
- if TextArray = nil then
- ShowError(strError3DS_NO_MEM);
- for I := 0 to NTextVerts - 1 do
- TextArray^[I] := DefTextVert3DS;
- end
- else
- begin
- Reallocmem(TextArray, SizeOf(TTexVert3DS) * NTextVerts);
- if TextArray = nil then
- ShowError(strError3DS_NO_MEM);
- end;
- end;
- end;
- if (Field and InitFaceArray3DS) <> 0 then
- begin
- if NFaces = 0 then
- RelMeshObjField(aMesh, RelFaceArray3DS)
- else
- begin
- if FaceArray = nil then
- begin
- FaceArray := AllocMem(NFaces * SizeOf(TFace3DS));
- if FaceArray = nil then
- ShowError(strError3DS_NO_MEM);
- for I := 0 to NFaces - 1 do
- FaceArray^[I] := DefFace3DS;
- end
- else
- begin
- ReallocMem(FaceArray, SizeOf(TFace3DS) * NFaces);
- if FaceArray = nil then
- ShowError(strError3DS_NO_MEM);
- end;
- end;
- end;
- if (Field and InitMatArray3DS) <> 0 then
- begin
- if NMats = 0 then
- RelMeshObjField(aMesh, RelMatArray3DS)
- else
- begin
- if Matarray = nil then
- begin
- MatArray := AllocMem(NMats * SizeOf(TObjmat3DS));
- if MatArray = nil then
- ShowError(strError3DS_NO_MEM);
- for I := 0 to NMats - 1 do
- MatArray^[I] := DefObjMat3DS;
- end
- else
- begin
- ReallocMem(MatArray, SizeOf(TObjmat3DS) * NMats);
- if MatArray = nil then
- ShowError(strError3DS_NO_MEM);
- end;
- end;
- end;
- if (Field and InitSmoothArray3DS) <> 0 then
- begin
- if NFaces = 0 then
- RelMeshObjField(aMesh, RelSmoothArray3DS)
- else
- begin
- if SmoothArray = nil then
- begin
- SmoothArray := AllocMem(NFaces * SizeOf(integer));
- if SmoothArray = nil then
- ShowError(strError3DS_NO_MEM);
- // done by AllocMem
- // for I := 0 to NFaces - 1 do SmoothArray[I] := 0;
- end
- else
- begin
- ReallocMem(SmoothArray, SizeOf(integer) * NFaces);
- if SmoothArray = nil then
- ShowError(strError3DS_NO_MEM);
- end;
- end;
- end;
- if (Field and InitProcData3DS) <> 0 then
- begin
- if ProcSize = 0 then
- RelMeshObjField(aMesh, RelProcData3DS)
- else
- begin
- if ProcData = nil then
- begin
- ProcData := AllocMem(ProcSize * SizeOf(byte));
- if ProcData = nil then
- ShowError(strError3DS_NO_MEM);
- end
- else
- begin
- ReallocMem(ProcData, SizeOf(byte) * ProcSize);
- if ProcData = nil then
- ShowError(strError3DS_NO_MEM);
- end;
- end;
- end;
- if (Field and InitVFlagArray3DS) <> 0 then
- begin
- if NVertices = 0 then
- RelMeshObjField(aMesh, RelVFlagArray3DS)
- else
- begin
- if VFlagArray = nil then
- begin
- VFlagArray := AllocMem(NVertices * SizeOf(word));
- if VFlagArray = nil then
- ShowError(strError3DS_NO_MEM);
- end
- else
- begin
- ReallocMem(VFlagArray, SizeOf(word) * NVertices);
- if VFlagArray = nil then
- ShowError(strError3DS_NO_MEM);
- end;
- end;
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function InitMeshObj(VertexCount, FaceCount, InitFlags: word): TMesh3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- with Result do
- begin
- NVertices := VertexCount;
- Map.TileX := 1;
- Map.TileY := 1;
- Map.Scale := 1;
- Map.Matrix[0] := 1;
- Map.Matrix[4] := 1;
- Map.PW := 1;
- Map.PH := 1;
- Map.CH := 1;
- NFaces := FaceCount;
- InitMeshObjField(Result, InitVertexArray3DS or InitFaceArray3DS);
- if (InitFlags and InitTextArray3DS) <> 0 then
- begin
- NTextVerts := VertexCount;
- InitMeshObjField(Result, InitTextArray3DS);
- end;
- if (InitFlags and InitVFlagArray3DS) <> 0 then
- begin
- NVFlags := VertexCount;
- InitMeshObjField(Result, InitVFlagArray3DS);
- end;
- if (InitFlags and InitSmoothArray3DS) <> 0 then
- InitMeshObjField(Result, InitSmoothArray3DS);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure ReleaseMeshObj(Mesh: PMesh3DS);
- begin
- if Assigned(Mesh) then
- begin
- RelMeshObjField(Mesh^, RelAll3DS);
- Dispose(Mesh);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetMeshEntryChunk(const Source: TFile3DS; Chunk: PChunk3DS): TMesh3DS;
- var
- NTriChunk, FaceArrayChunk, DataChunk, Current: PChunk3DS;
- I: integer;
- begin
- NTriChunk := FindNextChunk(Chunk^.Children, N_TRI_OBJECT);
- if NTriChunk = nil then
- ShowError(strError3DS_WRONG_OBJECT);
- Result := InitMeshObj(0, 0, 0);
- with Result do
- begin
- // get the mesh name
- Source.ReadChunkData(Chunk);
- NameStr := StrPas(Chunk^.Data.NamedObject);
- Current := NTriChunk^.Children;
- while Assigned(Current) do
- begin
- case Current^.Tag of
- POINT_ARRAY:
- begin
- Source.ReadChunkData(Current);
- NVertices := Current^.Data.PointArray^.Vertices;
- VertexArray := Current^.Data.PointArray^.PointList;
- // avoid freeing the just allocated memory
- Current^.Data.PointArray^.PointList := nil;
- FreeChunkData(Current);
- end;
- POINT_FLAG_ARRAY:
- begin
- Source.ReadChunkData(Current);
- NVFlags := Current^.Data.PointFlagArray^.Flags;
- VFlagArray := Current^.Data.PointFlagArray^.FlagList;
- Current^.Data.PointFlagArray^.FlagList := nil;
- FreeChunkData(Current);
- end;
- FACE_ARRAY:
- begin
- Source.ReadChunkData(Current);
- NFaces := Current^.Data.FaceArray^.Faces;
- FaceArray := Current^.Data.FaceArray^.FaceList;
- Current^.Data.FaceArray^.FaceList := nil;
- if Assigned(Current^.Children) then
- begin
- // begin search for MESH_MAT_GROUP and SMOOTH_GROUP
- FaceArrayChunk := Current;
- // creates a list of all mesh mat groups
- DataChunk := FindChunk(FaceArrayChunk, MSH_MAT_GROUP);
- if Assigned(DataChunk) then
- begin
- NMats := GetMeshMatCount(DataChunk);
- MatArray := AllocMem(NMats * SizeOf(TObjMat3DS));
- for I := 0 to NMats - 1 do
- begin
- Source.ReadChunkData(DataChunk);
- MatArray^[I].NameStr := DataChunk^.Data.MshMatGroup^.MatNameStr;
- MatArray^[I].NFaces := DataChunk^.Data.MshMatGroup^.Faces;
- MatArray^[I].FaceIndex := DataChunk^.Data.MshMatGroup^.FaceList;
- DataChunk^.Data.MshMatGroup^.FaceList := nil;
- FreeChunkData(DataChunk);
- DataChunk := FindNextChunk(DataChunk^.Sibling, MSH_MAT_GROUP);
- end;
- end;
- DataChunk := FindNextChunk(FaceArrayChunk^.Children, SMOOTH_GROUP);
- if Assigned(DataChunk) then
- begin
- Source.ReadChunkData(DataChunk);
- SmoothArray := DataChunk^.Data.SmoothGroup^.GroupList;
- DataChunk^.Data.SmoothGroup^.GroupList := nil;
- FreeChunkData(DataChunk);
- end;
- DataChunk := FindNextChunk(FaceArrayChunk^.Children, MSH_BOXMAP);
- if Assigned(DataChunk) then
- begin
- Source.ReadChunkData(DataChunk);
- for I := 0 to 5 do
- BoxMapStr[I] := string(DataChunk^.Data.MshBoxmap^[I]);
- UseBoxmap := True;
- FreeChunkData(DataChunk);
- end;
- end;
- FreeChunkData(Current);
- end;
- TEX_VERTS:
- begin
- Source.ReadChunkData(Current);
- ntextverts := Current^.Data.TexVerts^.NumCoords;
- TextArray := Current^.Data.TexVerts^.TextVertList;
- Current^.Data.TexVerts^.TextVertList := nil;
- FreeChunkData(Current);
- end;
- MESH_MATRIX:
- begin
- Source.ReadChunkData(Current);
- LocMatrix := Current^.Data.MeshMatrix^;
- FreeChunkData(Current);
- end;
- MESH_TEXTURE_INFO:
- begin
- UseMapInfo := True;
- Source.ReadChunkData(Current);
- Map.MapType := Current^.Data.MeshTextureInfo^.MapType;
- Map.TileX := Current^.Data.MeshTextureInfo^.XTiling;
- Map.TileY := Current^.Data.MeshTextureInfo^.YTiling;
- Map.CenX := Current^.Data.MeshTextureInfo^.IconPos.X;
- Map.CenY := Current^.Data.MeshTextureInfo^.IconPos.Y;
- Map.CenZ := Current^.Data.MeshTextureInfo^.IconPos.Z;
- Map.Scale := Current^.Data.MeshTextureInfo^.IconScaling;
- Map.Matrix := Current^.Data.MeshTextureInfo^.XMatrix;
- Map.PW := Current^.Data.MeshTextureInfo^.IconWidth;
- Map.PH := Current^.Data.MeshTextureInfo^.IconHeight;
- Map.CH := Current^.Data.MeshTextureInfo^.CylIconHeight;
- FreeChunkData(Current);
- end;
- PROC_NAME:
- begin
- Source.ReadChunkData(Current);
- ProcNameStr := string(StrPas(Current^.Data.ProcName));
- FreeChunkData(Current);
- end;
- PROC_DATA:
- begin
- Source.ReadChunkData(Current);
- ProcSize := Current^.Data.IpasData^.Size;
- ProcData := Current^.Data.IpasData^.Data;
- Current^.Data.IpasData^.Data := nil;
- FreeChunkData(Current);
- end;
- MESH_COLOR:
- begin
- Source.ReadChunkData(Current);
- MeshColor := Current^.Data.MeshColor^;
- FreeChunkData(Current);
- end;
- end;
- Current := Current^.Sibling;
- end;
- IsHidden := Assigned(FindNextChunk(Chunk^.Children, OBJ_HIDDEN));
- IsVisLofter := Assigned(FindNextChunk(Chunk^.Children, OBJ_VIS_LOFTER));
- IsNoCast := Assigned(FindNextChunk(Chunk^.Children, OBJ_DOESNT_CAST));
- IsMatte := Assigned(FindNextChunk(Chunk^.Children, OBJ_MATTE));
- IsFast := Assigned(FindNextChunk(Chunk^.Children, OBJ_FAST));
- IsFrozen := Assigned(FindNextChunk(Chunk^.Children, OBJ_FROZEN));
- IsNoRcvShad := Assigned(FindNextChunk(Chunk^.Children, OBJ_DONT_RCVSHADOW));
- UseProc := Assigned(FindNextChunk(Chunk^.Children, OBJ_PROCEDURAL));
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetMeshByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: integer): TMesh3DS;
- // fills a mesh structure from the (index)th mesh reference found in DB
- var
- Current: PChunk3DS;
- I, Count: integer;
- begin
- FillChar(Result, SizeOf(Result), 0);
- if DB.TopChunk = nil then
- ShowError(strError3DS_INVALID_DATABASE);
- if (DB.TopChunk^.Tag <> M3DMAGIC) and (DB.TopChunk^.Tag <> CMAGIC) then
- ShowError(strError3DS_WRONG_DATABASE);
- // update the index to named objects if the list has changed recently
- UpdateNamedObjectList(Source, DB);
- // scan through the list of named objects
- Count := 0;
- for I := 0 to DB.ObjList^.Count - 1 do
- begin
- // search each named object for a mesh chunk
- Current := FindChunk(DB.ObjList^.List^[I].Chunk, N_TRI_OBJECT);
- // if a mesh chunk is found
- if Assigned(Current) then
- begin
- // increment the running total
- Inc(Count);
- // if this is the (index)th mesh, fill out the structure
- if (Count - 1) = Index then
- begin
- Result := GetMeshEntryChunk(Source, DB.ObjList^.List^[I].Chunk);
- Break;
- end;
- end;
- end;
- end;
- //----------------- spot and omni light handling ----------------------------------------------------------------------
- function GetOmnilightCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- var
- DLite, SpotL: PChunk3DS;
- I: integer;
- begin
- // update the index to named objects if the list has changed recently
- UpdateNamedObjectList(Source, DB);
- Result := 0;
- if DB.ObjList = nil then
- Exit;
- // scan through the list of named objects looking for lights
- for I := 0 to DB.ObjList^.Count - 1 do
- begin
- // search each object for a Light chunk
- DLite := FindChunk(DB.ObjList^.List^[I].chunk, N_DIRECT_LIGHT);
- // if one was found, check to see if its a spotlight
- if Assigned(DLite) then
- begin
- SpotL := FindChunk(DLite, DL_SPOTLIGHT);
- // if it isn't a spotlight then increment the count
- if SpotL = nil then
- Inc(Result);
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetSpotlightCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- var
- DLite, SpotL: PChunk3DS;
- I: integer;
- begin
- // update the index to named objects if the list has changed recently
- UpdateNamedObjectList(Source, DB);
- Result := 0;
- if DB.ObjList = nil then
- Exit;
- // scan through the list of named objects looking for lights
- for I := 0 to DB.ObjList^.Count - 1 do
- begin
- // search each object for a Light chunk
- DLite := FindChunk(DB.ObjList^.List^[I].Chunk, N_DIRECT_LIGHT);
- // if one was found, check to see if its a spotlight
- if Assigned(DLite) then
- begin
- SpotL := FindChunk(DLite, DL_SPOTLIGHT);
- // if it is a spotlight then increment the count
- if Assigned(SpotL) then
- Inc(Result);
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure InitLight(var Light: TLight3DS);
- // Initializes the Light structure
- begin
- FillChar(Light, SizeOf(Light), 0);
- with Light do
- begin
- NameStr := '';
- Color.R := 0.708852;
- Color.G := 0.708852;
- Color.B := 0.708852;
- Multiplier := 1;
- Attenuation.Inner := 10;
- Attenuation.Outer := 100;
- Exclude := TStringList.Create;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure ReleaseLight(Light: PLight3DS);
- begin
- Light^.Exclude.Free;
- Light^.Exclude := nil;
- if Assigned(Light^.Spot) then
- begin
- Light^.Spot^.Projector.BitmapStr := '';
- FreeMem(Light^.Spot);
- end;
- Dispose(Light);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure InitSpotLight(var SpotLight: TLight3DS);
- begin
- // do the common Light initialization
- InitLight(SpotLight);
- SpotLight.Spot := AllocMem(SizeOf(TSpotLight3DS));
- with SpotLight.Spot^ do
- begin
- Target.X := 1;
- Target.Y := 1;
- Target.Z := 1;
- Hotspot := 44;
- Falloff := 45;
- Aspect := 1;
- Shadows.AType := ssUseShadowMap;
- Shadows.Bias := 1;
- Shadows.Filter := 3;
- Shadows.Mapsize := 512;
- Shadows.RayBias := 1;
- Cone.AType := csCircular;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetLightEntryChunk(const Source: TFile3DS; Chunk: PChunk3DS): TLight3DS;
- // fills out the given Light structure with the Light pointed to by Chunk
- var
- DLite, SpotChunk, Current: PChunk3DS;
- begin
- DLite := FindNextChunk(Chunk^.Children, N_DIRECT_LIGHT);
- if DLite = nil then
- ShowError(strError3DS_WRONG_OBJECT);
- DLite := FindChunk(Chunk^.Children, N_DIRECT_LIGHT);
- SpotChunk := FindChunk(Chunk, DL_SPOTLIGHT);
- if Assigned(DLite) then
- with Result do
- begin
- // initilize Light
- if SpotChunk = nil then
- InitLight(Result)
- else
- InitSpotLight(Result);
- // read object name
- Source.ReadChunkData(Chunk);
- NameStr := StrPas(Chunk^.Data.NamedObject);
- FreeChunkData(Chunk);
- // read Light postion
- Source.ReadChunkData(DLite);
- Pos := DLite^.Data.NDirectLight^;
- // scan all the chunks the Light contains
- Current := DLite^.Children;
- while Assigned(Current) do
- begin
- case Current^.Tag of
- COLOR_F:
- begin
- Source.ReadChunkData(Current);
- Color.R := Current^.Data.ColorF^.Red;
- Color.G := Current^.Data.ColorF^.Green;
- Color.B := Current^.Data.ColorF^.Blue;
- FreeChunkData(Current);
- end;
- COLOR_24:
- begin
- Source.ReadChunkData(Current);
- Color.R := Current^.Data.Color24^.Red / 255;
- Color.G := Current^.Data.Color24^.Green / 255;
- Color.B := Current^.Data.Color24^.Blue / 255;
- FreeChunkData(Current);
- end;
- DL_MULTIPLIER:
- begin
- Source.ReadChunkData(Current);
- Multiplier := Current^.Data.DlMultiplier^;
- FreeChunkData(Current);
- end;
- DL_INNER_RANGE:
- begin
- Source.ReadChunkData(Current);
- // assuming since there is a value it is on
- Attenuation.Inner := Current^.Data.DlInnerRange^;
- FreeChunkData(Current);
- end;
- DL_OUTER_RANGE:
- begin
- Source.ReadChunkData(Current);
- // assuming since there is a value it is on
- Attenuation.Outer := Current^.Data.DlOuterRange^;
- FreeChunkData(Current);
- end;
- DL_EXCLUDE:
- begin
- Source.ReadChunkData(Current);
- Exclude.Add(string(Current^.Data.DlExclude^));
- FreeChunkData(Current);
- end;
- DL_OFF:
- DLOff := True;
- DL_ATTENUATE:
- Attenuation.IsOn := True;
- end;
- Current := Current^.Sibling;
- end;
- // DL_SPOTLIGHT chunk
- if Assigned(SpotChunk) then
- begin
- // read spotlight data
- Source.ReadChunkData(SpotChunk);
- Spot^.Target := SpotChunk^.Data.DlSpotlight^.SpotLightTarg;
- Spot^.Hotspot := SpotChunk^.Data.DlSpotlight^.HotspotAngle;
- Spot^.Falloff := SpotChunk^.Data.DlSpotlight^.FalloffAngle;
- // scan all the chunks the spotlight contains
- Current := SpotChunk^.Children;
- while Assigned(Current) do
- begin
- case Current^.Tag of
- DL_SPOT_ROLL:
- begin
- Source.ReadChunkData(Current);
- Spot^.Roll := Current^.Data.DlSpotRoll^;
- FreeChunkData(Current);
- end;
- DL_LOCAL_SHADOW:
- Spot^.Shadows.Cast := True;
- DL_LOCAL_SHADOW2:
- begin
- Source.ReadChunkData(Current);
- Spot^.Shadows.Bias := Current^.Data.DlLocalShadow2^.LocalShadowBias;
- Spot^.Shadows.Filter := Current^.Data.DlLocalShadow2^.LocalShadowFilter;
- Spot^.Shadows.Mapsize :=
- Current^.Data.DlLocalShadow2^.LocalShadowMapSize;
- Spot^.Shadows.Local := True;
- FreeChunkData(Current);
- end;
- DL_SHADOWED:
- Spot^.Shadows.Cast := True;
- DL_SPOT_RECTANGULAR:
- Spot^.Cone.AType := csRectangular;
- DL_SEE_CONE:
- Spot^.Cone.Show := True;
- DL_SPOT_OVERSHOOT:
- Spot^.Cone.Overshoot := True;
- DL_SPOT_ASPECT:
- begin
- Source.ReadChunkData(Current);
- Spot^.Aspect := Current^.Data.DlSpotAspect^;
- FreeChunkData(Current);
- end;
- DL_RAY_BIAS:
- begin
- Source.ReadChunkData(Current);
- Spot^.Shadows.RayBias := Current^.Data.DlRayBias^;
- FreeChunkData(Current);
- end;
- DL_RAYSHAD:
- Spot^.Shadows.AType := ssUseRayTraceShadow;
- DL_SPOT_PROJECTOR:
- begin
- Source.ReadChunkData(Current);
- Spot^.Projector.BitmapStr :=
- string(StrPas(Current^.Data.DlSpotProjector));
- Spot^.Projector.Use := True;
- FreeChunkData(Current);
- end;
- end;
- Current := Current^.Sibling;
- end;
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetOmnilightByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: integer): TLight3DS;
- // fills out the omnilight structure from the (index)th mesh reference found in DB
- var
- LightChunk, SpotChunk: PChunk3DS;
- I, Count: integer;
- begin
- FillChar(Result, SizeOf(Result), 0);
- if (DB.TopChunk = nil) then
- ShowError(strError3DS_INVALID_DATABASE);
- if not (DB.TopChunk^.Tag = M3DMAGIC) and not (DB.TopChunk^.Tag = CMAGIC) then
- ShowError(strError3DS_WRONG_DATABASE);
- // update the list if it's changed recently
- UpdateNamedObjectList(Source, DB);
- // Scan through the List
- Count := 0;
- for I := 0 to DB.ObjList^.Count - 1 do
- begin
- // search for a Light chunk
- LightChunk := FindChunk(DB.ObjList^.List^[I].Chunk, N_DIRECT_LIGHT);
- // if one was found check to see if its a spot
- if Assigned(LightChunk) then
- begin
- SpotChunk := FindChunk(LightChunk, DL_SPOTLIGHT);
- // if its not a spot then increment the count
- if SpotChunk = nil then
- begin
- Inc(Count);
- // if this is the (index)th Light file out the structure
- if (Count - 1) = Index then
- begin
- Result := GetLightEntryChunk(Source, DB.ObjList^.List^[I].Chunk);
- Break;
- end;
- end;
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetSpotlightByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: integer): TLight3DS;
- // fills out the Spot structure from the (index)th spot reference found in DB
- var
- LightChunk, SpotChunk: PChunk3DS;
- I, Count: integer;
- begin
- FillChar(Result, SizeOf(Result), 0);
- if (DB.TopChunk = nil) then
- ShowError(strError3DS_INVALID_DATABASE);
- if not (DB.TopChunk^.Tag = M3DMAGIC) and not (DB.TopChunk^.Tag = CMAGIC) then
- ShowError(strError3DS_WRONG_DATABASE);
- // update the list if it's changed recently
- UpdateNamedObjectList(Source, DB);
- // Scan through the List
- Count := 0;
- for I := 0 to DB.ObjList^.Count - 1 do
- begin
- // search for a Light chunk
- LightChunk := FindChunk(DB.ObjList^.List^[I].Chunk, N_DIRECT_LIGHT);
- // if one was found check to see if its a spot
- if Assigned(LightChunk) then
- begin
- SpotChunk := FindChunk(LightChunk, DL_SPOTLIGHT);
- // if its not a spot then increment the count
- if Assigned(SpotChunk) then
- begin
- Inc(Count);
- // if this is the (index)th Light file out the structure
- if (Count - 1) = Index then
- begin
- Result := GetLightEntryChunk(Source, DB.ObjList^.List^[I].Chunk);
- Break;
- end;
- end;
- end;
- end;
- end;
- //----------------- camera handling -----------------------------------------------------------------------------------
- procedure InitCamera(var Camera: TCamera3DS);
- begin
- FillChar(Camera, SizeOf(Camera), 0);
- with Camera do
- begin
- Target.X := 1;
- Target.Y := 1;
- Target.Z := 1;
- FOV := 45;
- Ranges.CamNear := 10;
- Ranges.CamFar := 1000;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure ReleaseCamera(Camera: PCamera3DS);
- begin
- if Assigned(Camera) then
- begin
- Dispose(Camera);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetCameraCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- var
- Chunk: PChunk3DS;
- I: integer;
- begin
- UpdateNamedObjectList(Source, DB);
- Result := 0;
- if Assigned(DB.ObjList) then
- for I := 0 to DB.ObjList^.Count - 1 do
- begin
- Chunk := FindChunk(DB.ObjList^.List^[I].Chunk, N_CAMERA);
- if Assigned(Chunk) then
- Inc(Result);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetCameraEntry(const Source: TFile3DS; Chunk: PChunk3DS): TCamera3DS;
- var
- Current, Camera: PChunk3DS;
- begin
- if Chunk^.Tag <> NAMED_OBJECT then
- ShowError(strError3DS_WRONG_OBJECT);
- Camera := FindNextChunk(Chunk^.Children, N_CAMERA);
- if Camera = nil then
- ShowError(strError3DS_WRONG_OBJECT);
- with Result do
- begin
- InitCamera(Result);
- Camera := FindNextChunk(Chunk^.Children, N_CAMERA);
- Source.ReadChunkData(Chunk);
- NameStr := StrPas(Chunk^.Data.NamedObject);
- FreeChunkData(Chunk);
- Source.ReadChunkData(Camera);
- Position.X := Camera^.Data.NCamera^.CameraPos.X;
- Position.Y := Camera^.Data.NCamera^.CameraPos.Y;
- Position.Z := Camera^.Data.NCamera^.CameraPos.Z;
- Target.X := Camera^.Data.NCamera^.TargetPos.X;
- Target.Y := Camera^.Data.NCamera^.TargetPos.Y;
- Target.Z := Camera^.Data.NCamera^.TargetPos.Z;
- Roll := Camera^.Data.NCamera^.CameraBank;
- FOV := 2400 / Camera^.Data.NCamera^.CameraFocalLength;
- FreeChunkData(Camera);
- Current := Camera^.Children;
- while Assigned(Current) do
- begin
- case Current^.Tag of
- CAM_SEE_CONE:
- ShowCone := True;
- CAM_RANGES:
- begin
- Source.ReadChunkData(Current);
- Ranges.CamNear := Current^.Data.CamRanges^.NearPlane;
- Ranges.CamFar := Current^.Data.CamRanges^.FarPlane;
- FreeChunkData(Current);
- end;
- end;
- Current := Current^.Sibling;
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetCameraByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: integer): TCamera3DS;
- var
- Camera: PChunk3DS;
- I, Count: integer;
- begin
- FillChar(Result, SizeOf(Result), 0);
- UpdateNamedObjectList(Source, DB);
- Count := 0;
- for I := 0 to DB.ObjList^.Count - 1 do
- begin
- Camera := FindChunk(DB.ObjList^.List^[I].Chunk, N_CAMERA);
- if Assigned(Camera) then
- begin
- Inc(Count);
- if (Count - 1) = Index then
- Result := GetCameraEntry(Source, DB.ObjList^.List^[I].Chunk);
- end;
- end;
- end;
- //----------------- common animation settings -------------------------------------------------------------------------
- procedure InitKfSets(var Key: TKFSets3DS);
- begin
- Key.Anim.Length := 30;
- Key.Anim.CurFrame := 0;
- Key.Seg.Use := False;
- Key.Seg.SegBegin := 0;
- Key.Seg.SegEnd := 30;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetKFSeg(TopChunk: PChunk3DS): PChunk3DS;
- // all the keyframe information has to go in the appropriate segment KFDATA
- begin
- // look for KFDATA
- Result := FindNextChunk(TopChunk^.Children, KFDATA);
- if Result = nil then
- Result := PutGenericNode(KFDATA, TopChunk);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetKeyInfo(const Source: TFile3DS; var DB: TDatabase3DS): TKFKeyInfo3DS;
- var
- KFData, KFHdrChunk, KFCTChunk: PChunk3DS;
- begin
- KFData := GetKfSeg(DB.TopChunk);
- KFHdrChunk := FindNextChunk(KFData^.Children, KFHDR);
- if Assigned(KFHdrChunk) then
- begin
- Source.ReadChunkData(KFHdrChunk);
- Result.Length := KFHdrChunk^.Data.KFHdr^.AnimLength;
- FreeChunkData(KFHdrChunk);
- end;
- KFCTChunk := FindNextChunk(KFData^.Children, KFCURTIME);
- if Assigned(KFCTChunk) then
- begin
- Source.ReadChunkData(KFCTChunk);
- Result.CurFrame := KFCTChunk^.Data.KFCurTime^;
- FreeChunkData(KFCTChunk);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetKFSegment(const Source: TFile3DS; var DB: TDatabase3DS): TKFSegment3DS;
- var
- DataChunk, SegChunk: PChunk3DS;
- begin
- Result.SegBegin := 0;
- Result.SegEnd := 0;
- Result.Use := False;
- DataChunk := GetKFSeg(DB.TopChunk);
- SegChunk := FindNextChunk(DataChunk^.Children, KFSEG);
- if Assigned(SegChunk) then
- begin
- Source.ReadChunkData(SegChunk);
- Result.Use := True;
- Result.SegBegin := SegChunk^.Data.KFSeg^.First;
- Result.SegEnd := SegChunk^.Data.KFSeg^.Last;
- FreeChunkData(SegChunk);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetKFSettings(const Source: TFile3DS; var DB: TDatabase3DS): TKFSets3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- if DB.TopChunk = nil then
- ShowError(strError3DS_INVALID_DATABASE);
- if (DB.TopChunk^.Tag <> M3DMAGIC) and (DB.TopChunk^.Tag <> CMAGIC) then
- ShowError(strError3DS_WRONG_DATABASE);
- InitKFSets(Result);
- Result.Anim := GetKeyInfo(Source, DB);
- Result.Seg := GetKFSegment(Source, DB);
- end;
- //----------------- Camera animation ----------------------------------------------------------------------------------
- procedure InitCameraMotion(var Camera: TKFCamera3DS;
- NewNPKeys, NewNFKeys, NewNRKeys, NewNTKeys: cardinal);
- var
- I: integer;
- begin
- with Camera do
- begin
- // free any previously allocated memory first
- if Assigned(PKeys) then
- FreeMem(PKeys);
- if Assigned(Pos) then
- FreeMem(Pos);
- if Assigned(FKeys) then
- FreeMem(FKeys);
- if Assigned(FOV) then
- FreeMem(FOV);
- if Assigned(RKeys) then
- FreeMem(RKeys);
- if Assigned(Roll) then
- FreeMem(Roll);
- if Assigned(TKeys) then
- FreeMem(TKeys);
- if Assigned(TPos) then
- FreeMem(TPos);
- FillChar(Camera, SizeOf(TKFCamera3DS), 0);
- NPKeys := NewNPKeys;
- NFKeys := NewNFKeys;
- NRKeys := NewNRKeys;
- NTKeys := NewNTKeys;
- if NPKeys <> 0 then
- begin
- NPFlag := TrackSingle3DS;
- PKeys := AllocMem(NPKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NPKeys - 1 do
- PKeys^[I] := DefKeyHeader3DS;
- Pos := AllocMem(NPKeys * SizeOf(TPoint3DS));
- for I := 0 to NPKeys - 1 do
- Pos^[I] := DefPoint3DS;
- end;
- if NFKeys <> 0 then
- begin
- NFFlag := TrackSingle3DS;
- FKeys := AllocMem(NFKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NFKeys - 1 do
- FKeys^[I] := DefKeyHeader3DS;
- FOV := AllocMem(NFKeys * SizeOf(single));
- for I := 0 to NFKeys - 1 do
- FOV^[I] := 60;
- end;
- if NRKeys <> 0 then
- begin
- NRFlag := TrackSingle3DS;
- RKeys := AllocMem(NRKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NRKeys - 1 do
- RKeys^[I] := DefKeyHeader3DS;
- Roll := AllocMem(NRKeys * SizeOf(single));
- end;
- if NTKeys <> 0 then
- begin
- NTFlag := TrackSingle3DS;
- TFlags1 := 0;
- TFlags2 := 0;
- TKeys := AllocMem(NTKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NTKeys - 1 do
- TKeys^[I] := DefKeyHeader3DS;
- TPos := AllocMem(NTKeys * SizeOf(TPoint3DS));
- for I := 0 to NTKeys - 1 do
- TPos^[I] := DefPoint3DS;
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure ReleaseCameraMotion(Camera: PKFCamera3DS);
- begin
- if Assigned(Camera) then
- begin
- with Camera^ do
- begin
- if Assigned(PKeys) then
- FreeMem(PKeys);
- if Assigned(Pos) then
- FreeMem(Pos);
- if Assigned(FKeys) then
- FreeMem(FKeys);
- if Assigned(FOV) then
- FreeMem(FOV);
- if Assigned(RKeys) then
- FreeMem(RKeys);
- if Assigned(Roll) then
- FreeMem(Roll);
- if Assigned(TKeys) then
- FreeMem(TKeys);
- if Assigned(TPos) then
- FreeMem(TPos);
- end;
- Dispose(Camera);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure GetCameraNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
- List: TStringList);
- begin
- GetGenericNodeNameList(Source, DB, CAMERA_NODE_TAG, List);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetCameraNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- begin
- Result := GetGenericNodeCount(Source, DB, CAMERA_NODE_TAG);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetParentName(const Source: TFile3DS; Chunk: PChunk3DS): string;
- // get parent name if there is one
- var
- NameChunk: PChunk3DS;
- begin
- Result := '';
- NameChunk := FindChunk(Chunk, PARENT_NAME);
- if Assigned(NameChunk) then
- begin
- Source.ReadChunkData(NameChunk);
- Result := string(NameChunk^.Data.NamedObject);
- FreeChunkData(NameChunk);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetCameraMotion(const Source: TFile3DS;
- CamChunk, TargetChunk: PChunk3DS): TKFCamera3DS;
- // gets camera keyframe information from chunk
- // CamChunk : CAMERA_NODE_TAG chunk to extract data from
- // TargetChunk : TARGET_NODE_TAG chunk to extract target data from
- // KFCamera : Structure to fill in with chunk data
- var
- NodeHdrChunk, PosChunk, FovChunk, RollChunk, TargetPosChunk,
- TargetHdrChunk: PChunk3DS;
- PosKeys, FovKeys, RollKeys, TargetKeys: integer;
- begin
- FillChar(Result, SizeOf(Result), 0);
- TargetPosChunk := nil;
- TargetHdrChunk := nil;
- PosKeys := 0;
- FovKeys := 0;
- RollKeys := 0;
- TargetKeys := 0;
- // get information from chunks
- // search children of camera Chunk
- NodeHdrChunk := FindChunk(CamChunk, NODE_HDR);
- PosChunk := FindChunk(CamChunk, POS_TRACK_TAG);
- FovChunk := FindChunk(CamChunk, FOV_TRACK_TAG);
- RollChunk := FindChunk(CamChunk, ROLL_TRACK_TAG);
- Source.ReadChunkData(NodeHdrChunk);
- if Assigned(PosChunk) then
- begin
- Source.ReadChunkData(PosChunk);
- PosKeys := PosChunk^.Data.PosTrackTag^.TrackHdr.KeyCount;
- end;
- if Assigned(FOVChunk) then
- begin
- Source.ReadChunkData(FOVChunk);
- FovKeys := FOVChunk^.Data.FOVTrackTag^.TrackHdr.KeyCount;
- end;
- if Assigned(RollChunk) then
- begin
- Source.ReadChunkData(RollChunk);
- RollKeys := RollChunk^.Data.RollTrackTag^.TrackHdr.KeyCount;
- end;
- if Assigned(TargetChunk) then
- begin
- TargetHdrChunk := FindChunk(TargetChunk, NODE_HDR);
- if Assigned(TargetHdrChunk) then
- Source.ReadChunkData(TargetHdrChunk);
- TargetPosChunk := FindChunk(TargetChunk, POS_TRACK_TAG);
- if Assigned(TargetPosChunk) then
- begin
- Source.ReadChunkData(TargetPosChunk);
- TargetKeys := TargetPosChunk^.Data.PosTrackTag^.TrackHdr.KeyCount;
- end;
- end;
- // set-up and fill-in the kfcamera structure
- InitCameraMotion(Result, PosKeys, FOVKeys, RollKeys, TargetKeys);
- with Result do
- begin
- // header Information
- if Assigned(NodeHdrChunk) then
- begin
- NameStr := ansistring(NodeHdrChunk^.Data.NodeHdr^.ObjNameStr);
- Flags1 := NodeHdrChunk^.Data.NodeHdr^.Flags1;
- Flags2 := NodeHdrChunk^.Data.NodeHdr^.Flags2;
- end;
- // parents
- ParentStr := ansistring(GetParentName(Source, NodeHdrChunk));
- TParentStr := GetParentName(Source, TargetHdrChunk);
- // target information
- if TargetKeys <> 0 then
- begin
- NTFlag := TargetPosChunk^.Data.PosTrackTag^.TrackHdr.Flags;
- Move(TargetPosChunk^.Data.PosTrackTag^.KeyHdrList^, TKeys^,
- TargetKeys * SizeOf(TKeyHeader3DS));
- Move(TargetPosChunk^.Data.PosTrackTag^.PositionList^, TPos^,
- TargetKeys * SizeOf(TPoint3DS));
- end;
- if Assigned(TargetHdrChunk) then
- begin
- TFlags1 := TargetHdrChunk^.Data.NodeHdr^.Flags1;
- TFlags2 := TargetHdrChunk^.Data.NodeHdr^.Flags2;
- end;
- // position information
- if PosKeys <> 0 then
- begin
- NPFlag := PosChunk^.Data.PosTrackTag^.TrackHdr.Flags;
- Move(PosChunk^.Data.PosTrackTag^.KeyHdrList^, PKeys^, PosKeys *
- SizeOf(TKeyHeader3DS));
- Move(PosChunk^.Data.PosTrackTag^.PositionList^, Pos^, PosKeys * SizeOf(TPoint3DS));
- end;
- // field of view information
- if FOVKeys <> 0 then
- begin
- NFFlag := FOVChunk^.Data.FOVTrackTag^.TrackHdr.Flags;
- Move(FOVChunk^.Data.FOVTrackTag^.KeyHdrList^, FKeys^, FOVKeys *
- SizeOf(TKeyHeader3DS));
- Move(FOVChunk^.Data.FOVTrackTag^.FOVAngleList^, FOV^, FOVKeys * SizeOf(single));
- end;
- // roll track information
- if RollKeys <> 0 then
- begin
- NRFlag := RollChunk^.Data.RollTrackTag^.TrackHdr.Flags;
- Move(RollChunk^.Data.RollTrackTag^.KeyHdrList^, RKeys^, RollKeys *
- SizeOf(TKeyHeader3DS));
- Move(RollChunk^.Data.RollTrackTag^.RollangleList^, Roll^,
- RollKeys * SizeOf(single));
- end;
- // free chunk data
- if Assigned(PosChunk) then
- FreeChunkData(PosChunk);
- if Assigned(FovChunk) then
- FreeChunkData(FovChunk);
- if Assigned(RollChunk) then
- FreeChunkData(RollChunk);
- if Assigned(NodeHdrChunk) then
- FreeChunkData(NodeHdrChunk);
- if Assigned(TargetPosChunk) then
- FreeChunkData(TargetPosChunk);
- if Assigned(TargetHdrChunk) then
- FreeChunkData(TargetHdrChunk);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetCameraMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: integer): TKFCamera3DS;
- var
- CameraChunk, TargetChunk: PChunk3DS;
- List: TStringList;
- begin
- FillChar(Result, SizeOf(Result), 0);
- List := TStringList.Create;
- try
- GetCameraNodeNameList(Source, DB, List);
- if Index < List.Count then
- begin
- CameraChunk := FindNamedAndTaggedChunk(Source, DB, List[Index], CAMERA_NODE_TAG);
- if Assigned(CameraChunk) then
- begin
- TargetChunk := FindNamedAndTaggedChunk(Source, DB, List[Index], TARGET_NODE_TAG);
- Result := GetCameraMotion(Source, CameraChunk, TargetChunk);
- end;
- end;
- finally
- List.Free;
- end;
- end;
- //----------------- Ambient Light animation ---------------------------------------------------------------------------
- procedure InitAmbientLightMotion(var Light: TKFAmbient3DS; NewNCKeys: cardinal);
- var
- I: integer;
- begin
- with Light do
- begin
- if Assigned(Color) then
- FreeMem(Color);
- if Assigned(CKeys) then
- FreeMem(CKeys);
- FillChar(Light, SizeOf(Light), 0);
- NCKeys := NewNCKeys;
- if NCKeys <> 0 then
- begin
- NCFlag := TrackSingle3DS;
- CKeys := AllocMem(NCKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NCKeys - 1 do
- CKeys^[I] := DefKeyHeader3DS;
- Color := AllocMem(NCKeys * SizeOf(TFColor3DS));
- for I := 0 to NCKeys - 1 do
- begin
- Color^[I].R := 1;
- Color^[I].G := 1;
- Color^[I].B := 1;
- end;
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure ReleaseAmbientLightMotion(Light: PKFAmbient3DS);
- begin
- if Assigned(Light) then
- begin
- with Light^ do
- begin
- if Assigned(CKeys) then
- FreeMem(CKeys);
- if Assigned(Color) then
- FreeMem(Color);
- end;
- Dispose(Light);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetAmbientLightMotionChunk(const Source: TFile3DS;
- AmbientChunk: PChunk3DS): TKFAmbient3DS;
- // AmbientChunk : SPOTAMBIENT_NODE_TAG chunk to extract data from
- // TargetChunk : L_TARGET_NODE_TAG chunk to extract target data from
- // KFSpot : Structure to fill in with chunk data
- // Gets AmbientLight keyframe information from chunk
- // L_TARGET
- // ...
- // NODE_HDR
- // APP_DATA
- // COL_TRACK
- var
- NodeHdrChunk, ColChunk: PChunk3DS;
- ColKeys: integer;
- begin
- if AmbientChunk = nil then
- ShowError(strERROR3DS_INVALID_ARG);
- FillChar(Result, SizeOf(Result), 0);
- // get information from chunks
- // search children of AmbientLight chunk
- NodeHdrChunk := FindChunk(AmbientChunk, NODE_HDR);
- ColChunk := FindChunk(AmbientChunk, COL_TRACK_TAG);
- if Assigned(NodeHdrChunk) then
- Source.ReadChunkData(NodeHdrChunk);
- if Assigned(ColChunk) then
- begin
- Source.ReadChunkData(ColChunk);
- ColKeys := ColChunk^.Data.ColTrackTag^.TrackHdr.KeyCount;
- end
- else
- ColKeys := 0;
- // eat-up and fill-in the PKFAmbient3DS structure
- InitAmbientLightMotion(Result, ColKeys);
- // header information
- if Assigned(NodeHdrChunk) then
- begin
- Result.Flags1 := NodeHdrChunk^.Data.NodeHdr^.Flags1;
- Result.Flags2 := NodeHdrChunk^.Data.NodeHdr^.Flags2;
- end;
- // color information
- if Assigned(ColChunk) then
- begin
- if ColKeys <> 0 then
- begin
- Result.NCFlag := ColChunk^.Data.ColTrackTag^.TrackHdr.Flags;
- Move(ColChunk^.Data.ColTrackTag^.KeyHdrList^, Result.CKeys^,
- ColKeys * SizeOf(TKeyHeader3DS));
- Move(ColChunk^.Data.ColTrackTag^.ColorList^, Result.Color^,
- ColKeys * SizeOf(TFColor3DS));
- end;
- end;
- // free chunk data
- if Assigned(NodeHdrChunk) then
- FreeChunkData(NodeHdrChunk);
- if Assigned(ColChunk) then
- FreeChunkData(ColChunk);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetAmbientLightMotion(const Source: TFile3DS;
- var DB: TDatabase3DS): TKFAmbient3DS;
- // Ambient Light a special case: only one ambient node per keyframe data Chunk^.
- var
- KFChunk, Chunk: PChunk3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- // find keyframe chunk
- KFChunk := FindChunk(DB.TopChunk, KFDATA);
- if Assigned(KFChunk) then
- begin
- Chunk := FindChunk(KFChunk, AMBIENT_NODE_TAG);
- if Assigned(Chunk) then
- Result := GetAmbientLightMotionChunk(Source, Chunk);
- end;
- end;
- //----------------- Mesh object animation -----------------------------------------------------------------------------
- procedure InitObjectMotion(var Obj: TKFMesh3DS; NewNPKeys, // Number of position keys
- NewNRKeys, // Number of rot keys
- NewNSKeys, // Number of scale keys
- NewNMKeys, // Number of morph keys
- NewNHKeys: cardinal); // Number of hide keys
- var
- I: integer;
- begin
- with Obj do
- begin
- if Assigned(PKeys) then
- FreeMem(PKeys);
- if Assigned(Pos) then
- FreeMem(Pos);
- if Assigned(RKeys) then
- FreeMem(RKeys);
- if Assigned(Rot) then
- FreeMem(Rot);
- if Assigned(SKeys) then
- FreeMem(SKeys);
- if Assigned(Scale) then
- FreeMem(Scale);
- if Assigned(MKeys) then
- FreeMem(MKeys);
- if Assigned(Morph) then
- FreeMem(Morph);
- if Assigned(HKeys) then
- FreeMem(HKeys);
- FillChar(Obj, SizeOf(Obj), 0);
- Pivot := DefPoint3DS;
- BoundMin := DefPoint3DS;
- BoundMax := DefPoint3DS;
- NPKeys := NewNPKeys;
- NRKeys := NewNRKeys;
- NSKeys := NewNSKeys;
- NMKeys := NewNMKeys;
- NHKeys := NewNHKeys;
- MSAngle := 24;
- if NPKeys <> 0 then
- begin
- NPFlag := TrackSingle3DS;
- PKeys := AllocMem(NPKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NPKeys - 1 do
- PKeys^[I] := DefKeyHeader3DS;
- Pos := AllocMem(NPKeys * SizeOf(TPoint3DS));
- for I := 0 to NPKeys - 1 do
- Pos^[I] := DefPoint3DS;
- end;
- if NRKeys <> 0 then
- begin
- NRFlag := TrackSingle3DS;
- RKeys := AllocMem(NRKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NRKeys - 1 do
- RKeys^[I] := DefKeyHeader3DS;
- Rot := AllocMem(NRKeys * SizeOf(TKFRotKey3DS));
- for I := 0 to NRKeys - 1 do
- Rot^[I] := DefKfRotKey3DS;
- end;
- if NSKeys <> 0 then
- begin
- NSFlag := TrackSingle3DS;
- SKeys := AllocMem(NSKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NSKeys - 1 do
- SKeys^[I] := DefKeyHeader3DS;
- Scale := AllocMem(NSKeys * SizeOf(TPoint3DS));
- for I := 0 to NSKeys - 1 do
- begin
- Scale^[I].X := 1;
- Scale^[I].Y := 1;
- Scale^[I].Z := 1;
- end;
- end;
- if NMKeys <> 0 then
- begin
- NMFlag := TrackSingle3DS;
- MKeys := AllocMem(NMKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NMKeys - 1 do
- MKeys^[I] := DefKeyHeader3DS;
- Morph := AllocMem(NMKeys * SizeOf(TKFMorphKey3DS));
- for I := 0 to NMKeys - 1 do
- Morph^[I] := ' ';
- end;
- if NHKeys <> 0 then
- begin
- NHFlag := TrackSingle3DS;
- HKeys := AllocMem(NHKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NMKeys - 1 do
- MKeys^[I] := DefKeyHeader3DS;
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure ReleaseObjectMotion(Obj: PKFMesh3DS);
- begin
- if Assigned(Obj) then
- begin
- with Obj^ do
- begin
- if Assigned(PKeys) then
- FreeMem(PKeys);
- if Assigned(Pos) then
- FreeMem(Pos);
- if Assigned(RKeys) then
- FreeMem(RKeys);
- if Assigned(Rot) then
- FreeMem(Rot);
- if Assigned(SKeys) then
- FreeMem(SKeys);
- if Assigned(Scale) then
- FreeMem(Scale);
- if Assigned(MKeys) then
- FreeMem(MKeys);
- if Assigned(Morph) then
- FreeMem(Morph);
- if Assigned(HKeys) then
- FreeMem(HKeys);
- end;
- Dispose(Obj);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetObjectNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
- begin
- Result := GetGenericNodeCount(Source, DB, OBJECT_NODE_TAG);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure GetObjectNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
- List: TStringList);
- begin
- GetGenericNodeNameList(Source, DB, OBJECT_NODE_TAG, List);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetObjectMotion(const Source: TFile3DS; MeshChunk: PChunk3DS): TKFMesh3DS;
- // Gets mesh keyframe information from chunk
- // NODE_ID
- // NODE_HDR
- // APP_DATA
- // INSTANCE_NAME
- // PRESCALE a no-op in 3DS code
- // POS_TRACK
- // ROT_TRACK
- // SCL_TRACK
- // MORPH_TRACK
- // MORPH_SMOOTH
- // HIDE_TRACK
- // This function is really confusing, because instead of loading the MeshChunk and its children, reading the
- // data out and freeing it, the chunk structure is copied, its data is moved to the copy (so MeshChunk is then without
- // any data), the copy is parsed and then it is freed. I don't know why this is so, but I don't want to change
- // the way it works in case this has (or will later have) side effects I don't see yet. ml
- var
- NodeHdrChunk, InstChunk, PivotChunk, BboxChunk, MsChunk,
- PosChunk, RotChunk, ScaleChunk, MorphChunk, HideChunk,
- ObjTag: PChunk3DS;
- PosKeys, RotKeys, ScaleKeys, MorphKeys, HideKeys: integer;
- PivotData: PPivot;
- InstData: PInstanceName;
- BBoxData: PBoundBox;
- MsData: PMorphSmooth;
- PosData: PPosTrackTag;
- RotData: PRotTrackTag;
- ScaleData: PScaleTrackTag;
- MorphData: PMorphTrackTag;
- HideData: PHideTrackTag;
- begin
- PosKeys := 0;
- RotKeys := 0;
- ScaleKeys := 0;
- MorphKeys := 0;
- HideKeys := 0;
- PivotData := nil;
- InstData := nil;
- BboxData := nil;
- MsData := nil;
- PosData := nil;
- RotData := nil;
- ScaleData := nil;
- MorphData := nil;
- HideData := nil;
- if MeshChunk^.Tag <> OBJECT_NODE_TAG then
- ShowError(strERROR3DS_WRONG_OBJECT);
- ObjTag := CopyChunk(MeshChunk);
- // get information from chunks
- // search children of MeshLight chunk
- NodeHdrChunk := FindChunk(ObjTag, NODE_HDR);
- InstChunk := FindChunk(ObjTag, INSTANCE_NAME);
- PivotChunk := FindChunk(ObjTag, PIVOT);
- BboxChunk := FindChunk(ObjTag, BOUNDBOX);
- MsChunk := FindChunk(ObjTag, MORPH_SMOOTH);
- PosChunk := FindChunk(ObjTag, POS_TRACK_TAG);
- RotChunk := FindChunk(ObjTag, ROT_TRACK_TAG);
- ScaleChunk := FindChunk(ObjTag, SCL_TRACK_TAG);
- MorphChunk := FindChunk(ObjTag, MORPH_TRACK_TAG);
- HideChunk := FindChunk(ObjTag, HIDE_TRACK_TAG);
- Source.ReadChunkData(NodeHdrChunk);
- if Assigned(InstChunk) then
- begin
- Source.ReadChunkData(InstChunk);
- InstData := InstChunk^.Data.Dummy;
- InstChunk^.Data.Dummy := nil;
- end;
- if Assigned(PivotChunk) then
- begin
- Source.ReadChunkData(PivotChunk);
- PivotData := PivotChunk^.Data.Dummy;
- PivotChunk^.Data.Dummy := nil;
- end;
- if Assigned(BboxChunk) then
- begin
- Source.ReadChunkData(BboxChunk);
- BboxData := BboxChunk^.Data.Dummy;
- BboxChunk^.Data.Dummy := nil;
- end;
- if Assigned(MsChunk) then
- begin
- Source.ReadChunkData(MsChunk);
- MsData := MsChunk^.Data.Dummy;
- MsChunk^.Data.Dummy := nil;
- end;
- if Assigned(PosChunk) then
- begin
- Source.ReadChunkData(PosChunk);
- PosData := PosChunk^.Data.Dummy;
- PosKeys := PosData^.TrackHdr.KeyCount;
- PosChunk^.Data.Dummy := nil;
- end;
- if Assigned(RotChunk) then
- begin
- Source.ReadChunkData(RotChunk);
- RotData := RotChunk^.Data.Dummy;
- RotKeys := RotData^.TrackHdr.KeyCount;
- RotChunk^.Data.Dummy := nil;
- end;
- if Assigned(ScaleChunk) then
- begin
- Source.ReadChunkData(ScaleChunk);
- ScaleData := ScaleChunk^.Data.Dummy;
- ScaleKeys := ScaleData^.TrackHdr.KeyCount;
- ScaleChunk^.Data.Dummy := nil;
- end;
- if Assigned(MorphChunk) then
- begin
- Source.ReadChunkData(MorphChunk);
- MorphData := MorphChunk^.Data.Dummy;
- MorphKeys := MorphData^.TrackHdr.KeyCount;
- MorphChunk^.Data.Dummy := nil;
- end;
- if Assigned(HideChunk) then
- begin
- Source.ReadChunkData(HideChunk);
- HideData := HideChunk^.Data.Dummy;
- HideKeys := HideData^.TrackHdr.KeyCount;
- HideChunk^.Data.Dummy := nil;
- end;
- // set-up and fill-in the TKFMesh3DS structure
- with Result do
- begin
- //--- header Information
- NameStr := AnsiString(NodeHdrChunk^.Data.NodeHdr^.ObjNameStr);
- Flags1 := NodeHdrChunk^.Data.NodeHdr^.Flags1;
- Flags2 := NodeHdrChunk^.Data.NodeHdr^.Flags2;
- //--- get parent name if there is one
- ParentStr := AnsiString(GetParentName(Source, NodeHdrChunk));
- //--- Instance
- if Assigned(InstData) then
- begin
- InstanceStr := StrPas(InstData);
- NameStr := NameStr + '.' + InstanceStr;
- FreeMem(InstData);
- end
- else
- InstanceStr := '';
- //--- Pivot
- if Assigned(PivotData) then
- begin
- Pivot := PivotData^;
- FreeMem(PivotData);
- end
- else
- Pivot := DefPoint3DS;
- //--- Bound
- if Assigned(BboxData) then
- begin
- BoundMin := BboxData^.Min;
- BoundMax := BboxData^.Max;
- FreeMem(BboxData);
- end
- else
- begin
- BoundMin := DefPoint3DS;
- BoundMax := DefPoint3DS;
- end;
- //--- MorphSmooth Angle
- if Assigned(MsData) then
- begin
- MSAngle := MsData^;
- FreeMem(MsData);
- end
- else
- MSAngle := 0;
- //--- Position
- NPKeys := PosKeys;
- if PosKeys <> 0 then
- begin
- PKeys := PosData^.KeyHdrList;
- Pos := PosData^.PositionList;
- NPFlag := PosData^.TrackHdr.Flags;
- FreeMem(PosData);
- end
- else
- begin
- PKeys := nil;
- Pos := nil;
- NPFlag := 0;
- end;
- //--- Rotation
- NRKeys := RotKeys;
- if RotKeys <> 0 then
- begin
- RKeys := RotData^.KeyHdrList;
- Rot := RotData^.RotationList;
- NRFlag := RotData^.TrackHdr.Flags;
- FreeMem(RotData);
- end
- else
- begin
- RKeys := nil;
- Rot := nil;
- NRFlag := 0;
- end;
- //--- Scale
- NSKeys := ScaleKeys;
- if ScaleKeys <> 0 then
- begin
- SKeys := ScaleData^.KeyHdrList;
- Scale := ScaleData^.ScaleList;
- NSFlag := ScaleData^.TrackHdr.Flags;
- FreeMem(ScaleData);
- end
- else
- begin
- SKeys := nil;
- Scale := nil;
- NSFlag := 0;
- end;
- //--- Morph
- NMKeys := MorphKeys;
- if MorphKeys <> 0 then
- begin
- MKeys := MorphData^.KeyHdrList;
- Morph := MorphData^.MorphList;
- NMFlag := MorphData^.TrackHdr.Flags;
- FreeMem(MorphData);
- end
- else
- begin
- MKeys := nil;
- Morph := nil;
- NMFlag := 0;
- end;
- NHKeys := HideKeys;
- if HideKeys <> 0 then
- begin
- HKeys := HideData^.KeyHdrList;
- NHFlag := HideData^.TrackHdr.Flags;
- FreeMem(HideData);
- end
- else
- begin
- HKeys := nil;
- NHFlag := 0;
- end;
- end;
- //-- ADDITIONAL Morph INFO HERE
- //--- free chunk data: only free those that arent being copied
- ReleaseChunk(ObjTag);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetObjectMotionByName(const Source: TFile3DS; var DB: TDatabase3DS;
- const Name: string): TKFMesh3DS;
- var
- ObjectChunk: PChunk3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- ObjectChunk := FindNodeTagByNameAndType(Source, DB, Name, OBJECT_NODE_TAG);
- if Assigned(ObjectChunk) then
- Result := GetObjectMotion(Source, ObjectChunk);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetObjectMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: cardinal): TKFMesh3DS;
- var
- Chunk: PChunk3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- Chunk := FindNodeTagByIndexAndType(Source, DB, Index, OBJECT_NODE_TAG);
- if Assigned(Chunk) then
- Result := GetObjectMotion(Source, Chunk);
- end;
- //----------------- Omni Light animation ------------------------------------------------------------------------------
- procedure InitOmnilightMotion(var Light: TKFOmni3DS; NewNPKeys, NewNCKeys: cardinal);
- var
- I: integer;
- begin
- with Light do
- begin
- if Assigned(PKeys) then
- FreeMem(PKeys);
- if Assigned(Pos) then
- FreeMem(Pos);
- if Assigned(CKeys) then
- FreeMem(CKeys);
- if Assigned(Color) then
- FreeMem(Color);
- FillChar(Light, SizeOf(Light), 0);
- NPKeys := NewNPKeys;
- NCKeys := NewNCKeys;
- if NPKeys <> 0 then
- begin
- NPFlag := TrackSingle3DS;
- PKeys := AllocMem(NPKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NPKeys - 1 do
- PKeys^[I] := DefKeyHeader3DS;
- Pos := AllocMem(NPKeys * SizeOf(TPoint3DS));
- for I := 0 to NPKeys - 1 do
- Pos^[I] := DefPoint3DS;
- end;
- if NCKeys <> 0 then
- begin
- NCFlag := TrackSingle3DS;
- CKeys := AllocMem(NCKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NCKeys - 1 do
- CKeys^[I] := DefKeyHeader3DS;
- Color := AllocMem(NCKeys * SizeOf(TFColor3DS));
- for I := 0 to NCKeys - 1 do
- begin
- Color^[I].R := 1;
- Color^[I].G := 1;
- Color^[I].B := 1;
- end;
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure ReleaseOmnilightMotion(Light: PKFOmni3DS);
- begin
- if Assigned(Light) then
- begin
- with Light^ do
- begin
- if Assigned(PKeys) then
- FreeMem(PKeys);
- if Assigned(Pos) then
- FreeMem(Pos);
- if Assigned(CKeys) then
- FreeMem(CKeys);
- if Assigned(Color) then
- FreeMem(Color);
- end;
- Dispose(Light);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetOmnilightNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): cardinal;
- begin
- Result := GetGenericNodeCount(Source, DB, LIGHT_NODE_TAG);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure GetOmnilightNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
- List: TStringList);
- begin
- GetGenericNodeNameList(Source, DB, LIGHT_NODE_TAG, List);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetOmnilightMotion(const Source: TFile3DS; OmniChunk: PChunk3DS): TKFOmni3DS;
- // Gets Omnilight keyframe information from chunk
- // L_TARGET
- // NODE_ID
- // NODE_HDR
- // APP_DATA
- // POS_TRACK
- // COL_TRACK
- // HOT_TRACK
- // FALL_TRACK
- // ROLL_TRACK
- var
- NodeHdrChunk, PosChunk, ColChunk: PChunk3DS;
- PosKeys, ColKeys: cardinal;
- begin
- PosKeys := 0;
- ColKeys := 0;
- // get information from chunks
- // search children of OmniLight chunk
- NodeHdrChunk := FindChunk(OmniChunk, NODE_HDR);
- PosChunk := FindChunk(OmniChunk, POS_TRACK_TAG);
- ColChunk := FindChunk(OmniChunk, COL_TRACK_TAG);
- Source.ReadChunkData(NodeHdrChunk);
- if Assigned(PosChunk) then
- begin
- Source.ReadChunkData(PosChunk);
- PosKeys := PosChunk^.Data.PosTrackTag^.TrackHdr.KeyCount;
- end;
- if Assigned(ColChunk) then
- begin
- Source.ReadChunkData(ColChunk);
- ColKeys := ColChunk^.Data.ColTrackTag^.TrackHdr.KeyCount;
- end;
- // set-up and fill-in the TKFOmni3DS structure
- FillChar(Result, SizeOf(Result), $00);
- InitOmnilightMotion(Result, PosKeys, ColKeys);
- with Result do
- begin
- //--- Header Information
- Name := ansistring(NodeHdrChunk^.Data.NodeHdr^.ObjNameStr);
- Flags1 := NodeHdrChunk^.Data.NodeHdr^.Flags1;
- Flags2 := NodeHdrChunk^.Data.NodeHdr^.Flags2;
- Parent := ansistring(GetParentName(Source, NodeHdrChunk));
- //--- Position Information
- if PosKeys <> 0 then
- begin
- NPFlag := PosChunk^.Data.PosTrackTag^.TrackHdr.Flags;
- Move(PosChunk^.Data.PosTrackTag^.KeyHdrList^, PKeys^, PosKeys *
- SizeOf(TKeyHeader3DS));
- Move(PosChunk^.Data.PosTrackTag^.PositionList^, Pos^, PosKeys * SizeOf(TPoint3DS));
- end;
- //--- Color Information
- if ColKeys <> 0 then
- begin
- NCFlag := PosChunk^.Data.ColTrackTag^.TrackHdr.Flags;
- Move(ColChunk^.Data.ColTrackTag^.KeyHdrList^, CKeys^, ColKeys *
- SizeOf(TKeyHeader3DS));
- Move(ColChunk^.Data.ColTrackTag^.ColorList^, Color^, ColKeys * SizeOf(TFColor3DS));
- end;
- //--- Free Chunk Data
- if Assigned(NodeHdrChunk) then
- FreeChunkData(NodeHdrChunk);
- if Assigned(PosChunk) then
- FreeChunkData(PosChunk);
- if Assigned(ColChunk) then
- FreeChunkData(ColChunk);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetOmnilightMotionByName(const Source: TFile3DS; var DB: TDatabase3DS;
- const Name: string): TKFOmni3DS;
- var
- Chunk: PChunk3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- Chunk := FindNamedAndTaggedChunk(Source, DB, Name, LIGHT_NODE_TAG);
- if Assigned(Chunk) then
- Result := GetOmnilightMotion(Source, Chunk);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetOmnilightMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: cardinal): TKFOmni3DS;
- var
- Chunk: PChunk3DS;
- List: TStringList;
- begin
- FillChar(Result, SizeOf(Result), 0);
- List := TStringList.Create;
- try
- GetOmnilightNodeNameList(Source, DB, List);
- if Index < cardinal(List.Count) then
- begin
- Chunk := FindNamedAndTaggedChunk(Source, DB, List[Index], LIGHT_NODE_TAG);
- if Assigned(Chunk) then
- Result := GetOmnilightMotion(Source, Chunk);
- end;
- finally
- List.Free;
- end;
- end;
- //----------------- Spot Light animation ------------------------------------------------------------------------------
- procedure InitSpotlightMotion(var Spot: TKFSpot3DS;
- NewNPKeys, // Number of position keys
- NewNCKeys, // Number of Color keys
- NewNHKeys, // Number of hot spot angle keys
- NewNFKeys, // Number of falloff angle keys
- NewNRKeys, // Number of roll keys
- NewNTKeys: cardinal); // Number of target position keys
- var
- I: cardinal;
- begin
- with Spot do
- begin
- if Assigned(PKeys) then
- FreeMem(PKeys);
- if Assigned(Pos) then
- FreeMem(Pos);
- if Assigned(CKeys) then
- FreeMem(CKeys);
- if Assigned(Color) then
- FreeMem(Color);
- if Assigned(HKeys) then
- FreeMem(HKeys);
- if Assigned(Hot) then
- FreeMem(Hot);
- if Assigned(FKeys) then
- FreeMem(FKeys);
- if Assigned(Fall) then
- FreeMem(Fall);
- if Assigned(RKeys) then
- FreeMem(RKeys);
- if Assigned(Roll) then
- FreeMem(Roll);
- if Assigned(TKeys) then
- FreeMem(TKeys);
- if Assigned(TPos) then
- FreeMem(TPos);
- FillChar(Spot, SizeOf(Spot), 0);
- NPKeys := NewNPKeys;
- NCKeys := NewNCKeys;
- NFKeys := NewNFKeys;
- NTKeys := NewNTKeys;
- NHKeys := NewNHKeys;
- NRKeys := NewNRKeys;
- //--- POSITION KEYS -----------------------------------------------------
- if NPKeys <> 0 then
- begin
- NPFlag := TrackSingle3DS;
- PKeys := AllocMem(NPKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NPKeys - 1 do
- PKeys^[I] := DefKeyHeader3DS;
- Pos := AllocMem(NPKeys * SizeOf(TPoint3DS));
- for I := 0 to NPKeys - 1 do
- Pos^[I] := DefPoint3DS;
- end;
- //--- Color KEYS ----------------------------------------------------------
- if NCKeys <> 0 then
- begin
- NCFlag := TrackSingle3DS;
- CKeys := AllocMem(NCKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NCKeys - 1 do
- CKeys^[I] := DefKeyHeader3DS;
- Color := AllocMem(NCKeys * SizeOf(TFColor3DS));
- // Initialization is unclear, even the original developers didn't know what's up.
- // They put this part in an '#ifdef LATER #endif' block. ml
- // for I := 0 to NCKeys - 1 do Color[I] := localDColor.bDefFColor3DS;
- end;
- //---Hot-Spot ANGLE KEYS---------------------------------------------------
- if NHKeys <> 0 then
- begin
- NHFlag := TrackSingle3DS;
- HKeys := AllocMem(NHKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NHKeys - 1 do
- HKeys^[I] := DefKeyHeader3DS;
- Hot := AllocMem(NHKeys * SizeOf(single));
- // default Hot Spot ange 90.0 for now, get real value later (1..174.5)
- for I := 0 to NHKeys - 1 do
- Hot^[I] := 90;
- end;
- //---FALLOFF ANGLE KEYS----------------------------------------------------
- if NFKeys <> 0 then
- begin
- NFFlag := TrackSingle3DS;
- FKeys := AllocMem(NFKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NFKeys - 1 do
- FKeys^[I] := DefKeyHeader3DS;
- Fall := AllocMem(NFKeys * SizeOf(single));
- // default falloff ange 90.0 for now, get real value later (1..175)
- for I := 0 to NFKeys - 1 do
- Fall^[I] := 90;
- end;
- //--- Roll KEYS ----------------------------------------------------------
- if NRKeys <> 0 then
- begin
- NRFlag := TrackSingle3DS;
- RKeys := AllocMem(NRKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NRKeys - 1 do
- RKeys^[I] := DefKeyHeader3DS;
- Roll := AllocMem(NRKeys * SizeOf(single));
- for I := 0 to NRKeys - 1 do
- Roll^[I] := 0;
- end;
- //---L_TARGET Pos KEYS ------------------------------------------------
- if NTKeys <> 0 then
- begin
- NTFlag := TrackSingle3DS;
- TKeys := AllocMem(NTKeys * SizeOf(TKeyHeader3DS));
- for I := 0 to NTKeys - 1 do
- TKeys^[I] := DefKeyHeader3DS;
- TPos := AllocMem(NTKeys * SizeOf(TPoint3DS));
- // default target position, 0, 0, 0 sjw fix later if necessary
- for I := 0 to NTKeys - 1 do
- TPos^[I] := DefPoint3DS;
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure ReleaseSpotlightMotion(Spot: PKFSpot3DS);
- begin
- if Assigned(Spot) then
- begin
- with Spot^ do
- begin
- if Assigned(PKeys) then
- FreeMem(PKeys);
- if Assigned(Pos) then
- FreeMem(Pos);
- if Assigned(CKeys) then
- FreeMem(CKeys);
- if Assigned(Color) then
- FreeMem(Color);
- if Assigned(HKeys) then
- FreeMem(HKeys);
- if Assigned(Hot) then
- FreeMem(Hot);
- if Assigned(FKeys) then
- FreeMem(FKeys);
- if Assigned(Fall) then
- FreeMem(Fall);
- if Assigned(RKeys) then
- FreeMem(RKeys);
- if Assigned(Roll) then
- FreeMem(Roll);
- if Assigned(TKeys) then
- FreeMem(TKeys);
- if Assigned(TPos) then
- FreeMem(TPos);
- end;
- Dispose(Spot);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetSpotlightNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): cardinal;
- begin
- Result := GetGenericNodeCount(Source, DB, SPOTLIGHT_NODE_TAG);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- procedure GetSpotlightNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
- List: TStringList);
- begin
- GetGenericNodeNameList(Source, DB, SPOTLIGHT_NODE_TAG, List);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetSpotlightMotion(const Source: TFile3DS;
- SpotChunk, TargetChunk: PChunk3DS): TKFSpot3DS;
- // gets Spotlight keyframe information from chunk
- // L_TARGET
- // ...
- // NODE_HDR
- // APP_DATA
- // POS_TRACK
- // COL_TRACK
- // HOT_TRACK
- // FALL_TRACK
- // ROLL_TRACK
- var
- NodeHdrChunk, PosChunk, ColChunk, TargetPosChunk, HotChunk,
- FallChunk, RollChunk, TargetHdrChunk: PChunk3DS;
- PosKeys, ColKeys, HotKeys, FallKeys, RollKeys, TargetKeys: cardinal;
- begin
- TargetPosChunk := nil;
- TargetHdrChunk := nil;
- PosKeys := 0;
- ColKeys := 0;
- HotKeys := 0;
- FallKeys := 0;
- RollKeys := 0;
- TargetKeys := 0;
- // get information from chunks
- // search children of Spotlight chunk
- NodeHdrChunk := FindChunk(SpotChunk, NODE_HDR);
- PosChunk := FindChunk(SpotChunk, POS_TRACK_TAG);
- ColChunk := FindChunk(SpotChunk, COL_TRACK_TAG);
- HotChunk := FindChunk(SpotChunk, HOT_TRACK_TAG);
- FallChunk := FindChunk(SpotChunk, FALL_TRACK_TAG);
- RollChunk := FindChunk(SpotChunk, ROLL_TRACK_TAG);
- Source.ReadChunkData(NodeHdrChunk);
- if Assigned(PosChunk) then
- begin
- Source.ReadChunkData(PosChunk);
- PosKeys := PosChunk^.Data.PosTrackTag^.TrackHdr.KeyCount;
- end;
- if Assigned(ColChunk) then
- begin
- Source.ReadChunkData(ColChunk);
- ColKeys := ColChunk^.Data.ColTrackTag^.TrackHdr.KeyCount;
- end;
- if Assigned(HotChunk) then
- begin
- Source.ReadChunkData(HotChunk);
- HotKeys := HotChunk^.Data.HotTrackTag^.TrackHdr.KeyCount;
- end;
- if Assigned(FallChunk) then
- begin
- Source.ReadChunkData(FallChunk);
- FallKeys := FallChunk^.Data.FallTrackTag^.TrackHdr.KeyCount;
- end;
- if Assigned(RollChunk) then
- begin
- Source.ReadChunkData(RollChunk);
- RollKeys := RollChunk^.Data.RollTrackTag^.TrackHdr.KeyCount;
- end;
- if Assigned(TargetChunk) then
- begin
- TargetHdrChunk := FindChunk(TargetChunk, NODE_HDR);
- if Assigned(TargetHdrChunk) then
- Source.ReadChunkData(TargetHdrChunk);
- TargetPosChunk := FindChunk(TargetChunk, POS_TRACK_TAG);
- if Assigned(TargetPosChunk) then
- begin
- Source.ReadChunkData(TargetPosChunk);
- TargetKeys := TargetPosChunk^.Data.PosTrackTag^.TrackHdr.KeyCount;
- end;
- end;
- // set-up and fill-in the TKFSpot3DS structure
- InitSpotlightMotion(Result, PosKeys, ColKeys, HotKeys, FallKeys, RollKeys, TargetKeys);
- with Result do
- begin
- // header Information
- Name := ansistring(NodeHdrChunk^.Data.NodeHdr^.ObjNameStr);
- Flags1 := NodeHdrChunk^.Data.NodeHdr^.Flags1;
- Flags2 := NodeHdrChunk^.Data.NodeHdr^.Flags2;
- // get parent name if there is one
- Parent := ansistring(GetParentName(Source, NodeHdrChunk));
- TParent := ansistring(GetParentName(Source, TargetHdrChunk));
- if Assigned(TargetHdrChunk) then
- begin
- TFlags1 := TargetHdrChunk^.Data.NodeHdr^.Flags1;
- TFlags2 := TargetHdrChunk^.Data.NodeHdr^.Flags2;
- end
- else
- begin
- TFlags1 := 0;
- TFlags2 := 0;
- end;
- // target information
- if TargetKeys <> 0 then
- begin
- NTFlag := TargetPosChunk^.Data.PosTrackTag^.TrackHdr.Flags;
- Move(TargetPosChunk^.Data.PosTrackTag^.KeyHdrList^, TKeys^,
- TargetKeys * SizeOf(TKeyHeader3DS));
- Move(TargetPosChunk^.Data.PosTrackTag^.PositionList^, TPos^,
- TargetKeys * SizeOf(TPoint3DS));
- end;
- // position information
- if PosKeys <> 0 then
- begin
- NPFlag := PosChunk^.Data.PosTrackTag^.TrackHdr.Flags;
- Move(PosChunk^.Data.PosTrackTag^.KeyHdrList^, PKeys^, PosKeys *
- SizeOf(TKeyHeader3DS));
- Move(PosChunk^.Data.PosTrackTag^.PositionList^, Pos^, PosKeys * SizeOf(TPoint3DS));
- end;
- // color information
- if ColKeys <> 0 then
- begin
- NCFlag := ColChunk^.Data.ColTrackTag^.TrackHdr.Flags;
- Move(ColChunk^.Data.ColTrackTag^.KeyHdrList^, CKeys^, ColKeys *
- SizeOf(TKeyHeader3DS));
- Move(ColChunk^.Data.ColTrackTag^.ColorList^, Color^, ColKeys * SizeOf(TFColor3DS));
- end;
- // hot spot information
- if HotKeys <> 0 then
- begin
- NHFlag := HotChunk^.Data.HotTrackTag^.TrackHdr.Flags;
- Move(HotChunk^.Data.HotTrackTag^.KeyHdrList^, HKeys^, HotKeys *
- SizeOf(TKeyHeader3DS));
- Move(HotChunk^.Data.HotTrackTag^.HotSpotAngleList^, Hot^, HotKeys *
- SizeOf(single));
- end;
- // falloff information
- if FallKeys <> 0 then
- begin
- NFFlag := FallChunk^.Data.FallTrackTag^.TrackHdr.Flags;
- Move(FallChunk^.Data.FallTrackTag^.KeyHdrList^, FKeys^, FallKeys *
- SizeOf(TKeyHeader3DS));
- Move(FallChunk^.Data.FallTrackTag^.FallOffAngleList^, Fall^,
- FallKeys * SizeOf(single));
- end;
- // roll track Information
- if RollKeys <> 0 then
- begin
- NRFlag := RollChunk^.Data.RollTrackTag^.TrackHdr.Flags;
- Move(RollChunk^.Data.RollTrackTag^.KeyHdrList^, RKeys^, RollKeys *
- SizeOf(TKeyHeader3DS));
- Move(RollChunk^.Data.RollTrackTag^.RollAngleList^, Roll^,
- RollKeys * SizeOf(single));
- end;
- end;
- //--- Free Chunk Data
- if Assigned(NodeHdrChunk) then
- FreeChunkData(NodeHdrChunk);
- if Assigned(PosChunk) then
- FreeChunkData(PosChunk);
- if Assigned(ColChunk) then
- FreeChunkData(ColChunk);
- if Assigned(HotChunk) then
- FreeChunkData(HotChunk);
- if Assigned(FallChunk) then
- FreeChunkData(FallChunk);
- if Assigned(RollChunk) then
- FreeChunkData(RollChunk);
- if Assigned(TargetPosChunk) then
- FreeChunkData(TargetPosChunk);
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetSpotlightMotionByName(const Source: TFile3DS; var DB: TDatabase3DS;
- const Name: string): TKFSpot3DS;
- var
- SpotlightChunk, TargetChunk: PChunk3DS;
- begin
- FillChar(Result, SizeOf(Result), 0);
- SpotlightChunk := FindNamedAndTaggedChunk(Source, DB, Name, SPOTLIGHT_NODE_TAG);
- if Assigned(SpotlightChunk) then
- begin
- TargetChunk := FindNamedAndTaggedChunk(Source, DB, Name, L_TARGET_NODE_TAG);
- Result := GetSpotlightMotion(Source, SpotlightChunk, TargetChunk);
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetSpotlightMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
- Index: cardinal): TKFSpot3DS;
- var
- SpotChunk, TargetChunk: PChunk3DS;
- List: TStringList;
- begin
- FillChar(Result, SizeOf(Result), 0);
- List := TStringList.Create;
- try
- GetSpotlightNodeNameList(Source, DB, List);
- if Index < cardinal(List.Count) then
- begin
- SpotChunk := FindNamedAndTaggedChunk(Source, DB, List[Index], SPOTLIGHT_NODE_TAG);
- if Assigned(SpotChunk) then
- begin
- TargetChunk := FindNamedAndTaggedChunk(Source, DB, List[Index],
- L_TARGET_NODE_TAG);
- if Assigned(TargetChunk) then
- Result := GetSpotlightMotion(Source, SpotChunk, TargetChunk);
- end;
- end;
- finally
- List.Free;
- end;
- end;
- //----------------- Versioninformation --------------------------------------------------------------------------------
- function GetM3dMagicRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
- // Scans the database for M3D_VERSION chunk and returnes its release
- var
- Chunk: PChunk3DS;
- begin
- Result := rlReleaseNotKnown;
- // If the database is a 3DS file
- if DB.TopChunk^.Tag = M3DMAGIC then
- begin
- Chunk := FindChunk(DB.TopChunk, M3D_VERSION);
- if Assigned(Chunk) then
- begin
- Source.ReadChunkData(Chunk);
- case Chunk^.Data.M3dVersion^ of
- 1:
- Result := rlRelease1;
- 2:
- Result := rlRelease2;
- 3:
- Result := rlRelease3;
- else
- Result := rlReleaseNotKnown;
- end;
- end;
- end;
- end;
- //---------------------------------------------------------------------------------------------------------------------
- function GetMeshRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
- // Scans the database for MESH_VERSION chunk and returnes its release
- var
- Chunk: PChunk3DS;
- begin
- Result := rlReleaseNotKnown;
- // If the database is a 3DS file
- if (DB.TopChunk^.Tag = M3DMAGIC) or (DB.TopChunk^.Tag = CMAGIC) then
- begin
- Chunk := FindChunk(DB.TopChunk, MESH_VERSION);
- if Assigned(Chunk) then
- begin
- Source.ReadChunkData(Chunk);
- case Chunk^.Data.MeshVersion^ of
- 1:
- Result := rlRelease1;
- 2:
- Result := rlRelease2;
- 3:
- Result := rlRelease3;
- else
- Result := rlReleaseNotKnown;
- end;
- end;
- end;
- end;
- //---------------------------------------------------------------------------
- function GetKfRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
- // Scans the database for KFHDR chunk and returnes its release level
- var
- KFChunk, Chunk: PChunk3DS;
- begin
- Result := rlReleaseNotKnown;
- // If the database is a 3DS file
- if (DB.TopChunk^.Tag = M3DMAGIC) or (DB.TopChunk^.Tag = CMAGIC) then
- begin
- KFChunk := FindChunk(DB.TopChunk, KFDATA);
- if Assigned(KFChunk) then
- Chunk := FindChunk(DB.TopChunk, KFHDR)
- else
- Chunk := nil;
- if Assigned(Chunk) then
- begin
- Source.ReadChunkData(Chunk);
- case Chunk^.Data.KFHdr^.Revision of
- 1:
- Result := rlRelease1;
- 2:
- Result := rlRelease2;
- 3:
- Result := rlRelease3;
- else
- Result := rlReleaseNotKnown;
- end;
- end;
- end;
- end;
- //-----------------------------------------------------------------------------
- function GetDatabaseRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
- begin
- case DB.TopChunk^.Tag of
- M3DMAGIC:
- Result := GetM3dMagicRelease(Source, DB);
- CMAGIC:
- Result := GetMeshRelease(Source, DB);
- MLIBMAGIC:
- Result := rlRelease3;
- else
- Result := rlReleaseNotKnown;
- end;
- end;
- //----------------------------------------------------------------------------
- end.
|