2
0

Formats.m3DS.pas 86 KB

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