File3DS.pas 89 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. {
  5. Implementation of an universal 3DS file reader (and writer). This is the main file of the
  6. 3DS import library. Currently only loading of 3DS files (Mesh files * .3ds, Project files * .prj
  7. and Material files * .mli) is supported.
  8. Note: Be careful when using LoadFromStream, because chunk data (in opposition to the
  9. chunk structure) will be loaded on demand, i.e. when it is needed. Therefore the
  10. passed stream must be available during load.
  11. LoadFromStream does not make a copy of the passed stream, but keeps a reference
  12. which must stay valid either during the entire lifetime of TFile3DS or at least
  13. 'til all chunks have been read (by accessing them all once).
  14. }
  15. unit File3DS;
  16. interface
  17. {$I GLScene.inc}
  18. {$ALIGN ON}
  19. {$MINENUMSIZE 4}
  20. {$RANGECHECKS OFF}
  21. uses
  22. System.Classes,
  23. System.SysUtils,
  24. File3DSTypes;
  25. type
  26. TFile3DS = class;
  27. TLoadProgress = procedure(StreamPos, StreamMax: Longint) of object;
  28. // Progress : TProgressBar;
  29. //
  30. // This allows to use something like that:
  31. //
  32. // procedure TSomeForm.CreateForm(Sender: TObject);
  33. // begin
  34. // ....
  35. // 3DSReader.OnProgress := LoadProgress;
  36. // ....
  37. // end;
  38. // procedure TSomeForm.LoadProgress(StreamPos, StreamMax : Longint);
  39. // begin
  40. // if StreamMax <> 0 then
  41. // Progress.MaxValue := StreamMax;
  42. // Progress.Position := StreamPos;
  43. // end;
  44. // ----- support classes -----
  45. // All structure data of a 3DS file is actually held in TFile3DS.FDatabase as a
  46. // tree with lots of links across the various chunks.
  47. // For convinience and speed the data of the chunks is collected into some
  48. // special structures (FMaterialList etc.) and presented to the user
  49. // by the following helper classes:
  50. TMaterialList = class
  51. private
  52. FOwner: TFile3DS;
  53. FLocalList: TList;
  54. function GetCount: Integer;
  55. function GetMaterial(Index: Integer): PMaterial3DS;
  56. function GetMaterialByName(const Name: String): PMaterial3DS;
  57. public
  58. constructor Create(AOwner: TFile3DS); virtual;
  59. destructor Destroy; override;
  60. procedure ClearList;
  61. property Count: Integer read GetCount;
  62. property Material[Index: Integer]: PMaterial3DS read GetMaterial; default;
  63. property MaterialByName[const Name: String]: PMaterial3DS read GetMaterialByName;
  64. end;
  65. TObjectList = class
  66. private
  67. FOwner: TFile3DS;
  68. FMeshList,
  69. FOmniList,
  70. FSpotList,
  71. FCameraList: TList;
  72. function GetCamera(Index: Integer): PCamera3DS;
  73. function GetCamCount: Integer;
  74. function GetMeshObjectCount: Integer;
  75. function GetMesh(Index: Integer): PMesh3DS;
  76. function GetOmniCount: Integer;
  77. function GetOmniLight(Index: Integer): PLight3DS;
  78. function GetSpotCount: Integer;
  79. function GetSpotLight(Index: Integer): PLight3DS;
  80. public
  81. constructor Create(AOwner: TFile3DS); virtual;
  82. destructor Destroy; override;
  83. procedure ClearLists;
  84. property CameraCount: Integer read GetCamCount;
  85. property MeshCount: Integer read GetMeshObjectCount;
  86. property OmniLightCount: Integer read GetOmniCount;
  87. property SpotLightCount: Integer read GetSpotCount;
  88. property Mesh[Index: Integer]: PMesh3DS read GetMesh;
  89. property Camera[Index: Integer]: PCamera3DS read GetCamera;
  90. property OmniLight[Index: Integer]: PLight3DS read GetOmniLight;
  91. property SpotLight[Index: Integer]: PLight3DS read GetSpotLight;
  92. end;
  93. TKeyFramer = class
  94. private
  95. FOwner: TFile3DS;
  96. FMeshMotionList,
  97. FOmniMotionList,
  98. FSpotMotionList,
  99. FCameraMotionList: TList;
  100. FAmbientMotion: PKFAmbient3DS;
  101. function GetAmbientMotion: PKFAmbient3DS;
  102. function GetCameraMotion(Index: Integer): PKFCamera3DS;
  103. function GetCamMotionCount: Integer;
  104. function GetKFSets: TKFSets3DS;
  105. function GetMeshMotionCount: Integer;
  106. function GetMeshMotion(Index: Integer): PKFMesh3DS;
  107. function GetOmniMotionCount: Integer;
  108. function GetOmniLightMotion(Index: Integer): PKFOmni3DS;
  109. function GetSpotMotionCount: Integer;
  110. function GetSpotLightMotion(Index: Integer): PKFSpot3DS;
  111. public
  112. constructor Create(AOwner: TFile3DS); virtual;
  113. destructor Destroy; override;
  114. procedure ClearLists;
  115. property AmbientLightMotion: PKFAmbient3DS read GetAmbientMotion;
  116. property CameraMotionCount: Integer read GetCamMotionCount;
  117. property MeshMotionCount: Integer read GetMeshMotionCount;
  118. property OmniLightMotionCount: Integer read GetOmniMotionCount;
  119. property SpotLightMotionCount: Integer read GetSpotMotionCount;
  120. property MeshMotion[Index: Integer]: PKFMesh3DS read GetMeshMotion; default;
  121. property CameraMotion[Index: Integer]: PKFCamera3DS read GetCameraMotion;
  122. property OmniLightMotion[Index: Integer]: PKFOmni3DS read GetOmniLightMotion;
  123. property Settings: TKFSets3DS read GetKFSets;
  124. property SpotLightMotion[Index: Integer]: PKFSpot3DS read GetSpotLightMotion;
  125. end;
  126. (* The main class that supplies the user with all available data
  127. from a specific 3DS file. The data is currently read only, but the class might be
  128. finished sometime later... *)
  129. TFile3DS = class
  130. private
  131. FNodeList: PNodeList;
  132. FDatabase: TDatabase3DS;
  133. FStream: TStream;
  134. FOwnStream: Boolean;
  135. FMaterialList: TMaterialList;
  136. FObjectList: TObjectList;
  137. FKeyFramer: TKeyFramer;
  138. FFileName: String;
  139. FOnLoadProgress: TLoadProgress;
  140. function GetAtmosphereData: TAtmosphere3DS;
  141. function GetBackgroundData: TBackground3DS;
  142. function GetDatabaseType: TDBType3DS;
  143. function GetMeshSettings: TMeshSet3DS;
  144. function GetViewportData: TViewport3DS;
  145. function GetDatabaseRelease: TReleaseLevel;
  146. function GetMeshRelease: TReleaseLevel;
  147. protected
  148. procedure AddToNodeList(Chunk: PChunk3DS);
  149. procedure AssignParentNames;
  150. procedure CheckListNodeIDs;
  151. procedure CreateDatabase;
  152. function FindNodeByID(ID: SmallInt): PNodeList;
  153. function GetChunkNodeID(Chunk: PChunk3DS): SmallInt;
  154. procedure InitDatabase;
  155. function IsNode(Tag: Word): Boolean;
  156. procedure KFAddParentName(Chunk: PChunk3DS; const Name: String3DS);
  157. procedure MakeNode(var Node: PNodeList);
  158. procedure ParseDatabase;
  159. procedure ReadChildren(Parent: PChunk3DS);
  160. procedure ReadXDataEntryChildren(Parent: PChunk3DS);
  161. procedure ReleaseDatabase;
  162. procedure ReleaseNodeList;
  163. procedure ReleaseStream;
  164. public
  165. constructor Create; virtual;
  166. constructor CreateFromFile(const FileName: String); virtual;
  167. destructor Destroy; override;
  168. procedure ClearLists;
  169. // database methods
  170. procedure DumpDataBase(Strings: TStrings; DumpLevel: TDumpLevel);
  171. procedure LoadFromFile(const FileName: String);
  172. procedure LoadFromStream(const aStream: TStream);
  173. // basic access methods
  174. function ReadByte: Byte;
  175. function ReadCardinal: Cardinal;
  176. procedure ReadChunkData(Chunk: PChunk3DS);
  177. procedure ReadData(Size: Integer; Data: Pointer);
  178. function ReadDouble: Double;
  179. function ReadFace: TFace3DS;
  180. procedure ReadHeader(var ChunkType: Word; var ChunkSize: Cardinal);
  181. function ReadInteger: Integer;
  182. function ReadKeyHeader: TKeyHeader3DS;
  183. function ReadPoint: TPoint3DS;
  184. function ReadShort: SmallInt;
  185. function ReadSingle: Single;
  186. function ReadString: PChar3DS;
  187. function ReadTexVert: TTexVert3DS;
  188. function ReadTrackHeader: TTrackHeader3DS;
  189. function ReadWord: Word;
  190. procedure FinishHeader(StartPos, EndPos: Cardinal);
  191. function InitChunkData(Chunk: PChunk3DS): Pointer;
  192. procedure SeekChild(Chunk: PChunk3DS);
  193. procedure Skip(AValue: Integer);
  194. procedure WriteByte(AValue: Byte);
  195. procedure WriteCardinal(AValue: Cardinal);
  196. procedure WriteData(Size: Integer; Data: Pointer);
  197. procedure WriteDouble(AValue: Double);
  198. procedure WriteFace(const F: TFace3DS);
  199. procedure WriteFixedString(const AValue: String3DS; Len: Integer);
  200. procedure WriteHeader(ChunkType: Word; ChunkSize: Cardinal);
  201. procedure WriteInteger(AValue: Integer);
  202. procedure WriteKeyHeader(const K: TKeyHeader3DS);
  203. procedure WritePoint(const P: TPoint3DS);
  204. procedure WriteShort(AValue: SmallInt);
  205. procedure WriteSingle(AValue: Single);
  206. procedure WriteString(const AValue: String3DS);
  207. procedure WriteTexVertex(const T: TTexVert3DS);
  208. procedure WriteTrackHeader(const T: TTrackHeader3DS);
  209. procedure WriteWord(AValue: Word);
  210. property Atmosphere: TAtmosphere3DS read GetAtmosphereData;
  211. property Background: TBackground3DS read GetBackgroundData;
  212. property DatabaseRelease: TReleaseLevel read GetDatabaseRelease;
  213. property DatabaseType: TDBType3DS read GetDatabaseType;
  214. property FileName: String read FFileName;
  215. // this is only valid if loaded from a file
  216. property KeyFramer: TKeyFramer read FKeyFramer;
  217. property Materials: TMaterialList read FMaterialList;
  218. property MeshRelease: TReleaseLevel read GetMeshRelease;
  219. property MeshSettings: TMeshSet3DS read GetMeshSettings;
  220. property Objects: TObjectList read FObjectList;
  221. property Viewport: TViewport3DS read GetViewportData;
  222. property OnLoadProgress: TLoadProgress read FOnLoadProgress write FOnLoadProgress;
  223. end;
  224. // ---------------------------------------------------------------------------------------------------------------------
  225. implementation
  226. // ---------------------------------------------------------------------------------------------------------------------
  227. uses
  228. File3DSConst,
  229. File3DSUtils,
  230. GLApplicationFileIO;
  231. function StrPasFree(P: PChar3DS): String;
  232. begin
  233. Result := string(StrPas(P));
  234. FreeMem(P);
  235. end;
  236. // ----------------- TMaterialList -------------------------------------------------------------------------------------
  237. constructor TMaterialList.Create(AOwner: TFile3DS);
  238. begin
  239. FOwner := AOwner;
  240. FLocalList := TList.Create;
  241. end;
  242. // ---------------------------------------------------------------------------------------------------------------------
  243. destructor TMaterialList.Destroy;
  244. begin
  245. ClearList;
  246. FLocalList.Free;
  247. inherited Destroy;
  248. end;
  249. // ---------------------------------------------------------------------------------------------------------------------
  250. procedure TMaterialList.ClearList;
  251. var
  252. I: Integer;
  253. Mat: PMaterial3DS;
  254. begin
  255. for I := 0 to FLocalList.Count - 1 do
  256. if FLocalList[I] <> nil then
  257. begin
  258. Mat := FLocalList[I];
  259. // free structure data
  260. ReleaseMaterial(Mat);
  261. end;
  262. FLocalList.Count := 0;
  263. end;
  264. // ---------------------------------------------------------------------------------------------------------------------
  265. function TMaterialList.GetCount: Integer;
  266. begin
  267. if (FLocalList.Count = 0) and (FOwner.FDatabase.MatListDirty) then
  268. FLocalList.Count := GetMaterialCount(FOwner, FOwner.FDatabase);;
  269. Result := FLocalList.Count;
  270. end;
  271. // ---------------------------------------------------------------------------------------------------------------------
  272. function TMaterialList.GetMaterial(Index: Integer): PMaterial3DS;
  273. var
  274. NewEntry: PMaterial3DS;
  275. begin
  276. Result := nil;
  277. if Count = 0 then
  278. Exit; // force reading the list if it was modified
  279. if FLocalList[Index] = nil then
  280. begin
  281. New(NewEntry);
  282. FillChar(NewEntry^, SizeOf(NewEntry^), 0);
  283. NewEntry^ := GetMaterialByIndex(FOwner, FOwner.FDatabase, Index);
  284. FLocalList[Index] := NewEntry;
  285. end;
  286. Result := FLocalList[Index];
  287. end;
  288. // ---------------------------------------------------------------------------------------------------------------------
  289. function TMaterialList.GetMaterialByName(const Name: String): PMaterial3DS;
  290. var
  291. Entry: PMaterial3DS;
  292. Index: Integer;
  293. begin
  294. Result := nil;
  295. for Index := 0 to Count - 1 do
  296. begin
  297. Entry := GetMaterial(Index);
  298. if Entry = nil then
  299. Continue;
  300. if CompareText(string(Entry.NameStr), Name) = 0 then
  301. begin
  302. Result := Entry;
  303. Break;
  304. end;
  305. end;
  306. end;
  307. // ----------------- TObjectList ---------------------------------------------------------------------------------------
  308. constructor TObjectList.Create(AOwner: TFile3DS);
  309. begin
  310. FOwner := AOwner;
  311. FMeshList := TList.Create;
  312. FOmniList := TList.Create;
  313. FSpotList := TList.Create;
  314. FCameraList := TList.Create;
  315. end;
  316. // ---------------------------------------------------------------------------------------------------------------------
  317. destructor TObjectList.Destroy;
  318. begin
  319. ClearLists;
  320. FMeshList.Free;
  321. FOmniList.Free;
  322. FSpotList.Free;
  323. FCameraList.Free;
  324. inherited Destroy;
  325. end;
  326. // ---------------------------------------------------------------------------------------------------------------------
  327. procedure TObjectList.ClearLists;
  328. var
  329. I: Integer;
  330. begin
  331. for I := 0 to FMeshList.Count - 1 do
  332. ReleaseMeshObj(FMeshList[I]);
  333. FMeshList.Clear;
  334. for I := 0 to FOmniList.Count - 1 do
  335. ReleaseLight(FOmniList[I]);
  336. FOmniList.Clear;
  337. for I := 0 to FSpotList.Count - 1 do
  338. ReleaseLight(FSpotList[I]);
  339. FSpotList.Clear;
  340. for I := 0 to FCameraList.Count - 1 do
  341. ReleaseCamera(FCameraList[I]);
  342. FCameraList.Clear;
  343. end;
  344. // ---------------------------------------------------------------------------------------------------------------------
  345. function TObjectList.GetCamera(Index: Integer): PCamera3DS;
  346. var
  347. NewEntry: PCamera3DS;
  348. begin
  349. Result := nil;
  350. if CameraCount = 0 then
  351. Exit; // force reading the list if it was modified
  352. if FCameraList[Index] = nil then
  353. begin
  354. New(NewEntry);
  355. FillChar(NewEntry^, SizeOf(NewEntry^), 0);
  356. NewEntry^ := GetCameraByIndex(FOwner, FOwner.FDatabase, Index);
  357. FCameraList[Index] := NewEntry;
  358. end;
  359. Result := FCameraList[Index];
  360. end;
  361. // ---------------------------------------------------------------------------------------------------------------------
  362. function TObjectList.GetCamCount: Integer;
  363. begin
  364. if FCameraList.Count = 0 then
  365. FCameraList.Count := GetCameraCount(FOwner, FOwner.FDatabase);
  366. Result := FCameraList.Count;
  367. end;
  368. // ---------------------------------------------------------------------------------------------------------------------
  369. function TObjectList.GetMeshObjectCount: Integer;
  370. begin
  371. if FMeshList.Count = 0 then
  372. FMeshList.Count := GetMeshCount(FOwner, FOwner.FDatabase);
  373. Result := FMeshList.Count;
  374. end;
  375. // ---------------------------------------------------------------------------------------------------------------------
  376. function TObjectList.GetMesh(Index: Integer): PMesh3DS;
  377. var
  378. NewEntry: PMesh3DS;
  379. begin
  380. Result := nil;
  381. if MeshCount = 0 then
  382. Exit; // force reading the list if it was modified
  383. if FMeshList[Index] = nil then
  384. begin
  385. New(NewEntry);
  386. FillChar(NewEntry^, SizeOf(NewEntry^), 0);
  387. NewEntry^ := GetMeshByIndex(FOwner, FOwner.FDatabase, Index);
  388. FMeshList[Index] := NewEntry;
  389. end;
  390. Result := FMeshList[Index];
  391. end;
  392. // ---------------------------------------------------------------------------------------------------------------------
  393. function TObjectList.GetOmniCount: Integer;
  394. begin
  395. if FOmniList.Count = 0 then
  396. FOmniList.Count := GetOmniLightCount(FOwner, FOwner.FDatabase);
  397. Result := FOmniList.Count;
  398. end;
  399. // ---------------------------------------------------------------------------------------------------------------------
  400. function TObjectList.GetOmniLight(Index: Integer): PLight3DS;
  401. var
  402. NewEntry: PLight3DS;
  403. begin
  404. Result := nil;
  405. if OmniLightCount = 0 then
  406. Exit; // force reading the list if it was modified
  407. if FOmniList[Index] = nil then
  408. begin
  409. New(NewEntry);
  410. FillChar(NewEntry^, SizeOf(NewEntry^), 0);
  411. NewEntry^ := GetOmniLightByIndex(FOwner, FOwner.FDatabase, Index);
  412. FOmniList[Index] := NewEntry;
  413. end;
  414. Result := FOmniList[Index];
  415. end;
  416. // ---------------------------------------------------------------------------------------------------------------------
  417. function TObjectList.GetSpotCount: Integer;
  418. begin
  419. if FSpotList.Count = 0 then
  420. FSpotList.Count := GetSpotLightCount(FOwner, FOwner.FDatabase);
  421. Result := FSpotList.Count;
  422. end;
  423. // ---------------------------------------------------------------------------------------------------------------------
  424. function TObjectList.GetSpotLight(Index: Integer): PLight3DS;
  425. var
  426. NewEntry: PLight3DS;
  427. begin
  428. Result := nil;
  429. if SpotLightCount = 0 then
  430. Exit; // force reading the list if it was modified
  431. if FSpotList[Index] = nil then
  432. begin
  433. New(NewEntry);
  434. FillChar(NewEntry^, SizeOf(NewEntry^), 0);
  435. NewEntry^ := GetSpotLightByIndex(FOwner, FOwner.FDatabase, Index);
  436. FSpotList[Index] := NewEntry;
  437. end;
  438. Result := FSpotList[Index];
  439. end;
  440. // ----------------- TKeyFramer ----------------------------------------------------------------------------------------
  441. constructor TKeyFramer.Create(AOwner: TFile3DS);
  442. begin
  443. FOwner := AOwner;
  444. FMeshMotionList := TList.Create;
  445. FOmniMotionList := TList.Create;
  446. FSpotMotionList := TList.Create;
  447. FCameraMotionList := TList.Create;
  448. end;
  449. // ---------------------------------------------------------------------------------------------------------------------
  450. destructor TKeyFramer.Destroy;
  451. begin
  452. ClearLists;
  453. FMeshMotionList.Free;
  454. FOmniMotionList.Free;
  455. FSpotMotionList.Free;
  456. FCameraMotionList.Free;
  457. inherited;
  458. end;
  459. // ---------------------------------------------------------------------------------------------------------------------
  460. function TKeyFramer.GetAmbientMotion: PKFAmbient3DS;
  461. begin
  462. if FAmbientMotion = nil then
  463. begin
  464. New(FAmbientMotion);
  465. FillChar(FAmbientMotion^, SizeOf(FAmbientMotion^), 0);
  466. FAmbientMotion^ := GetAmbientLightMotion(FOwner, FOwner.FDatabase);
  467. end;
  468. Result := FAmbientMotion;
  469. end;
  470. // ---------------------------------------------------------------------------------------------------------------------
  471. function TKeyFramer.GetCameraMotion(Index: Integer): PKFCamera3DS;
  472. var
  473. NewEntry: PKFCamera3DS;
  474. begin
  475. Result := nil;
  476. if CameraMotionCount = 0 then
  477. Exit; // force reading the list if it was modified
  478. if FCameraMotionList[Index] = nil then
  479. begin
  480. New(NewEntry);
  481. FillChar(NewEntry^, SizeOf(NewEntry^), 0);
  482. NewEntry^ := GetCameraMotionByIndex(FOwner, FOwner.FDatabase, Index);
  483. FCameraMotionList[Index] := NewEntry;
  484. end;
  485. Result := FCameraMotionList[Index];
  486. end;
  487. // ---------------------------------------------------------------------------------------------------------------------
  488. function TKeyFramer.GetCamMotionCount: Integer;
  489. begin
  490. if FCameraMotionList.Count = 0 then
  491. FCameraMotionList.Count := GetCameraNodeCount(FOwner, FOwner.FDatabase);
  492. Result := FCameraMotionList.Count;
  493. end;
  494. // ---------------------------------------------------------------------------------------------------------------------
  495. function TKeyFramer.GetKFSets: TKFSets3DS;
  496. begin
  497. Result := GetKFSettings(FOwner, FOwner.FDatabase);
  498. end;
  499. // ---------------------------------------------------------------------------------------------------------------------
  500. function TKeyFramer.GetMeshMotionCount: Integer;
  501. begin
  502. if FMeshMotionList.Count = 0 then
  503. FMeshMotionList.Count := GetObjectNodeCount(FOwner, FOwner.FDatabase);
  504. Result := FMeshMotionList.Count;
  505. end;
  506. // ---------------------------------------------------------------------------------------------------------------------
  507. function TKeyFramer.GetMeshMotion(Index: Integer): PKFMesh3DS;
  508. var
  509. NewEntry: PKFMesh3DS;
  510. begin
  511. Result := nil;
  512. if MeshMotionCount = 0 then
  513. Exit; // force reading the list if it was modified
  514. if FMeshMotionList[Index] = nil then
  515. begin
  516. New(NewEntry);
  517. FillChar(NewEntry^, SizeOf(NewEntry^), 0);
  518. NewEntry^ := GetObjectMotionByIndex(FOwner, FOwner.FDatabase, Index);
  519. FMeshMotionList[Index] := NewEntry;
  520. end;
  521. Result := FMeshMotionList[Index];
  522. end;
  523. // ---------------------------------------------------------------------------------------------------------------------
  524. function TKeyFramer.GetOmniMotionCount: Integer;
  525. begin
  526. if FOmniMotionList.Count = 0 then
  527. FOmniMotionList.Count := GetOmniLightNodeCount(FOwner, FOwner.FDatabase);
  528. Result := FOmniMotionList.Count;
  529. end;
  530. // ---------------------------------------------------------------------------------------------------------------------
  531. function TKeyFramer.GetOmniLightMotion(Index: Integer): PKFOmni3DS;
  532. var
  533. NewEntry: PKFOmni3DS;
  534. begin
  535. Result := nil;
  536. if OmniLightMotionCount = 0 then
  537. Exit; // force reading the list if it was modified
  538. if FOmniMotionList[Index] = nil then
  539. begin
  540. New(NewEntry);
  541. FillChar(NewEntry^, SizeOf(NewEntry^), 0);
  542. NewEntry^ := GetOmniLightMotionByIndex(FOwner, FOwner.FDatabase, Index);
  543. FOmniMotionList[Index] := NewEntry;
  544. end;
  545. Result := FOmniMotionList[Index];
  546. end;
  547. // ---------------------------------------------------------------------------------------------------------------------
  548. function TKeyFramer.GetSpotMotionCount: Integer;
  549. begin
  550. if FSpotMotionList.Count = 0 then
  551. FSpotMotionList.Count := GetSpotLightNodeCount(FOwner, FOwner.FDatabase);
  552. Result := FSpotMotionList.Count;
  553. end;
  554. // ---------------------------------------------------------------------------------------------------------------------
  555. function TKeyFramer.GetSpotLightMotion(Index: Integer): PKFSpot3DS;
  556. var
  557. NewEntry: PKFSpot3DS;
  558. begin
  559. Result := nil;
  560. if SpotLightMotionCount = 0 then
  561. Exit; // force reading the list if it was modified
  562. if FSpotMotionList[Index] = nil then
  563. begin
  564. New(NewEntry);
  565. FillChar(NewEntry^, SizeOf(NewEntry^), 0);
  566. NewEntry^ := GetSpotLightMotionByIndex(FOwner, FOwner.FDatabase, Index);
  567. FSpotMotionList[Index] := NewEntry;
  568. end;
  569. Result := FSpotMotionList[Index];
  570. end;
  571. // ---------------------------------------------------------------------------------------------------------------------
  572. procedure TKeyFramer.ClearLists;
  573. var
  574. I: Integer;
  575. begin
  576. for I := 0 to FMeshMotionList.Count - 1 do
  577. ReleaseObjectMotion(FMeshMotionList[I]);
  578. FMeshMotionList.Clear;
  579. for I := 0 to FOmniMotionList.Count - 1 do
  580. ReleaseOmnilightMotion(FOmniMotionList[I]);
  581. FOmniMotionList.Clear;
  582. for I := 0 to FSpotMotionList.Count - 1 do
  583. ReleaseSpotlightMotion(FSpotMotionList[I]);
  584. FSpotMotionList.Clear;
  585. for I := 0 to FCameraMotionList.Count - 1 do
  586. ReleaseCameraMotion(FCameraMotionList[I]);
  587. FCameraMotionList.Clear;
  588. if assigned(FAmbientMotion) then
  589. ReleaseAmbientLightMotion(FAmbientMotion);
  590. FAmbientMotion := nil;
  591. end;
  592. // ----------------- TFile3DS ------------------------------------------------------------------------------------------
  593. constructor TFile3DS.Create;
  594. begin
  595. FMaterialList := TMaterialList.Create(Self);
  596. FObjectList := TObjectList.Create(Self);
  597. FKeyFramer := TKeyFramer.Create(Self);
  598. end;
  599. constructor TFile3DS.CreateFromFile(const FileName: String);
  600. begin
  601. Create;
  602. FFileName := FileName;
  603. FStream := CreateFileStream(FileName, fmOpenRead or fmShareDenyWrite);
  604. InitDatabase;
  605. CreateDatabase;
  606. end;
  607. destructor TFile3DS.Destroy;
  608. begin
  609. FKeyFramer.Free;
  610. FObjectList.Free;
  611. FMaterialList.Free;
  612. ReleaseDatabase;
  613. ReleaseStream;
  614. inherited Destroy;
  615. end;
  616. // ---------------------------------------------------------------------------------------------------------------------
  617. procedure TFile3DS.AddToNodeList(Chunk: PChunk3DS);
  618. // creates a node, put node in list and fill-in structure
  619. var
  620. NewNode: PNodeList;
  621. HdrChunk, InstChunk: PChunk3DS;
  622. begin
  623. MakeNode(NewNode);
  624. if NewNode = nil then
  625. Exit;
  626. HdrChunk := FindChunk(Chunk, NODE_HDR);
  627. if HdrChunk = nil then
  628. Exit;
  629. ReadChunkData(HdrChunk);
  630. if HdrChunk = nil then
  631. Exit;
  632. // fill in node Data
  633. NewNode.Name := HdrChunk.Data.NodeHdr.ObjNameStr;
  634. NewNode.ID := GetChunkNodeID(Chunk);
  635. NewNode.Tag := Chunk.Tag;
  636. NewNode.ParentID := HdrChunk.Data.NodeHdr.ParentIndex;
  637. NewNode.Next := nil;
  638. NewNode.InstStr := '';
  639. // check for instance
  640. if Chunk.Tag = OBJECT_NODE_TAG then
  641. begin
  642. InstChunk := FindChunk(Chunk, INSTANCE_NAME);
  643. if assigned(InstChunk) then
  644. begin
  645. ReadChunkData(InstChunk);
  646. NewNode.InstStr := string(StrPas(InstChunk.Data.InstanceName));
  647. FreeChunkData(InstChunk);
  648. end;
  649. end;
  650. HdrChunk.Data.NodeHdr.ObjNameStr := '';
  651. FreeChunkData(HdrChunk);
  652. end;
  653. // ---------------------------------------------------------------------------------------------------------------------
  654. procedure TFile3DS.AssignParentNames;
  655. // traverse keyframe data and assign parent names to its own chunk PARENT_NAME
  656. // which is a child of NODE_HDR
  657. var
  658. Chunk, KfDataChunk, HdrChunk, NameChunk, IdChunk: PChunk3DS;
  659. I: Integer;
  660. IDNode, IDParentNode: PNodeList;
  661. Name, Inst: String3DS;
  662. begin
  663. KfDataChunk := FindChunk(FDatabase.TopChunk, KFDATA);
  664. if KfDataChunk = nil then
  665. Exit;
  666. // Find chunks in KFRAMER
  667. for I := 1 to NodeTagCount do
  668. begin
  669. Chunk := FindChunk(KfDataChunk, NodeTags[I]);
  670. while assigned(Chunk) do
  671. begin
  672. HdrChunk := FindChunk(Chunk, NODE_HDR);
  673. if assigned(HdrChunk) then
  674. begin
  675. IdChunk := FindChunk(Chunk, NODE_ID);
  676. if assigned(IdChunk) then
  677. begin
  678. ReadChunkData(IdChunk);
  679. if assigned(IdChunk.Data.KFID) then
  680. begin
  681. // Find table entry for node of interest
  682. IDNode := FindNodeByID(IdChunk.Data.KFID^);
  683. // no ID (bad) or no parent (ok)
  684. if assigned(IDNode) and (IDNode.ParentID <> -1) then
  685. begin
  686. // find table entry for parent
  687. IDParentNode := FindNodeByID(IDNode.ParentID);
  688. if assigned(IDParentNode) then
  689. begin
  690. Name := UTF8String(IDParentNode.Name);
  691. Inst := UTF8String(IDParentNode.InstStr);
  692. end;
  693. if Length(Name) > 0 then
  694. begin
  695. // concatenate names if there is an inst name
  696. if Length(Inst) > 0 then
  697. Name := Name + '.' + Inst;
  698. // if PARENT chunk exists, copy into it
  699. NameChunk := FindChunk(HdrChunk, PARENT_NAME);
  700. if assigned(NameChunk) then
  701. begin
  702. ReadChunkData(NameChunk);
  703. if assigned(NameChunk.Data.InstanceName) then
  704. begin
  705. NameChunk.Data.InstanceName := AllocMem(Length(Name) + 1);
  706. Move(Name[1], NameChunk.Data.InstanceName^, Length(Name) + 1);
  707. end;
  708. end
  709. else
  710. KFAddParentName(HdrChunk, Name); // creates PARENT_NAME chunk
  711. end;
  712. end;
  713. end;
  714. end;
  715. end;
  716. Chunk := FindNextChunk(Chunk.Sibling, NodeTags[I]);
  717. end;
  718. end;
  719. end;
  720. // ---------------------------------------------------------------------------------------------------------------------
  721. procedure TFile3DS.CheckListNodeIDs;
  722. // Earlier versions (pre 3) of 3dStudio had no node ids, they simply used the order
  723. // in which they came along, if so put in NODE IDs. Assuming that if one node
  724. // has no ID the whole list get renumbered.
  725. var
  726. ID: PNodeList;
  727. Index: SmallInt;
  728. begin
  729. ID := FNodeList;
  730. while assigned(ID) do
  731. begin
  732. if (ID.ID = KNoID) then // if somebody has no ID renumber list
  733. begin
  734. Index := 0;
  735. ID := FNodeList;
  736. while assigned(ID) do
  737. begin
  738. ID.ID := Index;
  739. Inc(Index);
  740. ID := ID.Next;
  741. end;
  742. Break;
  743. end;
  744. ID := ID.Next;
  745. end;
  746. end;
  747. // ---------------------------------------------------------------------------------------------------------------------
  748. function TFile3DS.FindNodeByID(ID: SmallInt): PNodeList;
  749. begin
  750. Result := FNodeList;
  751. while assigned(Result) do
  752. begin
  753. if Result.ID = ID then
  754. Break;
  755. Result := Result.Next;
  756. end;
  757. end;
  758. // ---------------------------------------------------------------------------------------------------------------------
  759. procedure TFile3DS.DumpDataBase(Strings: TStrings; DumpLevel: TDumpLevel);
  760. // dumps entire database into the given string class
  761. var
  762. OldSeparator: Char;
  763. begin
  764. OldSeparator := FormatSettings.DecimalSeparator;
  765. FormatSettings.DecimalSeparator := '.';
  766. try
  767. if Assigned(FDatabase.TopChunk) then
  768. DumpChunk(Self, Strings, FDatabase.TopChunk, 0, DumpLevel);
  769. finally
  770. FormatSettings.DecimalSeparator := OldSeparator;
  771. end;
  772. end;
  773. // ---------------------------------------------------------------------------------------------------------------------
  774. function TFile3DS.GetChunkNodeID(Chunk: PChunk3DS): SmallInt;
  775. var
  776. IdChunk: PChunk3DS;
  777. begin
  778. Result := KNoID;
  779. IdChunk := FindChunk(Chunk, NODE_ID);
  780. if assigned(IdChunk) then
  781. begin
  782. ReadChunkData(IdChunk);
  783. if assigned(IdChunk.Data.KFID) then
  784. Result := IdChunk.Data.KFID^;
  785. FreeChunkData(IdChunk);
  786. end;
  787. end;
  788. // ---------------------------------------------------------------------------------------------------------------------
  789. function TFile3DS.IsNode(Tag: Word): Boolean;
  790. var
  791. I: Integer;
  792. begin
  793. Result := False;
  794. for I := 1 to NodeTagCount do
  795. if Tag = NodeTags[I] then
  796. begin
  797. Result := True;
  798. Break;
  799. end;
  800. end;
  801. // ---------------------------------------------------------------------------------------------------------------------
  802. procedure TFile3DS.KFAddParentName(Chunk: PChunk3DS; const Name: String3DS);
  803. var
  804. Temp: PChunk3DS;
  805. begin
  806. InitChunk(Temp);
  807. Temp.Tag := PARENT_NAME;
  808. Temp.Data.Dummy := AllocMem(Length(Name) + 1);
  809. Move(Name[1], Temp.Data.Dummy^, Length(Name) + 1);
  810. AddChildOrdered(Chunk, Temp);
  811. end;
  812. // ---------------------------------------------------------------------------------------------------------------------
  813. procedure TFile3DS.MakeNode(var Node: PNodeList);
  814. // add node to linked list (uninitialized)
  815. var
  816. ID: PNodeList;
  817. begin
  818. ID := FNodeList;
  819. Node := AllocMem(SizeOf(TNodeList));
  820. if assigned(Node) then
  821. begin
  822. // first node ?
  823. if ID = nil then
  824. FNodeList := Node
  825. else // add to list
  826. begin
  827. while assigned(ID.Next) do
  828. ID := ID.Next;
  829. ID.Next := Node;
  830. end;
  831. end;
  832. end;
  833. // ---------------------------------------------------------------------------------------------------------------------
  834. procedure TFile3DS.ParseDatabase;
  835. var
  836. Chunk, KfDataChunk: PChunk3DS;
  837. begin
  838. KfDataChunk := FindChunk(FDatabase.TopChunk, KFDATA);
  839. if assigned(KfDataChunk) then
  840. begin
  841. Chunk := KfDataChunk.Children;
  842. while assigned(Chunk) do
  843. begin
  844. if IsNode(Chunk.Tag) then
  845. AddToNodeList(Chunk);
  846. Chunk := Chunk.Sibling;
  847. end;
  848. CheckListNodeIDs;
  849. end;
  850. end;
  851. // ---------------------------------------------------------------------------------------------------------------------
  852. procedure TFile3DS.ReadXDataEntryChildren(Parent: PChunk3DS);
  853. var
  854. ParentBody: Cardinal;
  855. Child: PChunk3DS;
  856. begin
  857. SeekChild(Parent);
  858. ParentBody := Parent.Position + Parent.Size;
  859. // satisfy the D4 compiler by castíng the (longint) position to a cardinal
  860. while Cardinal(FStream.Position) < ParentBody do
  861. begin
  862. Child := nil;
  863. InitChunk(Child);
  864. Child.Position := FStream.Position;
  865. ReadHeader(Child.Tag, Child.Size);
  866. // Validate the child chunk...
  867. // First, is it a valid header?
  868. case Child.Tag of
  869. XDATA_APPNAME,
  870. XDATA_STRING,
  871. XDATA_FLOAT,
  872. XDATA_DOUBLE,
  873. XDATA_SHORT,
  874. XDATA_LONG,
  875. XDATA_VOID,
  876. XDATA_GROUP,
  877. XDATA_RFU6,
  878. XDATA_RFU5,
  879. XDATA_RFU4,
  880. XDATA_RFU3,
  881. XDATA_RFU2,
  882. XDATA_RFU1:
  883. begin
  884. // second, does the size fit inside the XDATA_ENTRY chunk?
  885. if (Child.Position + Child.Size) <= ParentBody then
  886. begin
  887. // chances are its a good subchunk, so add it in
  888. AddChild(Parent, Child);
  889. ReadXDataEntryChildren(Child);
  890. end
  891. else
  892. ReleaseChunk(Child);
  893. end
  894. else // must not be a valid chunk, seek to the end of the parent then
  895. begin
  896. ReleaseChunk(Child);
  897. FStream.Position := ParentBody;
  898. end;
  899. end;
  900. end;
  901. end;
  902. // ---------------------------------------------------------------------------------------------------------------------
  903. procedure TFile3DS.ReleaseNodeList;
  904. var
  905. Next: PNodeList;
  906. begin
  907. while assigned(FNodeList) do
  908. begin
  909. Next := FNodeList.Next;
  910. Dispose(FNodeList);
  911. FNodeList := Next;
  912. end;
  913. end;
  914. // ReleaseStream
  915. //
  916. procedure TFile3DS.ReleaseStream;
  917. begin
  918. if FOwnStream then
  919. FreeAndNil(FStream)
  920. else
  921. FStream := nil;
  922. FOwnStream := False;
  923. end;
  924. // ---------------------------------------------------------------------------------------------------------------------
  925. procedure TFile3DS.CreateDatabase;
  926. begin
  927. with FDatabase do
  928. begin
  929. InitChunk(TopChunk);
  930. FStream.Position := 0;
  931. ReadHeader(TopChunk.Tag, TopChunk.Size);
  932. // test header to determine whether it is a top level chunk type
  933. if (TopChunk.Tag = M3DMAGIC) or (TopChunk.Tag = CMAGIC) or
  934. (TopChunk.Tag = MLIBMAGIC) then
  935. begin
  936. // gw: set needed max value for ProgressBar
  937. if assigned(FOnLoadProgress) then
  938. FOnLoadProgress(0, FStream.Size);
  939. // read database structure
  940. ReadChildren(TopChunk);
  941. ParseDatabase;
  942. AssignParentNames;
  943. ReleaseNodeList;
  944. end;
  945. end;
  946. end;
  947. // ---------------------------------------------------------------------------------------------------------------------
  948. procedure TFile3DS.InitDatabase;
  949. begin
  950. with FDatabase do
  951. begin
  952. TopChunk := nil;
  953. ObjListDirty := True;
  954. MatListDirty := True;
  955. NodeListDirty := True;
  956. ObjList := nil;
  957. MatList := nil;
  958. NodeList := nil;
  959. end;
  960. end;
  961. // ---------------------------------------------------------------------------------------------------------------------
  962. procedure TFile3DS.ClearLists;
  963. begin
  964. FMaterialList.ClearList;
  965. FObjectList.ClearLists;
  966. FKeyFramer.ClearLists;
  967. ReleaseDatabase;
  968. end;
  969. //
  970. procedure TFile3DS.LoadFromFile(const FileName: String);
  971. begin
  972. ClearLists;
  973. ReleaseStream;
  974. FFileName := FileName;
  975. FStream := CreateFileStream(FileName, fmOpenRead or fmShareDenyWrite);
  976. FOwnStream := True;
  977. InitDatabase;
  978. CreateDatabase;
  979. end;
  980. // LoadFromStream
  981. //
  982. procedure TFile3DS.LoadFromStream(const aStream: TStream);
  983. begin
  984. ReleaseStream;
  985. ClearLists;
  986. FFileName := '';
  987. FStream := aStream;
  988. InitDatabase;
  989. CreateDatabase;
  990. end;
  991. // ---------------------------------------------------------------------------------------------------------------------
  992. function TFile3DS.GetAtmosphereData: TAtmosphere3DS;
  993. begin
  994. Result := GetAtmosphere(Self, FDatabase);
  995. end;
  996. // ---------------------------------------------------------------------------------------------------------------------
  997. function TFile3DS.GetBackgroundData: TBackground3DS;
  998. begin
  999. Result := GetBackground(Self, FDatabase);
  1000. end;
  1001. // ---------------------------------------------------------------------------------------------------------------------
  1002. function TFile3DS.GetDatabaseType: TDBType3DS;
  1003. begin
  1004. case FDatabase.TopChunk.Tag of
  1005. M3DMAGIC:
  1006. Result := dbMeshFile;
  1007. CMAGIC:
  1008. Result := dbProjectFile;
  1009. MLIBMAGIC:
  1010. Result := dbMaterialFile;
  1011. else
  1012. Result := dbUnknown;
  1013. end;
  1014. end;
  1015. // ---------------------------------------------------------------------------------------------------------------------
  1016. function TFile3DS.GetMeshSettings: TMeshSet3DS;
  1017. begin
  1018. Result := GetMeshSet(Self, FDatabase);
  1019. end;
  1020. // ---------------------------------------------------------------------------------------------------------------------
  1021. function TFile3DS.GetViewportData: TViewport3DS;
  1022. begin
  1023. Result := GetViewport(Self, FDatabase);
  1024. end;
  1025. // ---------------------------------------------------------------------------------------------------------------------
  1026. procedure TFile3DS.ReadChildren(Parent: PChunk3DS);
  1027. var
  1028. ParentBody: Integer;
  1029. Child: PChunk3DS;
  1030. begin
  1031. SeekChild(Parent);
  1032. ParentBody := Parent.Position + Parent.Size;
  1033. while FStream.Position < ParentBody do
  1034. begin
  1035. Child := nil;
  1036. InitChunk(Child);
  1037. // gw: set ProgressBar current position
  1038. if assigned(FOnLoadProgress) then
  1039. FOnLoadProgress(FStream.Position, 0);
  1040. Child.Position := FStream.Position;
  1041. ReadHeader(Child.Tag, Child.Size);
  1042. AddChild(Parent, Child);
  1043. if Child.Tag = XDATA_ENTRY then
  1044. ReadXDataEntryChildren(Child)
  1045. else
  1046. ReadChildren(Child);
  1047. end;
  1048. end;
  1049. // ---------------------------------------------------------------------------------------------------------------------
  1050. procedure TFile3DS.ReleaseDatabase;
  1051. begin
  1052. with FDatabase do
  1053. begin
  1054. if assigned(TopChunk) then
  1055. ReleaseChunk(TopChunk);
  1056. if assigned(ObjList) then
  1057. ReleaseChunkList(ObjList);
  1058. if assigned(MatList) then
  1059. ReleaseChunkList(MatList);
  1060. if assigned(NodeList) then
  1061. ReleaseChunkList(NodeList);
  1062. end;
  1063. end;
  1064. // ---------------------------------------------------------------------------------------------------------------------
  1065. function TFile3DS.InitChunkData(Chunk: PChunk3DS): Pointer;
  1066. begin
  1067. case Chunk.Tag of
  1068. COLOR_F:
  1069. Chunk.Data.ColorF := AllocMem(SizeOf(TColorF));
  1070. LIN_COLOR_F:
  1071. Chunk.Data.LinColorF := AllocMem(SizeOf(TLinColorF));
  1072. COLOR_24:
  1073. Chunk.Data.Color24 := AllocMem(SizeOf(TColor24));
  1074. LIN_COLOR_24:
  1075. Chunk.Data.LinColor24 := AllocMem(SizeOf(TLinColor24));
  1076. INT_PERCENTAGE:
  1077. Chunk.Data.IntPercentage := AllocMem(SizeOf(TIntPercentage));
  1078. FLOAT_PERCENTAGE:
  1079. Chunk.Data.FloatPercentage := AllocMem(SizeOf(TFloatPercentage));
  1080. MAT_MAPNAME:
  1081. Chunk.Data.MatMapname := nil; // AllocMem(SizeOf(TMatMapname));
  1082. M3D_VERSION:
  1083. Chunk.Data.M3dVersion := AllocMem(SizeOf(TM3dVersion));
  1084. MESH_VERSION:
  1085. Chunk.Data.MeshVersion := AllocMem(SizeOf(TMeshVersion));
  1086. MASTER_SCALE:
  1087. Chunk.Data.MasterScale := AllocMem(SizeOf(TMasterScale));
  1088. LO_SHADOW_BIAS:
  1089. Chunk.Data.LoShadowBias := AllocMem(SizeOf(TLoShadowBias));
  1090. SHADOW_FILTER:
  1091. Chunk.Data.ShadowFilter := AllocMem(SizeOf(TShadowFilter));
  1092. SHADOW_RANGE:
  1093. Chunk.Data.ShadowRange := AllocMem(SizeOf(TShadowRange));
  1094. HI_SHADOW_BIAS:
  1095. Chunk.Data.HiShadowBias := AllocMem(SizeOf(THiShadowBias));
  1096. RAY_BIAS:
  1097. Chunk.Data.RayBias := AllocMem(SizeOf(TRayBias));
  1098. SHADOW_MAP_SIZE:
  1099. Chunk.Data.ShadowMapSize := AllocMem(SizeOf(TShadowMapSize));
  1100. SHADOW_SAMPLES:
  1101. Chunk.Data.ShadowSamples := AllocMem(SizeOf(TShadowSamples));
  1102. O_CONSTS:
  1103. Chunk.Data.OConsts := AllocMem(SizeOf(TOConsts));
  1104. BIT_MAP:
  1105. Chunk.Data.BitMapName := nil; // AllocMem(SizeOf(TBitMapName));
  1106. V_GRADIENT:
  1107. Chunk.Data.VGradient := AllocMem(SizeOf(TVGradient));
  1108. FOG:
  1109. Chunk.Data.FOG := AllocMem(SizeOf(TFog));
  1110. LAYER_FOG:
  1111. Chunk.Data.LayerFog := AllocMem(SizeOf(TLayerFog));
  1112. DISTANCE_CUE:
  1113. Chunk.Data.DistanceCue := AllocMem(SizeOf(TDistanceCue));
  1114. VIEW_TOP,
  1115. VIEW_BOTTOM,
  1116. VIEW_LEFT,
  1117. VIEW_RIGHT,
  1118. VIEW_FRONT,
  1119. VIEW_BACK:
  1120. Chunk.Data.ViewStandard := AllocMem(SizeOf(TViewStandard));
  1121. VIEW_USER:
  1122. Chunk.Data.ViewUser := AllocMem(SizeOf(TViewUser));
  1123. VIEW_CAMERA:
  1124. Chunk.Data.ViewCamera := nil; // AllocMem(SizeOf(TViewCamera));
  1125. MAT_NAME:
  1126. Chunk.Data.MatName := nil; // AllocMem(SizeOf(TMatName));
  1127. MAT_SHADING:
  1128. Chunk.Data.MatShading := AllocMem(SizeOf(TMatShading));
  1129. MAT_ACUBIC:
  1130. Chunk.Data.MatAcubic := AllocMem(SizeOf(TMatAcubic));
  1131. MAT_SXP_TEXT_DATA,
  1132. MAT_SXP_TEXT2_DATA,
  1133. MAT_SXP_OPAC_DATA,
  1134. MAT_SXP_BUMP_DATA,
  1135. MAT_SXP_SPEC_DATA,
  1136. MAT_SXP_SHIN_DATA,
  1137. MAT_SXP_SELFI_DATA,
  1138. MAT_SXP_TEXT_MASKDATA,
  1139. MAT_SXP_TEXT2_MASKDATA,
  1140. MAT_SXP_OPAC_MASKDATA,
  1141. MAT_SXP_BUMP_MASKDATA,
  1142. MAT_SXP_SPEC_MASKDATA,
  1143. MAT_SXP_SHIN_MASKDATA,
  1144. MAT_SXP_SELFI_MASKDATA,
  1145. MAT_SXP_REFL_MASKDATA,
  1146. PROC_DATA:
  1147. Chunk.Data.IpasData := AllocMem(SizeOf(TIpasData));
  1148. MAT_WIRESIZE:
  1149. Chunk.Data.MatWireSize := AllocMem(SizeOf(TMatWireSize));
  1150. MAT_MAP_TILING:
  1151. Chunk.Data.MatMapTiling := AllocMem(SizeOf(TMatMapTiling));
  1152. MAT_MAP_TEXBLUR:
  1153. Chunk.Data.MatMapTexblur := AllocMem(SizeOf(TMatMapTexblur));
  1154. MAT_MAP_USCALE:
  1155. Chunk.Data.MatMapUScale := AllocMem(SizeOf(TMatMapUScale));
  1156. MAT_MAP_VSCALE:
  1157. Chunk.Data.MatMapVScale := AllocMem(SizeOf(TMatMapVScale));
  1158. MAT_MAP_UOFFSET:
  1159. Chunk.Data.MatMapUOffset := AllocMem(SizeOf(TMatMapUOffset));
  1160. MAT_MAP_VOFFSET:
  1161. Chunk.Data.MatMapVOffset := AllocMem(SizeOf(TMatMapVOffset));
  1162. MAT_MAP_ANG:
  1163. Chunk.Data.MatMapAng := AllocMem(SizeOf(TMatMapAng));
  1164. MAT_MAP_COL1:
  1165. Chunk.Data.MatMapCol1 := AllocMem(SizeOf(TMatMapCol1));
  1166. MAT_MAP_COL2:
  1167. Chunk.Data.MatMapCol2 := AllocMem(SizeOf(TMatMapCol2));
  1168. MAT_MAP_RCOL:
  1169. Chunk.Data.MatMapRCol := AllocMem(SizeOf(TMatMapRCol));
  1170. MAT_MAP_GCOL:
  1171. Chunk.Data.MatMapGCol := AllocMem(SizeOf(TMatMapGCol));
  1172. MAT_MAP_BCOL:
  1173. Chunk.Data.MatMapBCol := AllocMem(SizeOf(TMatMapBCol));
  1174. MAT_BUMP_PERCENT:
  1175. Chunk.Data.MatBumpPercent := AllocMem(SizeOf(TMatBumpPercent));
  1176. NAMED_OBJECT:
  1177. Chunk.Data.NamedObject := nil; // AllocMem(SizeOf(TNamedObject));
  1178. POINT_ARRAY:
  1179. Chunk.Data.PointArray := AllocMem(SizeOf(TPointArray));
  1180. POINT_FLAG_ARRAY:
  1181. Chunk.Data.PointFlagArray := AllocMem(SizeOf(TPointFlagArray));
  1182. FACE_ARRAY:
  1183. Chunk.Data.FaceArray := AllocMem(SizeOf(TFaceArray));
  1184. MSH_MAT_GROUP:
  1185. Chunk.Data.MshMatGroup := AllocMem(SizeOf(TMshMatGroup));
  1186. MSH_BOXMAP:
  1187. Chunk.Data.MshBoxmap := AllocMem(SizeOf(TMshBoxmap));
  1188. SMOOTH_GROUP:
  1189. Chunk.Data.SmoothGroup := AllocMem(SizeOf(TSmoothGroup));
  1190. TEX_VERTS:
  1191. Chunk.Data.TexVerts := AllocMem(SizeOf(TTexVerts));
  1192. MESH_MATRIX:
  1193. Chunk.Data.MeshMatrix := AllocMem(SizeOf(TMeshMatrix));
  1194. MESH_COLOR:
  1195. Chunk.Data.MeshColor := AllocMem(SizeOf(TMeshColor));
  1196. MESH_TEXTURE_INFO:
  1197. Chunk.Data.MeshTextureInfo := AllocMem(SizeOf(TMeshTextureInfo));
  1198. PROC_NAME:
  1199. Chunk.Data.ProcName := nil; // AllocMem(SizeOf(TProcName));
  1200. N_DIRECT_LIGHT:
  1201. Chunk.Data.NDirectLight := AllocMem(SizeOf(TNDirectLight));
  1202. DL_EXCLUDE:
  1203. Chunk.Data.DlExclude := nil; // AllocMem(SizeOf(TDlExclude));
  1204. DL_INNER_RANGE:
  1205. Chunk.Data.DlInnerRange := AllocMem(SizeOf(TDlInnerRange));
  1206. DL_OUTER_RANGE:
  1207. Chunk.Data.DlOuterRange := AllocMem(SizeOf(TDlOuterRange));
  1208. DL_MULTIPLIER:
  1209. Chunk.Data.DlMultiplier := AllocMem(SizeOf(TDlMultiplier));
  1210. DL_SPOTLIGHT:
  1211. Chunk.Data.DlSpotlight := AllocMem(SizeOf(TDlSpotlight));
  1212. DL_LOCAL_SHADOW2:
  1213. Chunk.Data.DlLocalShadow2 := AllocMem(SizeOf(TDlLocalShadow2));
  1214. DL_SPOT_ROLL:
  1215. Chunk.Data.DlSpotRoll := AllocMem(SizeOf(TDlSpotRoll));
  1216. DL_SPOT_ASPECT:
  1217. Chunk.Data.DlSpotAspect := AllocMem(SizeOf(TDlSpotAspect));
  1218. DL_SPOT_PROJECTOR:
  1219. Chunk.Data.DlSpotProjector := nil; // AllocMem(SizeOf(TDlSpotProjector));
  1220. DL_RAY_BIAS:
  1221. Chunk.Data.DlRayBias := AllocMem(SizeOf(TDlRayBias));
  1222. N_CAMERA:
  1223. Chunk.Data.NCamera := AllocMem(SizeOf(TNCamera));
  1224. CAM_RANGES:
  1225. Chunk.Data.CamRanges := AllocMem(SizeOf(TCamRanges));
  1226. VIEWPORT_LAYOUT:
  1227. Chunk.Data.ViewportLayout := AllocMem(SizeOf(TViewportLayout));
  1228. VIEWPORT_SIZE:
  1229. Chunk.Data.ViewportSize := AllocMem(SizeOf(TViewportSize));
  1230. VIEWPORT_DATA_3,
  1231. VIEWPORT_DATA:
  1232. Chunk.Data.ViewportData := AllocMem(SizeOf(TViewportData));
  1233. XDATA_ENTRY:
  1234. Chunk.Data.XDataEntry := AllocMem(SizeOf(TXDataEntry));
  1235. XDATA_APPNAME:
  1236. Chunk.Data.XDataAppName := nil; // AllocMem(SizeOf(TXDataAppName));
  1237. XDATA_STRING:
  1238. Chunk.Data.XDataString := nil; // AllocMem(SizeOf(TXDataString));
  1239. KFHDR:
  1240. Chunk.Data.KFHDR := AllocMem(SizeOf(TKFHdr));
  1241. KFSEG:
  1242. Chunk.Data.KFSEG := AllocMem(SizeOf(TKFSeg));
  1243. KFCURTIME:
  1244. Chunk.Data.KFCURTIME := AllocMem(SizeOf(TKFCurtime));
  1245. NODE_ID:
  1246. Chunk.Data.KFID := AllocMem(SizeOf(TKFId));
  1247. NODE_HDR:
  1248. Chunk.Data.NodeHdr := AllocMem(SizeOf(TNodeHdr));
  1249. PIVOT:
  1250. Chunk.Data.PIVOT := AllocMem(SizeOf(TPivot));
  1251. INSTANCE_NAME, PARENT_NAME:
  1252. Chunk.Data.InstanceName := nil; // AllocMem(SizeOf(TInstanceName));
  1253. MORPH_SMOOTH:
  1254. Chunk.Data.MorphSmooth := AllocMem(SizeOf(TMorphSmooth));
  1255. BOUNDBOX:
  1256. Chunk.Data.BOUNDBOX := AllocMem(SizeOf(TBoundBox));
  1257. POS_TRACK_TAG:
  1258. Chunk.Data.PosTrackTag := AllocMem(SizeOf(TPosTrackTag));
  1259. COL_TRACK_TAG:
  1260. Chunk.Data.ColTrackTag := AllocMem(SizeOf(TColTrackTag));
  1261. ROT_TRACK_TAG:
  1262. Chunk.Data.RotTrackTag := AllocMem(SizeOf(TRotTrackTag));
  1263. SCL_TRACK_TAG:
  1264. Chunk.Data.ScaleTrackTag := AllocMem(SizeOf(TScaleTrackTag));
  1265. MORPH_TRACK_TAG:
  1266. Chunk.Data.MorphTrackTag := AllocMem(SizeOf(TMorphTrackTag));
  1267. FOV_TRACK_TAG:
  1268. Chunk.Data.FovTrackTag := AllocMem(SizeOf(TFovTrackTag));
  1269. ROLL_TRACK_TAG:
  1270. Chunk.Data.RollTrackTag := AllocMem(SizeOf(TRollTrackTag));
  1271. HOT_TRACK_TAG:
  1272. Chunk.Data.HotTrackTag := AllocMem(SizeOf(THotTrackTag));
  1273. FALL_TRACK_TAG:
  1274. Chunk.Data.FallTrackTag := AllocMem(SizeOf(TFallTrackTag));
  1275. HIDE_TRACK_TAG:
  1276. Chunk.Data.HideTrackTag := AllocMem(SizeOf(THideTrackTag));
  1277. M3DMAGIC, // Chunks who consist entirely of children
  1278. MLIBMAGIC,
  1279. MDATA,
  1280. AMBIENT_LIGHT,
  1281. SOLID_BGND,
  1282. DEFAULT_VIEW,
  1283. MAT_ENTRY,
  1284. MAT_AMBIENT,
  1285. MAT_DIFFUSE,
  1286. MAT_SPECULAR,
  1287. MAT_SHININESS,
  1288. MAT_SHIN2PCT,
  1289. MAT_SHIN3PCT,
  1290. MAT_TRANSPARENCY,
  1291. MAT_XPFALL,
  1292. MAT_REFBLUR,
  1293. MAT_SELF_ILPCT,
  1294. MAT_TEXMAP,
  1295. MAT_TEXMASK,
  1296. MAT_TEX2MAP,
  1297. MAT_TEX2MASK,
  1298. MAT_OPACMAP,
  1299. MAT_OPACMASK,
  1300. MAT_REFLMAP,
  1301. MAT_REFLMASK,
  1302. MAT_BUMPMAP,
  1303. MAT_BUMPMASK,
  1304. MAT_SPECMAP,
  1305. MAT_SPECMASK,
  1306. MAT_SHINMAP,
  1307. MAT_SHINMASK,
  1308. MAT_SELFIMAP,
  1309. MAT_SELFIMASK,
  1310. N_TRI_OBJECT,
  1311. KFDATA,
  1312. AMBIENT_NODE_TAG,
  1313. OBJECT_NODE_TAG,
  1314. CAMERA_NODE_TAG,
  1315. TARGET_NODE_TAG,
  1316. LIGHT_NODE_TAG,
  1317. SPOTLIGHT_NODE_TAG,
  1318. L_TARGET_NODE_TAG,
  1319. CMAGIC,
  1320. XDATA_SECTION,
  1321. XDATA_GROUP:
  1322. Chunk.Data.Dummy := nil;
  1323. else // A truely hideous thing to do but it helps with unknown chunks
  1324. // Don't mess with dataless chunks
  1325. if Chunk.Size > 6 then
  1326. Chunk.Data.Dummy := AllocMem(Chunk.Size - 6)
  1327. else
  1328. Chunk.Data.Dummy := nil;
  1329. end; // end of case
  1330. Result := Chunk.Data.Dummy; // returns the pointer should someone want it
  1331. end;
  1332. // ---------------------------------------------------------------------------------------------------------------------
  1333. procedure TFile3DS.WriteByte(AValue: Byte);
  1334. begin
  1335. FStream.WriteBuffer(AValue, 1);
  1336. end;
  1337. // ---------------------------------------------------------------------------------------------------------------------
  1338. function TFile3DS.ReadByte: Byte;
  1339. begin
  1340. FStream.ReadBuffer(Result, 1);
  1341. end;
  1342. // ---------------------------------------------------------------------------------------------------------------------
  1343. procedure TFile3DS.WriteShort(AValue: SmallInt);
  1344. begin
  1345. FStream.WriteBuffer(AValue, SizeOf(AValue));
  1346. end;
  1347. // ---------------------------------------------------------------------------------------------------------------------
  1348. function TFile3DS.ReadShort: SmallInt;
  1349. begin
  1350. FStream.ReadBuffer(Result, SizeOf(Result));
  1351. end;
  1352. // ---------------------------------------------------------------------------------------------------------------------
  1353. function TFile3DS.ReadCardinal: Cardinal;
  1354. begin
  1355. FStream.ReadBuffer(Result, SizeOf(Result));
  1356. end;
  1357. // ---------------------------------------------------------------------------------------------------------------------
  1358. function TFile3DS.ReadDouble: Double;
  1359. begin
  1360. FStream.ReadBuffer(Result, SizeOf(Result));
  1361. end;
  1362. // ---------------------------------------------------------------------------------------------------------------------
  1363. function TFile3DS.ReadInteger: Integer;
  1364. begin
  1365. FStream.ReadBuffer(Result, SizeOf(Result));
  1366. end;
  1367. // ---------------------------------------------------------------------------------------------------------------------
  1368. function TFile3DS.ReadSingle: Single;
  1369. begin
  1370. FStream.ReadBuffer(Result, SizeOf(Result));
  1371. end;
  1372. // ---------------------------------------------------------------------------------------------------------------------
  1373. function TFile3DS.ReadWord: Word;
  1374. begin
  1375. FStream.ReadBuffer(Result, SizeOf(Result));
  1376. end;
  1377. // ---------------------------------------------------------------------------------------------------------------------
  1378. procedure TFile3DS.WriteCardinal(AValue: Cardinal);
  1379. begin
  1380. FStream.WriteBuffer(AValue, SizeOf(AValue));
  1381. end;
  1382. // ---------------------------------------------------------------------------------------------------------------------
  1383. procedure TFile3DS.WriteDouble(AValue: Double);
  1384. begin
  1385. FStream.WriteBuffer(AValue, SizeOf(AValue));
  1386. end;
  1387. // ---------------------------------------------------------------------------------------------------------------------
  1388. procedure TFile3DS.WriteInteger(AValue: Integer);
  1389. begin
  1390. FStream.WriteBuffer(AValue, SizeOf(AValue));
  1391. end;
  1392. // ---------------------------------------------------------------------------------------------------------------------
  1393. procedure TFile3DS.WriteSingle(AValue: Single);
  1394. begin
  1395. FStream.WriteBuffer(AValue, SizeOf(AValue));
  1396. end;
  1397. // ---------------------------------------------------------------------------------------------------------------------
  1398. procedure TFile3DS.WriteWord(AValue: Word);
  1399. begin
  1400. FStream.WriteBuffer(AValue, SizeOf(AValue));
  1401. end;
  1402. // WriteData
  1403. //
  1404. procedure TFile3DS.WriteData(Size: Integer; Data: Pointer);
  1405. begin
  1406. if assigned(Data) then
  1407. FStream.WriteBuffer(Data^, Size);
  1408. end;
  1409. // ReadData
  1410. //
  1411. procedure TFile3DS.ReadData(Size: Integer; Data: Pointer);
  1412. begin
  1413. FStream.ReadBuffer(Data^, Size);
  1414. end;
  1415. // ---------------------------------------------------------------------------------------------------------------------
  1416. procedure TFile3DS.Skip(AValue: Integer);
  1417. begin
  1418. FStream.Seek(soFromCurrent, AValue);
  1419. end;
  1420. // ---------------------------------------------------------------------------------------------------------------------
  1421. procedure TFile3DS.WriteString(const AValue: String3DS);
  1422. begin
  1423. WriteData(Length(AValue), @AValue[1]);
  1424. WriteByte(0); // Write a null on the end of the string
  1425. end;
  1426. // ---------------------------------------------------------------------------------------------------------------------
  1427. procedure TFile3DS.WriteFixedString(const AValue: String3DS; Len: Integer);
  1428. var
  1429. I: Integer;
  1430. begin
  1431. // len is the length of the target string space including null
  1432. WriteString(AValue); // 1 null byte will also be written
  1433. for I := 1 to Len - Length(AValue) - 1 do
  1434. WriteByte(0); // fill the remaining space with nulls
  1435. end;
  1436. // ---------------------------------------------------------------------------------------------------------------------
  1437. function TFile3DS.ReadString: PChar3DS;
  1438. var
  1439. Len, LB: Integer;
  1440. Buffer: String3DS;
  1441. begin
  1442. Len := 0;
  1443. LB := 0;
  1444. repeat
  1445. if Len >= LB then
  1446. begin
  1447. Inc(LB, 50);
  1448. SetLength(Buffer, LB);
  1449. end;
  1450. Inc(Len);
  1451. FStream.Read(Buffer[Len], 1);
  1452. until Buffer[Len] = #0;
  1453. Result := AllocMem(Len);
  1454. Move(Buffer[1], Result^, Len);
  1455. end;
  1456. // ---------------------------------------------------------------------------------------------------------------------
  1457. procedure TFile3DS.WriteHeader(ChunkType: Word; ChunkSize: Cardinal);
  1458. begin
  1459. WriteWord(ChunkType);
  1460. WriteCardinal(ChunkSize);
  1461. end;
  1462. // ---------------------------------------------------------------------------------------------------------------------
  1463. procedure TFile3DS.ReadHeader(var ChunkType: Word; var ChunkSize: Cardinal);
  1464. begin
  1465. ChunkType := ReadWord;
  1466. ChunkSize := ReadCardinal;
  1467. end;
  1468. // ---------------------------------------------------------------------------------------------------------------------
  1469. procedure TFile3DS.FinishHeader(StartPos, EndPos: Cardinal);
  1470. begin
  1471. FStream.Position := StartPos + 2;
  1472. WriteCardinal(EndPos - StartPos);
  1473. FStream.Position := EndPos;
  1474. end;
  1475. // ---------------------------------------------------------------------------------------------------------------------
  1476. procedure TFile3DS.WritePoint(const P: TPoint3DS);
  1477. begin
  1478. WriteSingle(P.X);
  1479. WriteSingle(P.Y);
  1480. WriteSingle(P.Z);
  1481. end;
  1482. // ---------------------------------------------------------------------------------------------------------------------
  1483. function TFile3DS.ReadPoint: TPoint3DS;
  1484. begin
  1485. Result := DefPoint3DS;
  1486. FStream.ReadBuffer(Result, SizeOf(Result));
  1487. end;
  1488. // ---------------------------------------------------------------------------------------------------------------------
  1489. procedure TFile3DS.WriteTexVertex(const T: TTexVert3DS);
  1490. begin
  1491. WriteSingle(T.U);
  1492. WriteSingle(T.V);
  1493. end;
  1494. // ---------------------------------------------------------------------------------------------------------------------
  1495. function TFile3DS.ReadTexVert: TTexVert3DS;
  1496. begin
  1497. Result := DefTextVert3DS;
  1498. Result.U := ReadSingle;
  1499. Result.V := ReadSingle;
  1500. end;
  1501. // ---------------------------------------------------------------------------------------------------------------------
  1502. procedure TFile3DS.WriteFace(const F: TFace3DS);
  1503. begin
  1504. WriteWord(F.v1);
  1505. WriteWord(F.v2);
  1506. WriteWord(F.v3);
  1507. WriteWord(F.flag);
  1508. end;
  1509. // ---------------------------------------------------------------------------------------------------------------------
  1510. function TFile3DS.ReadFace: TFace3DS;
  1511. begin
  1512. Result := DefFace3DS;
  1513. Result.v1 := ReadWord;
  1514. Result.v2 := ReadWord;
  1515. Result.v3 := ReadWord;
  1516. Result.flag := ReadWord;
  1517. end;
  1518. // ---------------------------------------------------------------------------------------------------------------------
  1519. procedure TFile3DS.WriteTrackHeader(const T: TTrackHeader3DS);
  1520. begin
  1521. WriteWord(T.Flags);
  1522. WriteCardinal(T.nu1);
  1523. WriteCardinal(T.nu2);
  1524. WriteCardinal(T.KeyCount);
  1525. end;
  1526. // ---------------------------------------------------------------------------------------------------------------------
  1527. function TFile3DS.ReadTrackHeader: TTrackHeader3DS;
  1528. begin
  1529. Result := DefTrackHeader3DS;
  1530. Result.Flags := ReadWord;
  1531. Result.nu1 := ReadCardinal;
  1532. Result.nu2 := ReadCardinal;
  1533. Result.KeyCount := ReadCardinal;
  1534. end;
  1535. // ---------------------------------------------------------------------------------------------------------------------
  1536. procedure TFile3DS.WriteKeyHeader(const K: TKeyHeader3DS);
  1537. begin
  1538. WriteCardinal(K.time);
  1539. WriteWord(K.rflags);
  1540. if (K.rflags and KeyUsesTension3DS) > 0 then
  1541. WriteSingle(K.tension);
  1542. if (K.rflags and KeyUsesCont3DS) > 0 then
  1543. WriteSingle(K.continuity);
  1544. if (K.rflags and KeyUsesBias3DS) > 0 then
  1545. WriteSingle(K.bias);
  1546. if (K.rflags and KeyUsesEaseTo3DS) > 0 then
  1547. WriteSingle(K.easeto);
  1548. if (K.rflags and KeyUsesEaseFrom3DS) > 0 then
  1549. WriteSingle(K.easefrom);
  1550. end;
  1551. // ---------------------------------------------------------------------------------------------------------------------
  1552. function TFile3DS.ReadKeyHeader: TKeyHeader3DS;
  1553. begin
  1554. Result := DefKeyHeader3DS;
  1555. Result.time := ReadCardinal;
  1556. Result.rflags := ReadWord;
  1557. if (Result.rflags and KeyUsesTension3DS) > 0 then
  1558. Result.tension := ReadSingle;
  1559. if (Result.rflags and KeyUsesCont3DS) > 0 then
  1560. Result.continuity := ReadSingle;
  1561. if (Result.rflags and KeyUsesBias3DS) > 0 then
  1562. Result.bias := ReadSingle;
  1563. if (Result.rflags and KeyUsesEaseTo3DS) > 0 then
  1564. Result.easeto := ReadSingle;
  1565. if (Result.rflags and KeyUsesEaseFrom3DS) > 0 then
  1566. Result.easefrom := ReadSingle;
  1567. end;
  1568. // ---------------------------------------------------------------------------------------------------------------------
  1569. procedure TFile3DS.ReadChunkData(Chunk: PChunk3DS);
  1570. // Reads the data out of the chunk detailed in Chunk and places a pointer to
  1571. // the data into the PChunk3DS structure, it will also return that pointer.
  1572. var
  1573. I: Integer;
  1574. begin
  1575. if Chunk.Data.Dummy = nil then // don't try to read the data if its already been read
  1576. begin
  1577. // seek to the beginning of the Chunk's data (harmless if the Chunk has no data)
  1578. FStream.Position := Chunk.Position + 6;
  1579. case Chunk.Tag of
  1580. COLOR_F:
  1581. begin
  1582. Chunk.Data.ColorF := AllocMem(SizeOf(TColorF)); // allocate the memory to hold the data
  1583. with Chunk.Data.ColorF^ do
  1584. begin
  1585. Red := ReadSingle; // Read the data out of the file
  1586. Green := ReadSingle;
  1587. Blue := ReadSingle;
  1588. end;
  1589. end;
  1590. LIN_COLOR_F:
  1591. begin
  1592. Chunk.Data.LinColorF := AllocMem(SizeOf(TLinColorF));
  1593. with Chunk.Data.LinColorF^ do
  1594. begin
  1595. Red := ReadSingle;
  1596. Green := ReadSingle;
  1597. Blue := ReadSingle;
  1598. end;
  1599. end;
  1600. COLOR_24:
  1601. begin
  1602. Chunk.Data.Color24 := AllocMem(SizeOf(TColor24));
  1603. with Chunk.Data.Color24^ do
  1604. begin
  1605. Red := ReadByte;
  1606. Green := ReadByte;
  1607. Blue := ReadByte;
  1608. end;
  1609. end;
  1610. LIN_COLOR_24:
  1611. begin
  1612. Chunk.Data.LinColor24 := AllocMem(SizeOf(TLinColor24));
  1613. with Chunk.Data.LinColor24^ do
  1614. begin
  1615. Red := ReadByte;
  1616. Green := ReadByte;
  1617. Blue := ReadByte;
  1618. end;
  1619. end;
  1620. INT_PERCENTAGE:
  1621. begin
  1622. Chunk.Data.IntPercentage := AllocMem(SizeOf(TIntPercentage));
  1623. Chunk.Data.IntPercentage^ := ReadShort;
  1624. end;
  1625. FLOAT_PERCENTAGE:
  1626. begin
  1627. Chunk.Data.FloatPercentage := AllocMem(SizeOf(TFloatPercentage));
  1628. Chunk.Data.FloatPercentage^ := ReadSingle;
  1629. end;
  1630. MAT_MAPNAME:
  1631. begin
  1632. // Chunk.Data.MatMapname := AllocMem(SizeOf(TMatMapname));
  1633. Chunk.Data.MatMapname := ReadString;
  1634. end;
  1635. M3D_VERSION:
  1636. begin
  1637. Chunk.Data.M3dVersion := AllocMem(SizeOf(TM3dVersion));
  1638. Chunk.Data.M3dVersion^ := ReadInteger;
  1639. end;
  1640. MESH_VERSION:
  1641. begin
  1642. Chunk.Data.MeshVersion := AllocMem(SizeOf(TMeshVersion));
  1643. Chunk.Data.MeshVersion^ := ReadInteger;
  1644. end;
  1645. MASTER_SCALE:
  1646. begin
  1647. Chunk.Data.MasterScale := AllocMem(SizeOf(TMasterScale));
  1648. Chunk.Data.MasterScale^ := ReadSingle;
  1649. end;
  1650. LO_SHADOW_BIAS:
  1651. begin
  1652. Chunk.Data.LoShadowBias := AllocMem(SizeOf(TLoShadowBias));
  1653. Chunk.Data.LoShadowBias^ := ReadSingle;
  1654. end;
  1655. SHADOW_FILTER:
  1656. begin
  1657. Chunk.Data.ShadowFilter := AllocMem(SizeOf(TShadowFilter));
  1658. Chunk.Data.ShadowFilter^ := ReadSingle;
  1659. end;
  1660. SHADOW_RANGE:
  1661. begin
  1662. Chunk.Data.ShadowRange := AllocMem(SizeOf(TShadowRange));
  1663. Chunk.Data.ShadowRange^ := ReadInteger;
  1664. end;
  1665. HI_SHADOW_BIAS:
  1666. begin
  1667. Chunk.Data.HiShadowBias := AllocMem(SizeOf(THiShadowBias));
  1668. Chunk.Data.HiShadowBias^ := ReadSingle;
  1669. end;
  1670. RAY_BIAS:
  1671. begin
  1672. Chunk.Data.RayBias := AllocMem(SizeOf(TRayBias));
  1673. Chunk.Data.RayBias^ := ReadSingle;
  1674. end;
  1675. SHADOW_MAP_SIZE:
  1676. begin
  1677. Chunk.Data.ShadowMapSize := AllocMem(SizeOf(TShadowMapSize));
  1678. Chunk.Data.ShadowMapSize^ := ReadShort;
  1679. end;
  1680. SHADOW_SAMPLES:
  1681. begin
  1682. Chunk.Data.ShadowSamples := AllocMem(SizeOf(TShadowSamples));
  1683. Chunk.Data.ShadowSamples^ := ReadShort;
  1684. end;
  1685. O_CONSTS:
  1686. begin
  1687. Chunk.Data.OConsts := AllocMem(SizeOf(TOConsts));
  1688. Chunk.Data.OConsts^ := ReadPoint;
  1689. end;
  1690. BIT_MAP:
  1691. begin
  1692. // Chunk.Data.BitMapName := AllocMem(SizeOf(TBitMapName));
  1693. Chunk.Data.BitMapName := ReadString;
  1694. end;
  1695. V_GRADIENT:
  1696. begin
  1697. Chunk.Data.VGradient := AllocMem(SizeOf(TVGradient));
  1698. Chunk.Data.VGradient^ := ReadSingle;
  1699. end;
  1700. FOG:
  1701. begin
  1702. Chunk.Data.FOG := AllocMem(SizeOf(TFog));
  1703. with Chunk.Data.FOG^ do
  1704. begin
  1705. NearPlaneDist := ReadSingle;
  1706. NearPlaneDensity := ReadSingle;
  1707. FarPlaneDist := ReadSingle;
  1708. FarPlaneDensity := ReadSingle;
  1709. end;
  1710. end;
  1711. LAYER_FOG:
  1712. begin
  1713. Chunk.Data.LayerFog := AllocMem(SizeOf(TLayerFog));
  1714. with Chunk.Data.LayerFog^ do
  1715. begin
  1716. ZMin := ReadSingle;
  1717. ZMax := ReadSingle;
  1718. Density := ReadSingle;
  1719. AType := ReadCardinal;
  1720. end;
  1721. end;
  1722. DISTANCE_CUE:
  1723. begin
  1724. Chunk.Data.DistanceCue := AllocMem(SizeOf(TDistanceCue));
  1725. with Chunk.Data.DistanceCue^ do
  1726. begin
  1727. NearPlaneDist := ReadSingle;
  1728. NearPlaneDimming := ReadSingle;
  1729. FarPlaneDist := ReadSingle;
  1730. FarPlaneDimming := ReadSingle;
  1731. end;
  1732. end;
  1733. VIEW_TOP,
  1734. VIEW_BOTTOM,
  1735. VIEW_LEFT,
  1736. VIEW_RIGHT,
  1737. VIEW_FRONT,
  1738. VIEW_BACK:
  1739. begin
  1740. Chunk.Data.ViewStandard := AllocMem(SizeOf(TViewStandard));
  1741. with Chunk.Data.ViewStandard^ do
  1742. begin
  1743. ViewWidth := ReadSingle;
  1744. ViewTargetCoord := ReadPoint;
  1745. end;
  1746. end;
  1747. VIEW_USER:
  1748. begin
  1749. Chunk.Data.ViewUser := AllocMem(SizeOf(TViewUser));
  1750. with Chunk.Data.ViewUser^ do
  1751. begin
  1752. ViewWidth := ReadSingle;
  1753. XYViewAngle := ReadSingle;
  1754. YZViewAngle := ReadSingle;
  1755. BankAngle := ReadSingle;
  1756. ViewTargetCoord := ReadPoint;
  1757. end;
  1758. end;
  1759. VIEW_CAMERA:
  1760. begin
  1761. // Chunk.Data.ViewCamera := AllocMem(SizeOf(TViewCamera));
  1762. Chunk.Data.ViewCamera := ReadString;
  1763. end;
  1764. MAT_NAME:
  1765. begin
  1766. // Chunk.Data.MatName := AllocMem(SizeOf(TMatName));
  1767. Chunk.Data.MatName := ReadString;
  1768. end;
  1769. MAT_SHADING:
  1770. begin
  1771. Chunk.Data.MatShading := AllocMem(SizeOf(TMatShading));
  1772. FStream.Position := Chunk.Position + 6;
  1773. Chunk.Data.MatShading^ := ReadShort;
  1774. end;
  1775. MAT_ACUBIC:
  1776. begin
  1777. Chunk.Data.MatAcubic := AllocMem(SizeOf(TMatAcubic));
  1778. with Chunk.Data.MatAcubic^ do
  1779. begin
  1780. ShadeLevel := ReadByte;
  1781. AntiAlias := ReadByte;
  1782. Flags := ReadShort;
  1783. MapSize := ReadCardinal;
  1784. FrameInterval := ReadCardinal;
  1785. end;
  1786. end;
  1787. MAT_SXP_TEXT_DATA,
  1788. MAT_SXP_TEXT2_DATA,
  1789. MAT_SXP_OPAC_DATA,
  1790. MAT_SXP_BUMP_DATA,
  1791. MAT_SXP_SPEC_DATA,
  1792. MAT_SXP_SHIN_DATA,
  1793. MAT_SXP_SELFI_DATA,
  1794. MAT_SXP_TEXT_MASKDATA,
  1795. MAT_SXP_TEXT2_MASKDATA,
  1796. MAT_SXP_OPAC_MASKDATA,
  1797. MAT_SXP_BUMP_MASKDATA,
  1798. MAT_SXP_SPEC_MASKDATA,
  1799. MAT_SXP_SHIN_MASKDATA,
  1800. MAT_SXP_SELFI_MASKDATA,
  1801. MAT_SXP_REFL_MASKDATA,
  1802. PROC_DATA:
  1803. begin
  1804. Chunk.Data.IpasData := AllocMem(SizeOf(TIpasData));
  1805. with Chunk.Data.IpasData^ do
  1806. begin
  1807. Size := Chunk.Size - 6;
  1808. Data := AllocMem(Size);
  1809. ReadData(Size, Data);
  1810. end;
  1811. end;
  1812. MAT_WIRESIZE:
  1813. begin
  1814. Chunk.Data.MatWireSize := AllocMem(SizeOf(TMatWireSize));
  1815. Chunk.Data.MatWireSize^ := ReadSingle;
  1816. end;
  1817. MAT_MAP_TILING:
  1818. begin
  1819. Chunk.Data.MatMapTiling := AllocMem(SizeOf(TMatMapTiling));
  1820. Chunk.Data.MatMapTiling^ := ReadWord;
  1821. end;
  1822. MAT_MAP_TEXBLUR:
  1823. begin
  1824. Chunk.Data.MatMapTexblur := AllocMem(SizeOf(TMatMapTexblur));
  1825. Chunk.Data.MatMapTexblur^ := ReadSingle;
  1826. end;
  1827. MAT_MAP_USCALE:
  1828. begin
  1829. Chunk.Data.MatMapUScale := AllocMem(SizeOf(TMatMapUScale));
  1830. Chunk.Data.MatMapUScale^ := ReadSingle;
  1831. end;
  1832. MAT_MAP_VSCALE:
  1833. begin
  1834. Chunk.Data.MatMapVScale := AllocMem(SizeOf(TMatMapVScale));
  1835. Chunk.Data.MatMapVScale^ := ReadSingle;
  1836. end;
  1837. MAT_MAP_UOFFSET:
  1838. begin
  1839. Chunk.Data.MatMapUOffset := AllocMem(SizeOf(TMatMapUOffset));
  1840. Chunk.Data.MatMapUOffset^ := ReadSingle;
  1841. end;
  1842. MAT_MAP_VOFFSET:
  1843. begin
  1844. Chunk.Data.MatMapVOffset := AllocMem(SizeOf(TMatMapVOffset));
  1845. Chunk.Data.MatMapVOffset^ := ReadSingle;
  1846. end;
  1847. MAT_MAP_ANG:
  1848. begin
  1849. Chunk.Data.MatMapAng := AllocMem(SizeOf(TMatMapAng));
  1850. Chunk.Data.MatMapAng^ := ReadSingle;
  1851. end;
  1852. MAT_MAP_COL1:
  1853. begin
  1854. Chunk.Data.MatMapCol1 := AllocMem(SizeOf(TMatMapCol1));
  1855. with Chunk.Data.MatMapCol1^ do
  1856. begin
  1857. Red := ReadByte;
  1858. Green := ReadByte;
  1859. Blue := ReadByte;
  1860. end;
  1861. end;
  1862. MAT_MAP_COL2:
  1863. begin
  1864. Chunk.Data.MatMapCol2 := AllocMem(SizeOf(TMatMapCol2));
  1865. with Chunk.Data.MatMapCol2^ do
  1866. begin
  1867. Red := ReadByte;
  1868. Green := ReadByte;
  1869. Blue := ReadByte;
  1870. end;
  1871. end;
  1872. MAT_MAP_RCOL:
  1873. begin
  1874. Chunk.Data.MatMapRCol := AllocMem(SizeOf(TMatMapRCol));
  1875. with Chunk.Data.MatMapRCol^ do
  1876. begin
  1877. Red := ReadByte;
  1878. Green := ReadByte;
  1879. Blue := ReadByte;
  1880. end;
  1881. end;
  1882. MAT_MAP_GCOL:
  1883. begin
  1884. Chunk.Data.MatMapGCol := AllocMem(SizeOf(TMatMapGCol));
  1885. with Chunk.Data.MatMapGCol^ do
  1886. begin
  1887. Red := ReadByte;
  1888. Green := ReadByte;
  1889. Blue := ReadByte;
  1890. end;
  1891. end;
  1892. MAT_MAP_BCOL:
  1893. begin
  1894. Chunk.Data.MatMapBCol := AllocMem(SizeOf(TMatMapBCol));
  1895. with Chunk.Data.MatMapBCol^ do
  1896. begin
  1897. Red := ReadByte;
  1898. Green := ReadByte;
  1899. Blue := ReadByte;
  1900. end;
  1901. end;
  1902. MAT_BUMP_PERCENT:
  1903. begin
  1904. Chunk.Data.MatBumpPercent := AllocMem(SizeOf(TMatBumpPercent));
  1905. Chunk.Data.MatBumpPercent^ := ReadShort;
  1906. end;
  1907. NAMED_OBJECT:
  1908. begin
  1909. // Chunk.Data.NamedObject := AllocMem(SizeOf(TNamedObject));
  1910. Chunk.Data.NamedObject := ReadString;
  1911. end;
  1912. POINT_ARRAY:
  1913. begin
  1914. Chunk.Data.PointArray := AllocMem(SizeOf(TPointArray));
  1915. with Chunk.Data.PointArray^ do
  1916. begin
  1917. Vertices := ReadWord;
  1918. PointList := AllocMem(Vertices * SizeOf(TPoint3DS));
  1919. // for I := 0 to Vertices - 1 do PointList[I] := ReadPoint;
  1920. ReadData(Vertices * SizeOf(TPoint3DS), PointList);
  1921. end;
  1922. end;
  1923. POINT_FLAG_ARRAY:
  1924. begin
  1925. Chunk.Data.PointFlagArray := AllocMem(SizeOf(TPointFlagArray));
  1926. with Chunk.Data.PointFlagArray^ do
  1927. begin
  1928. Flags := ReadWord;
  1929. FlagList := AllocMem(Flags * SizeOf(SmallInt));
  1930. // for I := 0 to Flags - 1 do FlagList[I] := ReadShort;
  1931. ReadData(Flags * SizeOf(SmallInt), FlagList);
  1932. end;
  1933. end;
  1934. FACE_ARRAY:
  1935. begin
  1936. Chunk.Data.FaceArray := AllocMem(SizeOf(TFaceArray));
  1937. with Chunk.Data.FaceArray^ do
  1938. begin
  1939. Faces := ReadWord;
  1940. FaceList := AllocMem(Faces * SizeOf(TFace3DS));
  1941. // for I := 0 to Faces - 1 do FaceList[I] := ReadFace;
  1942. ReadData(Faces * SizeOf(TFace3DS), FaceList);
  1943. end;
  1944. end;
  1945. MSH_MAT_GROUP:
  1946. begin
  1947. Chunk.Data.MshMatGroup := AllocMem(SizeOf(TMshMatGroup));
  1948. with Chunk.Data.MshMatGroup^ do
  1949. begin
  1950. MatNameStr := AnsiString(StrPasFree(ReadString));
  1951. Faces := ReadWord;
  1952. if Faces > 0 then
  1953. begin
  1954. FaceList := AllocMem(Faces * SizeOf(Word));
  1955. // for I := 0 to Faces - 1 do FaceList[I] := ReadWord;
  1956. ReadData(Faces * SizeOf(Word), FaceList);
  1957. end
  1958. else
  1959. FaceList := nil;
  1960. end;
  1961. end;
  1962. MSH_BOXMAP:
  1963. begin
  1964. Chunk.Data.MshBoxmap := AllocMem(SizeOf(TMshBoxmap));
  1965. for I := 0 to 5 do
  1966. Chunk.Data.MshBoxmap[I] := ReadString;
  1967. end;
  1968. SMOOTH_GROUP:
  1969. begin
  1970. Chunk.Data.SmoothGroup := AllocMem(SizeOf(TSmoothGroup));
  1971. with Chunk.Data.SmoothGroup^ do
  1972. begin
  1973. Groups := (Chunk.Size - 6) div 4;
  1974. GroupList := AllocMem(Groups * SizeOf(Cardinal));
  1975. // for I := 0 to Groups - 1 do GroupList[I] := ReadCardinal;
  1976. ReadData(Groups * SizeOf(Cardinal), GroupList);
  1977. end;
  1978. end;
  1979. TEX_VERTS:
  1980. begin
  1981. Chunk.Data.TexVerts := AllocMem(SizeOf(TTexVerts));
  1982. with Chunk.Data.TexVerts^ do
  1983. begin
  1984. NumCoords := ReadWord;
  1985. TextVertList := AllocMem(NumCoords * SizeOf(TTexVert3DS));
  1986. // for I := 0 to NumCoords - 1 do TextVertList[I] := ReadTexVert;
  1987. ReadData(NumCoords * SizeOf(TTexVert3DS), TextVertList);
  1988. end;
  1989. end;
  1990. MESH_MATRIX:
  1991. begin
  1992. Chunk.Data.MeshMatrix := AllocMem(SizeOf(TMeshMatrix));
  1993. for I := 0 to 11 do
  1994. Chunk.Data.MeshMatrix[I] := ReadSingle;
  1995. end;
  1996. MESH_COLOR:
  1997. begin
  1998. Chunk.Data.MeshColor := AllocMem(SizeOf(TMeshColor));
  1999. Chunk.Data.MeshColor^ := ReadByte;
  2000. end;
  2001. MESH_TEXTURE_INFO:
  2002. begin
  2003. Chunk.Data.MeshTextureInfo := AllocMem(SizeOf(TMeshTextureInfo));
  2004. with Chunk.Data.MeshTextureInfo^ do
  2005. begin
  2006. MapType := ReadWord;
  2007. XTiling := ReadSingle;
  2008. YTiling := ReadSingle;
  2009. IconPos := ReadPoint();
  2010. IconScaling := ReadSingle;
  2011. for I := 0 to 11 do
  2012. XMatrix[I] := ReadSingle;
  2013. IconWidth := ReadSingle;
  2014. IconHeight := ReadSingle;
  2015. CylIconHeight := ReadSingle;
  2016. end;
  2017. end;
  2018. PROC_NAME:
  2019. begin
  2020. // Chunk.Data.ProcName := AllocMem(SizeOf(TProcName));
  2021. Chunk.Data.ProcName := ReadString;
  2022. end;
  2023. N_DIRECT_LIGHT:
  2024. begin
  2025. Chunk.Data.NDirectLight := AllocMem(SizeOf(TNDirectLight));
  2026. Chunk.Data.NDirectLight^ := ReadPoint;
  2027. end;
  2028. DL_EXCLUDE:
  2029. begin
  2030. // Chunk.Data.DlExclude := AllocMem(SizeOf(TDlExclude));
  2031. Chunk.Data.DlExclude := ReadString;
  2032. end;
  2033. DL_INNER_RANGE:
  2034. begin
  2035. Chunk.Data.DlInnerRange := AllocMem(SizeOf(TDlInnerRange));
  2036. Chunk.Data.DlInnerRange^ := ReadSingle;
  2037. end;
  2038. DL_OUTER_RANGE:
  2039. begin
  2040. Chunk.Data.DlOuterRange := AllocMem(SizeOf(TDlOuterRange));
  2041. Chunk.Data.DlOuterRange^ := ReadSingle;
  2042. end;
  2043. DL_MULTIPLIER:
  2044. begin
  2045. Chunk.Data.DlMultiplier := AllocMem(SizeOf(TDlMultiplier));
  2046. Chunk.Data.DlMultiplier^ := ReadSingle;
  2047. end;
  2048. DL_SPOTLIGHT:
  2049. begin
  2050. Chunk.Data.DlSpotlight := AllocMem(SizeOf(TDlSpotlight));
  2051. with Chunk.Data.DlSpotlight^ do
  2052. begin
  2053. SpotlightTarg := ReadPoint;
  2054. HotspotAngle := ReadSingle;
  2055. FalloffAngle := ReadSingle;
  2056. end;
  2057. end;
  2058. DL_LOCAL_SHADOW2:
  2059. begin
  2060. Chunk.Data.DlLocalShadow2 := AllocMem(SizeOf(TDlLocalShadow2));
  2061. with Chunk.Data.DlLocalShadow2^ do
  2062. begin
  2063. LocalShadowBias := ReadSingle;
  2064. LocalShadowFilter := ReadSingle;
  2065. LocalShadowMapSize := ReadShort;
  2066. end;
  2067. end;
  2068. DL_SPOT_ROLL:
  2069. begin
  2070. Chunk.Data.DlSpotRoll := AllocMem(SizeOf(TDlSpotRoll));
  2071. Chunk.Data.DlSpotRoll^ := ReadSingle;
  2072. end;
  2073. DL_SPOT_ASPECT:
  2074. begin
  2075. Chunk.Data.DlSpotAspect := AllocMem(SizeOf(TDlSpotAspect));
  2076. Chunk.Data.DlSpotAspect^ := ReadSingle;
  2077. end;
  2078. DL_SPOT_PROJECTOR:
  2079. begin
  2080. // Chunk.Data.DlSpotProjector := AllocMem(SizeOf(TDlSpotProjector));
  2081. Chunk.Data.DlSpotProjector := ReadString;
  2082. end;
  2083. DL_RAY_BIAS:
  2084. begin
  2085. Chunk.Data.DlRayBias := AllocMem(SizeOf(TDlRayBias));
  2086. Chunk.Data.DlRayBias^ := ReadSingle;
  2087. end;
  2088. N_CAMERA:
  2089. begin
  2090. Chunk.Data.NCamera := AllocMem(SizeOf(TNCamera));
  2091. with Chunk.Data.NCamera^ do
  2092. begin
  2093. CameraPos := ReadPoint;
  2094. TargetPos := ReadPoint;
  2095. CameraBank := ReadSingle;
  2096. CameraFocalLength := ReadSingle;
  2097. end;
  2098. end;
  2099. CAM_RANGES:
  2100. begin
  2101. Chunk.Data.CamRanges := AllocMem(SizeOf(TCamRanges));
  2102. with Chunk.Data.CamRanges^ do
  2103. begin
  2104. NearPlane := ReadSingle;
  2105. FarPlane := ReadSingle;
  2106. end;
  2107. end;
  2108. VIEWPORT_LAYOUT:
  2109. begin
  2110. Chunk.Data.ViewportLayout := AllocMem(SizeOf(TViewportLayout));
  2111. with Chunk.Data.ViewportLayout^ do
  2112. begin
  2113. Form := ReadShort;
  2114. Top := ReadShort;
  2115. Ready := ReadShort;
  2116. WState := ReadShort;
  2117. SwapWS := ReadShort;
  2118. SwapPort := ReadShort;
  2119. SwapCur := ReadShort;
  2120. end;
  2121. end;
  2122. VIEWPORT_SIZE:
  2123. begin
  2124. Chunk.Data.ViewportSize := AllocMem(SizeOf(TViewportSize));
  2125. with Chunk.Data.ViewportSize^ do
  2126. begin
  2127. XPos := ReadWord;
  2128. YPos := ReadWord;
  2129. Width := ReadWord;
  2130. Height := ReadWord;
  2131. end;
  2132. end;
  2133. VIEWPORT_DATA_3,
  2134. VIEWPORT_DATA:
  2135. begin
  2136. Chunk.Data.ViewportData := AllocMem(SizeOf(TViewportData));
  2137. with Chunk.Data.ViewportData^ do
  2138. begin
  2139. Flags := ReadShort;
  2140. AxisLockout := ReadShort;
  2141. WinXPos := ReadShort;
  2142. WinYPos := ReadShort;
  2143. WinWidth := ReadShort;
  2144. WinHeight := ReadShort;
  2145. View := ReadShort;
  2146. ZoomFactor := ReadSingle;
  2147. Center := ReadPoint;
  2148. HorizAng := ReadSingle;
  2149. VertAng := ReadSingle;
  2150. CamNameStr := AnsiString(StrPasFree(ReadString));
  2151. end;
  2152. end;
  2153. XDATA_ENTRY:
  2154. begin
  2155. InitChunkData(Chunk);
  2156. with Chunk.Data.XDataEntry^ do
  2157. begin
  2158. Size := (Chunk.Size) - 6;
  2159. Data := AllocMem(Size);
  2160. ReadData(Size, Data);
  2161. end;
  2162. end;
  2163. XDATA_APPNAME:
  2164. begin
  2165. Chunk.Data.XDataAppName := ReadString;
  2166. end;
  2167. XDATA_STRING:
  2168. begin
  2169. Chunk.Data.XDataString := ReadString;
  2170. end;
  2171. KFHDR:
  2172. begin
  2173. Chunk.Data.KFHDR := AllocMem(SizeOf(TKFHdr));
  2174. with Chunk.Data.KFHDR^ do
  2175. begin
  2176. Revision := ReadShort;
  2177. FileName := StrPasFree(ReadString);
  2178. AnimLength := ReadInteger;
  2179. end;
  2180. end;
  2181. KFSEG:
  2182. begin
  2183. Chunk.Data.KFSEG := AllocMem(SizeOf(TKFSeg));
  2184. with Chunk.Data.KFSEG^ do
  2185. begin
  2186. First := ReadInteger;
  2187. Last := ReadInteger;
  2188. end;
  2189. end;
  2190. KFCURTIME:
  2191. begin
  2192. Chunk.Data.KFCURTIME := AllocMem(SizeOf(TKFCurtime));
  2193. Chunk.Data.KFCURTIME^ := ReadInteger;
  2194. end;
  2195. NODE_ID:
  2196. begin
  2197. Chunk.Data.KFID := AllocMem(SizeOf(TKFId));
  2198. Chunk.Data.KFID^ := ReadShort;
  2199. end;
  2200. NODE_HDR:
  2201. begin
  2202. Chunk.Data.NodeHdr := AllocMem(SizeOf(TNodeHdr));
  2203. with Chunk.Data.NodeHdr^ do
  2204. begin
  2205. ObjNameStr := StrPasFree(ReadString);
  2206. Flags1 := ReadWord;
  2207. Flags2 := ReadWord;
  2208. ParentIndex := ReadShort;
  2209. end;
  2210. end;
  2211. PIVOT:
  2212. begin
  2213. Chunk.Data.PIVOT := AllocMem(SizeOf(TPivot));
  2214. Chunk.Data.PIVOT^ := ReadPoint;
  2215. end;
  2216. INSTANCE_NAME:
  2217. begin
  2218. Chunk.Data.InstanceName := ReadString;
  2219. end;
  2220. PARENT_NAME:
  2221. ; // do nothing
  2222. MORPH_SMOOTH:
  2223. begin
  2224. Chunk.Data.MorphSmooth := AllocMem(SizeOf(TMorphSmooth));
  2225. Chunk.Data.MorphSmooth^ := ReadSingle;
  2226. end;
  2227. BOUNDBOX:
  2228. begin
  2229. Chunk.Data.BOUNDBOX := AllocMem(SizeOf(TBoundBox));
  2230. with Chunk.Data.BOUNDBOX^ do
  2231. begin
  2232. Min := ReadPoint;
  2233. Max := ReadPoint;
  2234. end;
  2235. end;
  2236. POS_TRACK_TAG:
  2237. begin
  2238. Chunk.Data.PosTrackTag := AllocMem(SizeOf(TPosTrackTag));
  2239. with Chunk.Data.PosTrackTag^ do
  2240. begin
  2241. TrackHdr := ReadTrackHeader;
  2242. KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
  2243. PositionList := AllocMem(TrackHdr.KeyCount * SizeOf(TPoint3DS));
  2244. for I := 0 to TrackHdr.KeyCount - 1 do
  2245. begin
  2246. KeyHdrList[I] := ReadKeyHeader;
  2247. PositionList[I] := ReadPoint;
  2248. end;
  2249. end;
  2250. end;
  2251. COL_TRACK_TAG:
  2252. begin
  2253. Chunk.Data.ColTrackTag := AllocMem(SizeOf(TColTrackTag));
  2254. with Chunk.Data.ColTrackTag^ do
  2255. begin
  2256. TrackHdr := ReadTrackHeader;
  2257. ColorList := AllocMem(TrackHdr.KeyCount * SizeOf(TFColor3DS));
  2258. KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
  2259. for I := 0 to TrackHdr.KeyCount - 1 do
  2260. begin
  2261. KeyHdrList[I] := ReadKeyHeader;
  2262. ColorList[I].R := ReadSingle;
  2263. ColorList[I].G := ReadSingle;
  2264. ColorList[I].B := ReadSingle;
  2265. end;
  2266. end;
  2267. end;
  2268. ROT_TRACK_TAG:
  2269. begin
  2270. Chunk.Data.RotTrackTag := AllocMem(SizeOf(TRotTrackTag));
  2271. with Chunk.Data.RotTrackTag^ do
  2272. begin
  2273. TrackHdr := ReadTrackHeader;
  2274. KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
  2275. RotationList := AllocMem(TrackHdr.KeyCount * SizeOf(TKFrotkey3DS));
  2276. for I := 0 to TrackHdr.KeyCount - 1 do
  2277. begin
  2278. KeyHdrList[I] := ReadKeyHeader;
  2279. RotationList[I].Angle := ReadSingle;
  2280. RotationList[I].X := ReadSingle;
  2281. RotationList[I].Y := ReadSingle;
  2282. RotationList[I].Z := ReadSingle;
  2283. end;
  2284. end;
  2285. end;
  2286. SCL_TRACK_TAG:
  2287. begin
  2288. Chunk.Data.ScaleTrackTag := AllocMem(SizeOf(TScaleTrackTag));
  2289. with Chunk.Data.ScaleTrackTag^ do
  2290. begin
  2291. TrackHdr := ReadTrackHeader;
  2292. KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
  2293. ScaleList := AllocMem(TrackHdr.KeyCount * SizeOf(TPoint3DS));
  2294. for I := 0 to TrackHdr.KeyCount - 1 do
  2295. begin
  2296. KeyHdrList[I] := ReadKeyHeader;
  2297. ScaleList[I].X := ReadSingle;
  2298. ScaleList[I].Y := ReadSingle;
  2299. ScaleList[I].Z := ReadSingle;
  2300. end;
  2301. end;
  2302. end;
  2303. MORPH_TRACK_TAG:
  2304. begin
  2305. Chunk.Data.MorphTrackTag := AllocMem(SizeOf(TMorphTrackTag));
  2306. with Chunk.Data.MorphTrackTag^ do
  2307. begin
  2308. TrackHdr := ReadTrackHeader;
  2309. KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
  2310. MorphList := AllocMem(TrackHdr.KeyCount * SizeOf(TKFmorphKey3DS));
  2311. for I := 0 to TrackHdr.KeyCount - 1 do
  2312. begin
  2313. KeyHdrList[I] := ReadKeyHeader;
  2314. MorphList[I] := StrPasFree(ReadString);
  2315. end;
  2316. end;
  2317. end;
  2318. FOV_TRACK_TAG:
  2319. begin
  2320. Chunk.Data.FovTrackTag := AllocMem(SizeOf(TFovTrackTag));
  2321. with Chunk.Data.FovTrackTag^ do
  2322. begin
  2323. TrackHdr := ReadTrackHeader;
  2324. KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
  2325. FOVAngleList := AllocMem(TrackHdr.KeyCount * SizeOf(Single));
  2326. for I := 0 to TrackHdr.KeyCount - 1 do
  2327. begin
  2328. KeyHdrList[I] := ReadKeyHeader;
  2329. FOVAngleList[I] := ReadSingle;
  2330. end;
  2331. end;
  2332. end;
  2333. ROLL_TRACK_TAG:
  2334. begin
  2335. Chunk.Data.RollTrackTag := AllocMem(SizeOf(TRollTrackTag));
  2336. with Chunk.Data.RollTrackTag^ do
  2337. begin
  2338. TrackHdr := ReadTrackHeader;
  2339. KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
  2340. RollAngleList := AllocMem(TrackHdr.KeyCount * SizeOf(Single));
  2341. for I := 0 to TrackHdr.KeyCount - 1 do
  2342. begin
  2343. KeyHdrList[I] := ReadKeyHeader;
  2344. RollAngleList[I] := ReadSingle;
  2345. end;
  2346. end;
  2347. end;
  2348. HOT_TRACK_TAG:
  2349. begin
  2350. Chunk.Data.HotTrackTag := AllocMem(SizeOf(THotTrackTag));
  2351. with Chunk.Data.HotTrackTag^ do
  2352. begin
  2353. TrackHdr := ReadTrackHeader;
  2354. KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
  2355. HotspotAngleList := AllocMem(TrackHdr.KeyCount * SizeOf(Single));
  2356. for I := 0 to TrackHdr.KeyCount - 1 do
  2357. begin
  2358. KeyHdrList[I] := ReadKeyHeader;
  2359. HotspotAngleList[I] := ReadSingle;
  2360. end;
  2361. end;
  2362. end;
  2363. FALL_TRACK_TAG:
  2364. begin
  2365. Chunk.Data.FallTrackTag := AllocMem(SizeOf(TFallTrackTag));
  2366. with Chunk.Data.FallTrackTag^ do
  2367. begin
  2368. TrackHdr := ReadTrackHeader;
  2369. KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
  2370. FalloffAngleList := AllocMem(TrackHdr.KeyCount * SizeOf(Single));
  2371. for I := 0 to TrackHdr.KeyCount - 1 do
  2372. begin
  2373. KeyHdrList[I] := ReadKeyHeader;
  2374. FalloffAngleList[I] := ReadSingle;
  2375. end;
  2376. end;
  2377. end;
  2378. HIDE_TRACK_TAG:
  2379. begin
  2380. Chunk.Data.HideTrackTag := AllocMem(SizeOf(THideTrackTag));
  2381. with Chunk.Data.HideTrackTag^ do
  2382. begin
  2383. TrackHdr := ReadTrackHeader;
  2384. KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
  2385. for I := 0 to TrackHdr.KeyCount - 1 do
  2386. KeyHdrList[I] := ReadKeyHeader;
  2387. end;
  2388. end;
  2389. M3DMAGIC, // Chunks that do not contain data, or only contain children
  2390. MLIBMAGIC,
  2391. MDATA,
  2392. AMBIENT_LIGHT,
  2393. SOLID_BGND,
  2394. DEFAULT_VIEW,
  2395. MAT_ENTRY,
  2396. MAT_AMBIENT,
  2397. MAT_DIFFUSE,
  2398. MAT_SPECULAR,
  2399. MAT_SHININESS,
  2400. MAT_SHIN2PCT,
  2401. MAT_SHIN3PCT,
  2402. MAT_TRANSPARENCY,
  2403. MAT_XPFALL,
  2404. MAT_REFBLUR,
  2405. MAT_SELF_ILPCT,
  2406. MAT_TEXMAP,
  2407. MAT_TEXMASK,
  2408. MAT_TEX2MAP,
  2409. MAT_TEX2MASK,
  2410. MAT_OPACMAP,
  2411. MAT_OPACMASK,
  2412. MAT_REFLMAP,
  2413. MAT_REFLMASK,
  2414. MAT_BUMPMAP,
  2415. MAT_BUMPMASK,
  2416. MAT_SPECMAP,
  2417. MAT_SPECMASK,
  2418. MAT_SHINMAP,
  2419. MAT_SHINMASK,
  2420. MAT_SELFIMAP,
  2421. MAT_SELFIMASK,
  2422. N_TRI_OBJECT,
  2423. KFDATA,
  2424. AMBIENT_NODE_TAG,
  2425. OBJECT_NODE_TAG,
  2426. CAMERA_NODE_TAG,
  2427. TARGET_NODE_TAG,
  2428. LIGHT_NODE_TAG,
  2429. SPOTLIGHT_NODE_TAG,
  2430. L_TARGET_NODE_TAG,
  2431. CMAGIC,
  2432. XDATA_SECTION,
  2433. XDATA_GROUP:
  2434. ; // do nothing
  2435. else // a truely hideous thing to do, but it helps with unknown chunks
  2436. if Chunk.Size > 6 then // don't mess with dataless chunks
  2437. begin
  2438. Chunk.Data.Dummy := AllocMem(Chunk.Size - 6);
  2439. ReadData(Chunk.Size - 6, Chunk.Data.Dummy);
  2440. end;
  2441. end; // end of case
  2442. end;
  2443. end;
  2444. //---------------------------------------------------------------------------------------------------------------------
  2445. procedure TFile3DS.SeekChild(Chunk: PChunk3DS);
  2446. // Function skips to next Chunk on disk by seeking the next file position
  2447. var
  2448. Offset: Integer;
  2449. begin
  2450. Offset := 0;
  2451. case Chunk.Tag of
  2452. M3DMAGIC,
  2453. SMAGIC,
  2454. LMAGIC,
  2455. MATMAGIC,
  2456. MLIBMAGIC,
  2457. MDATA,
  2458. AMBIENT_LIGHT,
  2459. SOLID_BGND,
  2460. DEFAULT_VIEW,
  2461. MAT_ENTRY,
  2462. MAT_AMBIENT,
  2463. MAT_DIFFUSE,
  2464. MAT_SPECULAR,
  2465. MAT_SHININESS,
  2466. MAT_SHIN2PCT,
  2467. MAT_SHIN3PCT,
  2468. MAT_TRANSPARENCY,
  2469. MAT_XPFALL,
  2470. MAT_REFBLUR,
  2471. MAT_SELF_ILPCT,
  2472. MAT_TEXMAP,
  2473. MAT_TEXMASK,
  2474. MAT_TEX2MAP,
  2475. MAT_TEX2MASK,
  2476. MAT_OPACMAP,
  2477. MAT_OPACMASK,
  2478. MAT_REFLMAP,
  2479. MAT_REFLMASK,
  2480. MAT_BUMPMAP,
  2481. MAT_BUMPMASK,
  2482. MAT_SPECMAP,
  2483. MAT_SPECMASK,
  2484. MAT_SHINMAP,
  2485. MAT_SHINMASK,
  2486. MAT_SELFIMAP,
  2487. MAT_SELFIMASK,
  2488. N_TRI_OBJECT,
  2489. XDATA_SECTION,
  2490. XDATA_ENTRY,
  2491. KFDATA,
  2492. OBJECT_NODE_TAG,
  2493. CAMERA_NODE_TAG,
  2494. TARGET_NODE_TAG,
  2495. LIGHT_NODE_TAG,
  2496. SPOTLIGHT_NODE_TAG,
  2497. L_TARGET_NODE_TAG,
  2498. AMBIENT_NODE_TAG,
  2499. CMAGIC :
  2500. ; // do nothing
  2501. M3D_VERSION:
  2502. Offset := SizeOf(Integer);
  2503. COLOR_F:
  2504. Offset := 3 * SizeOf(Single);
  2505. COLOR_24:
  2506. Offset := 3 * SizeOf(Byte);
  2507. INT_PERCENTAGE:
  2508. Offset := SizeOf(SmallInt);
  2509. FLOAT_PERCENTAGE:
  2510. Offset := SizeOf(Single);
  2511. MAT_MAPNAME:
  2512. FreeMem(ReadString);
  2513. MESH_VERSION:
  2514. Offset := SizeOf(Integer);
  2515. MASTER_SCALE:
  2516. Offset := SizeOf(Single);
  2517. LO_SHADOW_BIAS:
  2518. Offset := SizeOf(Single);
  2519. HI_SHADOW_BIAS:
  2520. Offset := SizeOf(Single);
  2521. SHADOW_MAP_SIZE:
  2522. Offset := SizeOf(SmallInt);
  2523. SHADOW_SAMPLES:
  2524. Offset := SizeOf(SmallInt);
  2525. O_CONSTS:
  2526. Offset := 12;
  2527. V_GRADIENT:
  2528. Offset := SizeOf(Single);
  2529. NAMED_OBJECT:
  2530. FreeMem(ReadString);
  2531. BIT_MAP:
  2532. FreeMem(ReadString);
  2533. FOG:
  2534. Offset := 4 * SizeOf(Single);
  2535. LAYER_FOG:
  2536. Offset := 3 * SizeOf(Single) + SizeOf(Integer);
  2537. DISTANCE_CUE:
  2538. Offset := 4 * SizeOf(Single);
  2539. N_DIRECT_LIGHT:
  2540. Offset := 12;
  2541. DL_SPOTLIGHT:
  2542. Offset := 12 + 2 * SizeOf(Single);
  2543. N_CAMERA:
  2544. Offset := 24 + 2 * SizeOf(Single);
  2545. VIEWPORT_LAYOUT:
  2546. Offset := 7 * SizeOf(SmallInt);
  2547. VIEW_TOP,
  2548. VIEW_BOTTOM,
  2549. VIEW_LEFT,
  2550. VIEW_RIGHT,
  2551. VIEW_FRONT,
  2552. VIEW_BACK:
  2553. Offset := 12 + SizeOf(Single);
  2554. VIEW_USER:
  2555. Offset := 12 + 4 * SizeOf(Single);
  2556. VIEW_CAMERA:
  2557. FreeMem(ReadString);
  2558. MAT_NAME:
  2559. FreeMem(ReadString);
  2560. MAT_ACUBIC:
  2561. Offset := 2 * SizeOf(Byte) + 2 * SizeOf(Integer) + SizeOf(SmallInt);
  2562. POINT_ARRAY,
  2563. POINT_FLAG_ARRAY:
  2564. Offset := Chunk.Size - 6;
  2565. FACE_ARRAY:
  2566. Offset := ReadWord * SizeOf(SmallInt) * 4;
  2567. MSH_MAT_GROUP:
  2568. Offset := Chunk.Size - 6;
  2569. SMOOTH_GROUP:
  2570. Offset := Chunk.Size - 6;
  2571. TEX_VERTS:
  2572. Offset := Chunk.Size - 6;
  2573. MESH_MATRIX:
  2574. Offset := 12 * SizeOf(Single);
  2575. MESH_TEXTURE_INFO:
  2576. Offset := Chunk.Size - 6;
  2577. PROC_NAME:
  2578. FreeMem(ReadString);
  2579. DL_LOCAL_SHADOW2:
  2580. Offset := 2 * SizeOf(Single) + SizeOf(SmallInt);
  2581. KFHDR:
  2582. begin
  2583. ReadShort;
  2584. FreeMem(ReadString);
  2585. ReadInteger;
  2586. end;
  2587. KFSEG:
  2588. Offset := 2 * SizeOf(Integer);
  2589. KFCURTIME:
  2590. Offset := SizeOf(Integer);
  2591. NODE_HDR:
  2592. begin
  2593. FreeMem(ReadString);
  2594. Offset := 2 * SizeOf(SmallInt) + SizeOf(SmallInt);
  2595. end;
  2596. NODE_ID:
  2597. Offset := SizeOf(SmallInt);
  2598. PIVOT:
  2599. Offset := 12;
  2600. INSTANCE_NAME:
  2601. FreeMem(ReadString);
  2602. MORPH_SMOOTH:
  2603. Offset := SizeOf(Single);
  2604. BOUNDBOX:
  2605. Offset := 24;
  2606. VPDATA:
  2607. Offset := SizeOf(Integer);
  2608. else
  2609. Offset := Chunk.Size - 6;
  2610. end;
  2611. FStream.Seek(Offset, soFromCurrent);
  2612. end;
  2613. //---------------------------------------------------------------------------------------------------------------------
  2614. function TFile3DS.GetDatabaseRelease: TReleaseLevel;
  2615. begin
  2616. Result := File3DSUtils.GetDatabaseRelease(Self, FDatabase);
  2617. end;
  2618. //---------------------------------------------------------------------------------------------------------------------
  2619. function TFile3DS.GetMeshRelease: TReleaseLevel;
  2620. begin
  2621. Result := File3DSUtils.GetMeshRelease(Self, FDatabase);
  2622. end;
  2623. //---------------------------------------------------------------------------------------------------------------------
  2624. end.