Formatx.m3DS.pas 86 KB

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