12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791 |
- //
- // The multimedia graphics platform GLScene https://github.com/glscene
- //
- unit Formats.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 GLScene.inc}
- {$R-}
- uses
- System.Classes,
- System.SysUtils,
- Formats.m3DS,
- Formats.m3DSTypes,
- Formats.m3DSConst,
- GLS.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.
|