| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793 |
- //
- // This unit is part of the GLScene Engine, http://glscene.org
- //
- unit File3DSUtils;
- (*
- 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,
- File3DS,
- File3DSTypes,
- 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
- //-------------------------------------------------
- uses
- File3DSConst;
- 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.
|