Преглед на файлове

Replaced units in vcl/fmx folders

GLScene преди 2 години
родител
ревизия
f8bf53bd88
променени са 100 файла, в които са добавени 388 реда и са изтрити 12433 реда
  1. 1 1
      Examples/Demos/graph/fxy/FxyC.cbproj
  2. 2 2
      Examples/Demos/graph/fxy/FxyC.cpp
  3. 89 72
      Examples/Demos/graph/fxy/fFxyC.cpp
  4. 73 42
      Examples/Demos/graph/fxy/fFxyC.dfm
  5. 45 44
      Examples/Demos/graph/fxy/fFxyC.h
  6. 9 6
      Examples/Demos/graph/projection/fProjectionC.cpp
  7. 8 13
      Examples/Demos/graph/projection/fProjectionC.dfm
  8. 0 2
      Examples/Demos/graph/projection/fProjectionC.h
  9. 1 2
      Examples/Demos/graph/projection/fProjectionD.pas
  10. 22 17
      Examples/Demos/specialsFX/warping/fWarpingC.cpp
  11. 11 8
      Examples/Demos/specialsFX/warping/fWarpingC.dfm
  12. 3 20
      Examples/Demos/specialsFX/warping/fWarpingC.h
  13. 0 1
      Examples/Sandbox/#sandbox.txt
  14. 2 2
      Packages/GLScene_Cg_DT.dproj
  15. 1 3
      Packages/GLScene_RT.dpk
  16. 1 3
      Packages/GLScene_RT.dproj
  17. 8 9
      Packagex/GLXcene_RT.dpk
  18. 7 8
      Packagex/GLXcene_RT.dproj
  19. 2 2
      Source/CUDA.APIComps.pas
  20. 1 1
      Source/CUDA.Context.pas
  21. 2 2
      Source/CUDA.EditorFm.pas
  22. 2 2
      Source/CUDA.FFTPlan.pas
  23. 2 2
      Source/CUDA.Graphics.pas
  24. 2 2
      Source/Cg.BombShader.pas
  25. 1 1
      Source/Cg.PostTransformationShader.pas
  26. 1 1
      Source/Cg.Register.pas
  27. 1 1
      Source/Cg.Shader.pas
  28. 1 1
      Source/Common/FMOD.Import.pas
  29. 1 1
      Source/Common/OpenAL.Import.pas
  30. 2 2
      Source/FMX/CGx.BombShader.pas
  31. 1 1
      Source/FMX/CGx.PostTransformationShader.pas
  32. 1 1
      Source/FMX/CGx.Register.pas
  33. 1 1
      Source/FMX/CGx.Shader.pas
  34. 1 1
      Source/FMX/CUDAx.API.pas
  35. 1 1
      Source/FMX/CUDAx.Compiler.pas
  36. 1 1
      Source/FMX/CUDAx.Context.pas
  37. 1 1
      Source/FMX/CUDAx.FFTPlan.pas
  38. 1 1
      Source/FMX/CUDAx.Graphics.pas
  39. 1 1
      Source/FMX/DWSx.OpenGL.pas
  40. 1 1
      Source/FMX/FMxCUDAEditor.pas
  41. 1 1
      Source/FMX/FMxInfo.pas
  42. 1 1
      Source/FMX/FMxSceneEditor.pas
  43. 1 1
      Source/FMX/FMxShaderUniformEditor.pas
  44. 1 1
      Source/FMX/FMxXCollectionEditor.pas
  45. 1 1
      Source/FMX/Formatx.B3D.pas
  46. 1 1
      Source/FMX/Formatx.DDSImage.pas
  47. 1 1
      Source/FMX/Formatx.DXTC.pas
  48. 1 1
      Source/FMX/Formatx.HDRImage.pas
  49. 1 1
      Source/FMX/Formatx.LWObjects.pas
  50. 1 1
      Source/FMX/Formatx.MD2.pas
  51. 0 94
      Source/FMX/Formatx.O3TCImage.pas
  52. 1 1
      Source/FMX/Formatx.OCT.pas
  53. 2 2
      Source/FMX/Formatx.TGA.pas
  54. 1 1
      Source/FMX/Formatx.VFW.pas
  55. 2 2
      Source/FMX/Formatx.VRML.pas
  56. 2 2
      Source/FMX/Formatx.VfsPAK.pas
  57. 4 3
      Source/FMX/Formatx.X.pas
  58. 0 2832
      Source/FMX/Formatx.m3DS.pas
  59. 0 971
      Source/FMX/Formatx.m3DSConst.pas
  60. 0 1388
      Source/FMX/Formatx.m3DSTypes.pas
  61. 0 6789
      Source/FMX/Formatx.m3DSUtils.pas
  62. 1 1
      Source/FMX/GLSLx.AsmShader.pas
  63. 2 2
      Source/FMX/GLSLx.BumpShaders.pas
  64. 2 2
      Source/FMX/GLSLx.CustomShader.pas
  65. 2 2
      Source/FMX/GLSLx.DiffuseSpecularShader.pas
  66. 1 1
      Source/FMX/GLSLx.Parameter.pas
  67. 1 1
      Source/FMX/GLSLx.PhongShader.pas
  68. 2 2
      Source/FMX/GLSLx.PostEffects.pas
  69. 1 1
      Source/FMX/GLSLx.PostShaders.pas
  70. 1 1
      Source/FMX/GLSLx.ProjectedTextures.pas
  71. 1 1
      Source/FMX/GLSLx.Shader.pas
  72. 2 2
      Source/FMX/GLSLx.ShaderCombiner.pas
  73. 1 1
      Source/FMX/GLSLx.TextureShaders.pas
  74. 1 1
      Source/FMX/GLX.AVIRecorder.pas
  75. 2 2
      Source/FMX/GLX.AnimatedSprite.pas
  76. 1 1
      Source/FMX/GLX.AnimationUtils.pas
  77. 2 2
      Source/FMX/GLX.ApplicationFileIO.pas
  78. 2 2
      Source/FMX/GLX.ArchiveManager.pas
  79. 1 1
      Source/FMX/GLX.AsyncHDS.pas
  80. 1 1
      Source/FMX/GLX.AsyncTimer.pas
  81. 2 2
      Source/FMX/GLX.Atmosphere.pas
  82. 1 1
      Source/FMX/GLX.BSP.pas
  83. 1 1
      Source/FMX/GLX.BaseClasses.pas
  84. 1 1
      Source/FMX/GLX.BaseMeshSilhouette.pas
  85. 1 1
      Source/FMX/GLX.Behaviours.pas
  86. 1 1
      Source/FMX/GLX.BitmapFont.pas
  87. 2 2
      Source/FMX/GLX.Blur.pas
  88. 1 1
      Source/FMX/GLX.BumpmapHDS.pas
  89. 1 1
      Source/FMX/GLX.Cadencer.pas
  90. 1 1
      Source/FMX/GLX.Canvas.pas
  91. 1 1
      Source/FMX/GLX.CelShader.pas
  92. 1 1
      Source/FMX/GLX.Collision.pas
  93. 1 1
      Source/FMX/GLX.Color.pas
  94. 2 2
      Source/FMX/GLX.Console.pas
  95. 2 2
      Source/FMX/GLX.Context.pas
  96. 2 2
      Source/FMX/GLX.Coordinates.pas
  97. 2 2
      Source/FMX/GLX.CurvesAndSurfaces.pas
  98. 2 2
      Source/FMX/GLX.DCE.pas
  99. 1 1
      Source/FMX/GLX.DCEMisc.pas
  100. 2 2
      Source/FMX/GLX.DynamicTexture.pas

+ 1 - 1
Examples/Demos/graph/fxy/FxyC.cbproj

@@ -149,7 +149,7 @@
     </PropertyGroup>
     <ItemGroup>
         <CppCompile Include="fFxyC.cpp">
-            <Form>Form1</Form>
+            <Form>FormPlot</Form>
             <DependentOn>fFxyC.h</DependentOn>
             <BuildOrder>3</BuildOrder>
         </CppCompile>

+ 2 - 2
Examples/Demos/graph/fxy/FxyC.cpp

@@ -4,7 +4,7 @@
 #pragma hdrstop
 #include <tchar.h>
 //---------------------------------------------------------------------------
-USEFORM("fFxyC.cpp", Form1);
+USEFORM("fFxyC.cpp", FormPlot);
 //---------------------------------------------------------------------------
 int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
 {
@@ -12,7 +12,7 @@ int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
 	{
 		Application->Initialize();
 		Application->MainFormOnTaskBar = true;
-		Application->CreateForm(__classid(TForm1), &Form1);
+		Application->CreateForm(__classid(TFormPlot), &FormPlot);
 		Application->Run();
 	}
 	catch (Exception &exception)

+ 89 - 72
Examples/Demos/graph/fxy/fFxyC.cpp

@@ -15,106 +15,105 @@
 #pragma link "GLS.Coordinates"
 
 #pragma resource "*.dfm"
-TForm1 *Form1;
+TFormPlot* FormPlot;
 
 //---------------------------------------------------------------------------
-__fastcall TForm1::TForm1(TComponent * Owner):TForm(Owner)
-{
-}
+
+__fastcall TFormPlot::TFormPlot(TComponent* Owner) : TForm(Owner) {}
 
 //---------------------------------------------------------------------------
-void __fastcall TForm1::Formula0(const float x, const float y, float &z,
-		  TVector4f &color, TTexPoint &texPoint)
+void __fastcall TFormPlot::Formula0(const float x, const float y, float &z,
+	TVector4f &color, TTexPoint &texPoint)
 {
-   // 0ro formula
-   z = VectorNorm(x, y);
-   z = x*y;
-   VectorLerp(clrBlue, clrRed, (z+1)/2, color);
+	// 0ro formula
+	z = VectorNorm(x, y);
+	z = x * y;
+	VectorLerp(clrBlue, clrRed, (z + 1) / 2, color);
 }
 
 //---------------------------------------------------------------------------
-void __fastcall TForm1::Formula1(const float x, const float y, float &z,
-		  TVector4f &color, TTexPoint &texPoint)
+void __fastcall TFormPlot::Formula1(const float x, const float y, float &z,
+	TVector4f &color, TTexPoint &texPoint)
 {
 	// 1st formula
-   z = VectorNorm(x, y);
-   z = x*y*z;
-  // z = (x*x)*(y*y);
-   VectorLerp(clrBlue, clrRed, (z+1)/2, color);
+	z = VectorNorm(x, y);
+	z = x * y * z;  // or z = (x*x)*(y*y);
+	VectorLerp(clrBlue, clrRed, (z + 1) / 2, color);
 }
 
 //---------------------------------------------------------------------------
-void __fastcall TForm1::Formula2(const float x, const float y, float &z,
-		  TVector4f &color, TTexPoint &texPoint)
+void __fastcall TFormPlot::Formula2(const float x, const float y, float &z,
+	TVector4f &color, TTexPoint &texPoint)
 {
-   // 2nd formula
-  z = VectorNorm(x, y);
-  z = sin(z*12)/(2*(z*6.28+1));
-   VectorLerp(clrBlue, clrRed, (z+1)/2, color);
+	// 2nd formula
+	z = VectorNorm(x, y);
+	z = sin(z * 12) / (2 * (z * 6.28 + 1));
+	VectorLerp(clrBlue, clrRed, (z + 1) / 2, color);
 }
 
 //---------------------------------------------------------------------------
-void __fastcall TForm1::Formula3(const float x, const float y, float &z,
-		  TVector4f &color, TTexPoint &texPoint)
+void __fastcall TFormPlot::Formula3(const float x, const float y, float &z,
+	TVector4f &color, TTexPoint &texPoint)
 {
-   // 3rd formula
-   z = VectorNorm(x, y);
-   z = (pow(x,2) + pow(y,2)) * sin(8*atan2(x,y));
-   VectorLerp(clrBlue, clrRed, (z+1)/2, color);
+	// 3rd formula
+	z = VectorNorm(x, y);
+	z = (pow(x, 2) + pow(y, 2)) * sin(8 * atan2(x, y));
+	VectorLerp(clrBlue, clrRed, (z + 1) / 2, color);
 }
 
-
 //---------------------------------------------------------------------------
 
-void __fastcall TForm1::CheckBox1Click(TObject * Sender)
+void __fastcall TFormPlot::FormCreate(TObject* Sender)
 {
-  if(CheckBox1->Checked)
-  {
-	XZGrid->YSamplingScale->Origin = 0;
-	YZGrid->XSamplingScale->Origin = 0;
-	XYGrid->ZSamplingScale->Origin = 0;
-  }
-  else
-  {
-	XZGrid->YSamplingScale->Origin = -1;
-	YZGrid->XSamplingScale->Origin = -1;
-	XYGrid->ZSamplingScale->Origin = -1;
-  }
+	rgFormulaClick(Sender);
 }
 
 //---------------------------------------------------------------------------
 
-void __fastcall TForm1::TrackBar1Change(TObject * Sender)
+void __fastcall TFormPlot::chbCenterClick(TObject* Sender)
 {
-  XYGrid->ZSamplingScale->Origin = -((float)TrackBar1->Position / 10);
+	if (chbCenter->Checked) {
+		XZGrid->YSamplingScale->Origin = 0;
+		YZGrid->XSamplingScale->Origin = 0;
+		XYGrid->ZSamplingScale->Origin = 0;
+	} else {
+		XZGrid->YSamplingScale->Origin = -1;
+		YZGrid->XSamplingScale->Origin = -1;
+		XYGrid->ZSamplingScale->Origin = -1;
+	}
 }
 
 //---------------------------------------------------------------------------
 
-void __fastcall TForm1::TrackBar2Change(TObject *Sender)
+void __fastcall TFormPlot::TrackBarYChange(TObject* Sender)
 {
-  XZGrid->YSamplingScale->Origin = -((float)TrackBar2->Position / 10);
+	XYGrid->ZSamplingScale->Origin = -((float)TrackBarY->Position / 10);
 }
+
 //---------------------------------------------------------------------------
 
-void __fastcall TForm1::TrackBar3Change(TObject *Sender)
+void __fastcall TFormPlot::TrackBarXChange(TObject* Sender)
 {
-  YZGrid->XSamplingScale->Origin = -((float)TrackBar3->Position / 10);
+	XZGrid->YSamplingScale->Origin = -((float)TrackBarX->Position / 10);
 }
 //---------------------------------------------------------------------------
 
+void __fastcall TFormPlot::TrackBarZChange(TObject* Sender)
+{
+	YZGrid->XSamplingScale->Origin = -((float)TrackBarZ->Position / 10);
+}
 //---------------------------------------------------------------------------
-void __fastcall TForm1::ViewerMouseDown(TObject * Sender,
-												TMouseButton Button,
-												TShiftState Shift, int X, int Y)
+
+void __fastcall TFormPlot::ViewerMouseDown(
+	TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
 {
-  mx = X;
-  my = Y;
+	mx = X;
+	my = Y;
 }
 
 //---------------------------------------------------------------------------
-void __fastcall TForm1::ViewerMouseMove(TObject * Sender,
-												TShiftState Shift, int X, int Y)
+void __fastcall TFormPlot::ViewerMouseMove(
+	TObject* Sender, TShiftState Shift, int X, int Y)
 {
 	if (Shift.Contains(ssLeft))
 		Camera->MoveAroundTarget(my - Y, mx - X);
@@ -125,33 +124,51 @@ void __fastcall TForm1::ViewerMouseMove(TObject * Sender,
 }
 
 //---------------------------------------------------------------------------
-void __fastcall TForm1::FormMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta,
-		  TPoint &MousePos, bool &Handled)
+void __fastcall TFormPlot::FormMouseWheel(TObject* Sender, TShiftState Shift,
+	int WheelDelta, TPoint &MousePos, bool &Handled)
 {
-  Camera->AdjustDistanceToTarget(Power(1.1, (WheelDelta / 120.0)));
+	Camera->AdjustDistanceToTarget(Power(1.1, (WheelDelta / 120.0)));
 }
 
 //---------------------------------------------------------------------------
 
-
-
-void __fastcall TForm1::RadioGroup1Click(TObject *Sender)
+void __fastcall TFormPlot::rgFormulaClick(TObject *Sender)
 {
-  switch (RadioGroup1->ItemIndex) {
-	 case 0: GLHeightField1->OnGetHeight = Formula0; break;
-	 case 1: GLHeightField1->OnGetHeight = Formula1; break;
-	 case 2: GLHeightField1->OnGetHeight = Formula2; break;
-	 case 3: GLHeightField1->OnGetHeight = Formula3; break;
-   default:
-	  ;
-  }
+	switch (rgFormula->ItemIndex) {
+		case 0:
+			HeightField->OnGetHeight = Formula0;
+			break;
+		case 1:
+			HeightField->OnGetHeight = Formula1;
+			break;
+		case 2:
+			HeightField->OnGetHeight = Formula2;
+			break;
+		case 3:
+			HeightField->OnGetHeight = Formula3;
+			break;
+		default:;
+	}
 }
+
 //---------------------------------------------------------------------------
 
-void __fastcall TForm1::FormCreate(TObject *Sender)
+void __fastcall TFormPlot::rgPolygonModeClick(TObject* Sender)
 {
-  RadioGroup1Click(Sender);
+	switch (rgPolygonMode->ItemIndex) {
+		case 0:
+			HeightField->Material->PolygonMode = pmFill;
+			break;
+		case 1:
+			HeightField->Material->PolygonMode = pmLines;
+			break;
+		case 2:
+			HeightField->Material->PolygonMode = pmPoints;
+			break;
+		default:;
+	}
+   HeightField->StructureChanged();
 }
-//---------------------------------------------------------------------------
 
+//---------------------------------------------------------------------------
 

+ 73 - 42
Examples/Demos/graph/fxy/fFxyC.dfm

@@ -1,9 +1,9 @@
-object Form1: TForm1
+object FormPlot: TFormPlot
   Left = 192
   Top = 121
   Caption = 'Fxy '
-  ClientHeight = 536
-  ClientWidth = 677
+  ClientHeight = 564
+  ClientWidth = 786
   Color = clBtnFace
   Font.Charset = DEFAULT_CHARSET
   Font.Color = clWindowText
@@ -17,8 +17,8 @@ object Form1: TForm1
   object Viewer: TGLSceneViewer
     Left = 0
     Top = 0
-    Width = 454
-    Height = 536
+    Width = 563
+    Height = 564
     Margins.Left = 2
     Margins.Top = 2
     Margins.Right = 2
@@ -26,33 +26,58 @@ object Form1: TForm1
     Camera = Camera
     Buffer.BackgroundColor = clTeal
     Buffer.AntiAliasing = aa4xHQ
-    FieldOfView = 122.320289611816400000
+    FieldOfView = 132.112792968750000000
     PenAsTouch = False
     Align = alClient
     OnMouseDown = ViewerMouseDown
     OnMouseMove = ViewerMouseMove
     TabOrder = 0
+    ExplicitWidth = 455
+    ExplicitHeight = 537
   end
   object Panel1: TPanel
-    Left = 454
+    Left = 563
     Top = 0
     Width = 223
-    Height = 536
+    Height = 564
     Align = alRight
     TabOrder = 1
-    object Label1: TLabel
-      Left = 66
-      Top = 40
-      Width = 80
+    ExplicitLeft = 579
+    object LabelX: TLabel
+      Left = 34
+      Top = 48
+      Width = 15
+      Height = 19
+      Margins.Left = 2
+      Margins.Top = 2
+      Margins.Right = 2
+      Margins.Bottom = 2
+      Caption = 'X'
+    end
+    object LabelY: TLabel
+      Left = 104
+      Top = 48
+      Width = 7
       Height = 13
       Margins.Left = 2
       Margins.Top = 2
       Margins.Right = 2
       Margins.Bottom = 2
-      Caption = 'XYZ grid position'
+      Caption = 'Y'
     end
-    object TrackBar1: TTrackBar
-      Left = 173
+    object LabelZ: TLabel
+      Left = 168
+      Top = 48
+      Width = 7
+      Height = 13
+      Margins.Left = 2
+      Margins.Top = 2
+      Margins.Right = 2
+      Margins.Bottom = 2
+      Caption = 'Z'
+    end
+    object TrackBarY: TTrackBar
+      Left = 101
       Top = 71
       Width = 36
       Height = 257
@@ -63,9 +88,9 @@ object Form1: TForm1
       Min = -10
       Orientation = trVertical
       TabOrder = 0
-      OnChange = TrackBar1Change
+      OnChange = TrackBarYChange
     end
-    object TrackBar2: TTrackBar
+    object TrackBarX: TTrackBar
       Left = 29
       Top = 71
       Width = 36
@@ -77,10 +102,10 @@ object Form1: TForm1
       Min = -10
       Orientation = trVertical
       TabOrder = 1
-      OnChange = TrackBar2Change
+      OnChange = TrackBarXChange
     end
-    object TrackBar3: TTrackBar
-      Left = 101
+    object TrackBarZ: TTrackBar
+      Left = 165
       Top = 71
       Width = 36
       Height = 257
@@ -91,9 +116,9 @@ object Form1: TForm1
       Min = -10
       Orientation = trVertical
       TabOrder = 2
-      OnChange = TrackBar3Change
+      OnChange = TrackBarZChange
     end
-    object CheckBox1: TCheckBox
+    object chbCenter: TCheckBox
       Left = 64
       Top = 11
       Width = 97
@@ -104,9 +129,9 @@ object Form1: TForm1
       Margins.Bottom = 2
       Caption = 'Centered Grids'
       TabOrder = 3
-      OnClick = CheckBox1Click
+      OnClick = chbCenterClick
     end
-    object RadioGroup1: TRadioGroup
+    object rgFormula: TRadioGroup
       Left = 16
       Top = 345
       Width = 217
@@ -119,31 +144,43 @@ object Form1: TForm1
         'sin(z*12)/(2*(z*6.28+1))'
         '(pow(x,2)+pow(y,2))*sin(8*atan2(x,y))')
       TabOrder = 4
-      OnClick = RadioGroup1Click
+      OnClick = rgFormulaClick
+    end
+    object rgPolygonMode: TRadioGroup
+      Left = 13
+      Top = 464
+      Width = 196
+      Height = 89
+      Caption = 'PolygonMode'
+      ItemIndex = 0
+      Items.Strings = (
+        'pmFill'
+        'pmLines'
+        'pmPoints')
+      TabOrder = 5
+      OnClick = rgPolygonModeClick
     end
-  end
-  object Edit1: TEdit
-    Left = 112
-    Top = 72
-    Width = 121
-    Height = 21
-    TabOrder = 2
-    Text = 'Edit1'
   end
   object GLScene1: TGLScene
     Left = 80
     Top = 48
-    object GLLightSource1: TGLLightSource
+    object Camera: TGLCamera
+      DepthOfView = 100.000000000000000000
+      FocalLength = 125.000000000000000000
+      TargetObject = HeightField
+      Position.Coordinates = {0000404000008040000000410000803F}
+    end
+    object LightSource: TGLLightSource
       ConstAttenuation = 1.000000000000000000
       Position.Coordinates = {0000F041000048420000C8420000803F}
       SpotCutOff = 180.000000000000000000
     end
-    object GLHeightField1: TGLHeightField
+    object HeightField: TGLHeightField
       Direction.Coordinates = {0044F4970000803F2EBD3BB300000000}
       Scale.Coordinates = {00000040000000400000004000000000}
       ShowAxes = True
       Up.Coordinates = {0000803FEDAD09A72EBD3BB300000000}
-      OnPicked = CheckBox1Click
+      OnPicked = chbCenterClick
       XSamplingScale.Min = -1.000000000000000000
       XSamplingScale.Max = 1.000000000000000000
       XSamplingScale.Step = 0.019999999552965160
@@ -198,11 +235,5 @@ object Form1: TForm1
         Parts = [gpY, gpZ]
       end
     end
-    object Camera: TGLCamera
-      DepthOfView = 100.000000000000000000
-      FocalLength = 125.000000000000000000
-      TargetObject = GLHeightField1
-      Position.Coordinates = {0000404000008040000000410000803F}
-    end
   end
 end

+ 45 - 44
Examples/Demos/graph/fxy/fFxyC.h

@@ -18,54 +18,55 @@
 #include <Vcl.ImgList.hpp>
 
 //---------------------------------------------------------------------------
-class TForm1:public TForm
+class TFormPlot : public TForm
 {
-__published:                   // IDE-managed Components
-  TGLScene * GLScene1;
-	TGLSceneViewer *Viewer;
-	TGLCamera *Camera;
-  TGLLightSource *GLLightSource1;
-  TGLHeightField *GLHeightField1;
-  TGLXYZGrid *XYGrid;
-  TGLXYZGrid *XZGrid;
-  TGLXYZGrid *YZGrid;
-	TPanel *Panel1;
-	TTrackBar *TrackBar1;
-	TTrackBar *TrackBar2;
-	TTrackBar *TrackBar3;
-	TLabel *Label1;
-	TCheckBox *CheckBox1;
-	TRadioGroup *RadioGroup1;
-	TEdit *Edit1;
-  void __fastcall CheckBox1Click(TObject * Sender);
-  void __fastcall TrackBar1Change(TObject * Sender);
-  void __fastcall ViewerMouseDown(TObject * Sender, TMouseButton Button,
-                                          TShiftState Shift, int X, int Y);
-  void __fastcall ViewerMouseMove(TObject * Sender, TShiftState Shift,
-                                          int X, int Y);
-	void __fastcall TrackBar2Change(TObject *Sender);
-	void __fastcall TrackBar3Change(TObject *Sender);
-	void __fastcall FormMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta,
-          TPoint &MousePos, bool &Handled);
-	void __fastcall RadioGroup1Click(TObject *Sender);
-	void __fastcall FormCreate(TObject *Sender);
-
-private:                       // User declarations
-	int mx,my;
-	void __fastcall Formula0(const float x, const float y, float &z,
-		  TVector4f &color, TTexPoint &texPoint);
-	void __fastcall Formula1(const float x, const float y, float &z,
-		  TVector4f &color, TTexPoint &texPoint);
-	void __fastcall Formula2(const float x, const float y, float &z,
-		  TVector4f &color, TTexPoint &texPoint);
+  __published: // IDE-managed Components
+    TGLScene* GLScene1;
+    TGLSceneViewer* Viewer;
+    TGLCamera* Camera;
+	TGLLightSource *LightSource;
+	TGLHeightField *HeightField;
+    TGLXYZGrid* XYGrid;
+    TGLXYZGrid* XZGrid;
+    TGLXYZGrid* YZGrid;
+    TPanel* Panel1;
+	TTrackBar *TrackBarY;
+	TTrackBar *TrackBarX;
+	TTrackBar *TrackBarZ;
+	TLabel *LabelX;
+	TCheckBox *chbCenter;
+	TRadioGroup *rgFormula;
+	TRadioGroup *rgPolygonMode;
+	TLabel *LabelY;
+	TLabel *LabelZ;
+    void __fastcall chbCenterClick(TObject* Sender);
+    void __fastcall TrackBarYChange(TObject* Sender);
+    void __fastcall ViewerMouseDown(
+        TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y);
+    void __fastcall ViewerMouseMove(
+        TObject* Sender, TShiftState Shift, int X, int Y);
+    void __fastcall TrackBarXChange(TObject* Sender);
+    void __fastcall TrackBarZChange(TObject* Sender);
+    void __fastcall FormMouseWheel(TObject* Sender, TShiftState Shift,
+        int WheelDelta, TPoint &MousePos, bool &Handled);
+    void __fastcall rgFormulaClick(TObject* Sender);
+    void __fastcall FormCreate(TObject* Sender);
+	void __fastcall rgPolygonModeClick(TObject *Sender);
+  private: // User declarations
+    int mx, my;
+    void __fastcall Formula0(const float x, const float y, float &z,
+        TVector4f &color, TTexPoint &texPoint);
+    void __fastcall Formula1(const float x, const float y, float &z,
+        TVector4f &color, TTexPoint &texPoint);
+    void __fastcall Formula2(const float x, const float y, float &z,
+        TVector4f &color, TTexPoint &texPoint);
 	void __fastcall Formula3(const float x, const float y, float &z,
-		  TVector4f &color, TTexPoint &texPoint);
-
-public:                        // User declarations
-    __fastcall TForm1(TComponent * Owner);
+        TVector4f &color, TTexPoint &texPoint);
+  public: // User declarations
+    __fastcall TFormPlot(TComponent* Owner);
 };
 //---------------------------------------------------------------------------
-extern PACKAGE TForm1 *Form1;
+extern PACKAGE TFormPlot* FormPlot;
 //---------------------------------------------------------------------------
 #endif
 

+ 9 - 6
Examples/Demos/graph/projection/fProjectionC.cpp

@@ -26,13 +26,15 @@ __fastcall TForm1::TForm1(TComponent* Owner)
 {
 }
 //---------------------------------------------------------------------------
-void __fastcall TForm1::FormCreate(TObject *Sender)
+void __fastcall TForm1::FormCreate(TObject* Sender)
 {
-   int i;
-   // generate a bunch of random points
-   for (i=1; i < 1000; i++)
-	  GLPoints->Positions->Add((float)(Random()-0.5)*5,
-			  (float)(Random()-0.5)*5, (float)(Random()-0.5)*5);
+    int i;
+    // generate a bunch of random points
+    for (i = 1; i < 1000; i++) {
+		GLPoints->Positions->Add((float)(Random() - 0.5) * 5,
+			(float)(Random() - 0.5) * 5, (float)(Random() - 0.5) * 5);
+		GLPoints->Colors->Add(Random(), Random(), Random(), 0.8);
+	}
 }
 //---------------------------------------------------------------------------
 void __fastcall TForm1::DirectOpenGLRender(TObject *Sender, TGLRenderContextInfo &rci)
@@ -95,3 +97,4 @@ void __fastcall TForm1::FormMouseWheel(TObject *Sender, TShiftState Shift, int W
    GLPlane->Position->Y = GLPlane->Position->Y+WheelDelta*0.001;
 }
 //---------------------------------------------------------------------------
+

+ 8 - 13
Examples/Demos/graph/projection/fProjectionC.dfm

@@ -2,33 +2,28 @@ object Form1: TForm1
   Left = 0
   Top = 0
   Caption = 'Projection'
-  ClientHeight = 506
-  ClientWidth = 699
+  ClientHeight = 405
+  ClientWidth = 559
   Color = clBtnFace
   Font.Charset = DEFAULT_CHARSET
   Font.Color = clWindowText
-  Font.Height = -14
+  Font.Height = -11
   Font.Name = 'Tahoma'
   Font.Style = []
   Position = poScreenCenter
   OnCreate = FormCreate
   OnMouseWheel = FormMouseWheel
-  PixelsPerInch = 120
-  TextHeight = 17
+  TextHeight = 13
   object SceneViewer: TGLSceneViewer
     Left = 0
     Top = 0
-    Width = 699
-    Height = 506
-    Margins.Left = 4
-    Margins.Top = 4
-    Margins.Right = 4
-    Margins.Bottom = 4
+    Width = 559
+    Height = 405
     Camera = GLCamera
-    Buffer.BackgroundColor = clBlack
+    Buffer.BackgroundColor = clGray
     Buffer.FaceCulling = False
     Buffer.AntiAliasing = aa4xHQ
-    FieldOfView = 153.317077636718800000
+    FieldOfView = 146.991271972656300000
     PenAsTouch = False
     Align = alClient
     OnMouseDown = SceneViewerMouseDown

+ 0 - 2
Examples/Demos/graph/projection/fProjectionC.h

@@ -16,8 +16,6 @@
 #include "GLS.Scene.hpp"
 #include "GLS.SceneViewer.hpp"
 #include "GLS.RenderContextInfo.hpp"
-#include <gl\gl.h>
-
 
 
 //---------------------------------------------------------------------------

+ 1 - 2
Examples/Demos/graph/projection/fProjectionD.pas

@@ -49,9 +49,8 @@ type
     procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
       WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
   private
-     
+
   public
-     
     mx, my: Integer;
   end;
 

+ 22 - 17
Examples/Demos/specialsFX/warping/fWarpingC.cpp

@@ -20,14 +20,24 @@
 TForm1 *Form1;
 //---------------------------------------------------------------------------
 __fastcall TForm1::TForm1(TComponent* Owner)
-        : TForm(Owner)
+		: TForm(Owner)
 {
-  TFileName Path = GetCurrentAssetPath();
+  PathToTexture = GetCurrentAssetPath() + "\\texture";
 }
+
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::FormCreate(TObject *Sender)
+{
+   warpX = -1000;
+   warpY = -1000;
+   warpRadius = 20;
+}
+
 //---------------------------------------------------------------------------
 
 void __fastcall TForm1::HeightFieldGetHeight(const float x, const float y,
-      float &z, TVector4f &color, TTexPoint &texPoint)
+	  float &z, TVector4f &color, TTexPoint &texPoint)
 {
    // Here is the warping function
    // it basicly converts current pixel coords (x, y) to deformed coords (dx, dy)
@@ -37,11 +47,11 @@ void __fastcall TForm1::HeightFieldGetHeight(const float x, const float y,
 
    switch (warpEffect)
    {
-      case 0 : { // the "zoom" effect
-         d = 1.0-exp(-sqrt((x-warpX)*(x-warpX)+(y-warpY)*(y-warpY))/warpRadius);
-         dx = x*d+warpX*(1-d);
-         dy = y*d+warpY*(1-d);
-         break;
+	  case 0 : { // the "zoom" effect
+		 d = 1.0-exp(-sqrt((x-warpX)*(x-warpX)+(y-warpY)*(y-warpY))/warpRadius);
+		 dx = x*d+warpX*(1-d);
+		 dy = y*d+warpY*(1-d);
+		 break;
       }
       case 1 : { // the "spin" effect
 		 vec.X = x-warpX;
@@ -87,7 +97,7 @@ void __fastcall TForm1::MIOpenImageFileClick(TObject *Sender)
          GLCamera->FocalLength = 100.0/picture->Width;
       }
       __finally
-      {
+	  {
          delete picture;
       }
    }
@@ -116,7 +126,7 @@ void __fastcall TForm1::MISaveCurrentImageClick(TObject *Sender)
    }
    __finally
    {
-      delete bmp32;
+	  delete bmp32;
    }
 }
 //---------------------------------------------------------------------------
@@ -144,14 +154,9 @@ void __fastcall TForm1::GLSceneViewerMouseMove(TObject *Sender,
       GLSceneViewer->Refresh();
    }
 }
+
 //---------------------------------------------------------------------------
-void __fastcall TForm1::FormCreate(TObject *Sender)
-{
-   warpX = -1000;
-   warpY = -1000;
-   warpRadius = 20;        
-}
-//---------------------------------------------------------------------------
+
 void __fastcall TForm1::MIQualityOptionClick(TObject *Sender)
 {
    ((TMenuItem *) Sender)->Checked = true;

+ 11 - 8
Examples/Demos/specialsFX/warping/fWarpingC.dfm

@@ -2,25 +2,28 @@ object Form1: TForm1
   Left = 239
   Top = 111
   Caption = 'Warping'
-  ClientHeight = 456
-  ClientWidth = 664
+  ClientHeight = 365
+  ClientWidth = 531
   Color = clBtnFace
   Font.Charset = DEFAULT_CHARSET
   Font.Color = clWindowText
-  Font.Height = -14
+  Font.Height = -11
   Font.Name = 'MS Sans Serif'
   Font.Style = []
   Menu = MainMenu1
   OnCreate = FormCreate
-  PixelsPerInch = 120
-  TextHeight = 16
+  TextHeight = 13
   object GLSceneViewer: TGLSceneViewer
     Left = 0
     Top = 0
-    Width = 664
-    Height = 456
+    Width = 531
+    Height = 365
+    Margins.Left = 2
+    Margins.Top = 2
+    Margins.Right = 2
+    Margins.Bottom = 2
     Camera = GLCamera
-    FieldOfView = 179.748703002929700000
+    FieldOfView = 179.686050415039100000
     PenAsTouch = False
     Align = alClient
     OnMouseDown = GLSceneViewerMouseDown

+ 3 - 20
Examples/Demos/specialsFX/warping/fWarpingC.h

@@ -1,21 +1,3 @@
-//---------------------------------------------------------------------------
-/*: Demonstrates how to use texture coordinates to warp an image.
-
-   Load an image (preferably with dimensions a power of two, not too big,
-   and less than 256x256 if you have and old hardware, all TNT, GeForce,
-   Radeon and better should have no trouble loading big pictures), then click
-   somewhere in the image to define the warp point.<br>
-   You may use the menu to adjust or choose the effect.
-
-   This sample displays an image with the help of a single TGLHeightField used
-   as a convenient way to specify texture coordinates. The camera is in
-   orthogonal mode and adjusted along with the viewer to a ratio of 1:1.
-
-   All the warping code is in the TForm1.HeightFieldGetHeight event (the two
-   warping codes actually), the rest are just utility methods to load/save,
-   adjust settings etc.
-*/
-
 #ifndef fWarpingCH
 #define fWarpingCH
 //---------------------------------------------------------------------------
@@ -78,9 +60,10 @@ __published:	// IDE-managed Components
         void __fastcall FormCreate(TObject *Sender);
         void __fastcall MIQualityOptionClick(TObject *Sender);
         void __fastcall MIRadiusSettingClick(TObject *Sender);
-        void __fastcall MIZoomEffectClick(TObject *Sender);
+		void __fastcall MIZoomEffectClick(TObject *Sender);
 private:	// User declarations
-        int warpX, warpY, warpRadius, warpEffect;
+		int warpX, warpY, warpRadius, warpEffect;
+		TFileName PathToTexture;
 public:		// User declarations
         __fastcall TForm1(TComponent* Owner);
 };

+ 0 - 1
Examples/Sandbox/#sandbox.txt

@@ -1 +0,0 @@
-The directory for Sandbox

+ 2 - 2
Packages/GLScene_Cg_DT.dproj

@@ -166,12 +166,12 @@
                         <Overwrite>true</Overwrite>
                     </Platform>
                 </DeployFile>
-                <DeployFile LocalName="$(BDS)\Redist\iossimulator\libpcre.dylib" Class="DependencyModule">
+                <DeployFile LocalName="$(BDS)\Redist\iossimulator\libPCRE.dylib" Class="DependencyModule">
                     <Platform Name="iOSSimulator">
                         <Overwrite>true</Overwrite>
                     </Platform>
                 </DeployFile>
-                <DeployFile LocalName="$(BDS)\Redist\iossimulator\libPCRE.dylib" Class="DependencyModule">
+                <DeployFile LocalName="$(BDS)\Redist\iossimulator\libpcre.dylib" Class="DependencyModule">
                     <Platform Name="iOSSimulator">
                         <Overwrite>true</Overwrite>
                     </Platform>

+ 1 - 3
Packages/GLScene_RT.dpk

@@ -111,8 +111,6 @@ contains
   GLS.FileMS3D in '..\Source\GLS.FileMS3D.pas',
   GLS.FileNMF in '..\Source\GLS.FileNMF.pas',
   GLS.FileNurbs in '..\Source\GLS.FileNurbs.pas',
-  GLS.FileO3TC in '..\Source\GLS.FileO3TC.pas',
-  GLS.FileO3TCImage in '..\Source\GLS.FileO3TCImage.pas',
   GLS.FileOBJ in '..\Source\GLS.FileOBJ.pas',
   GLS.FileOCT in '..\Source\GLS.FileOCT.pas',
   GLS.FilePAK in '..\Source\GLS.FilePAK.pas',
@@ -263,7 +261,7 @@ contains
   GLS.VectorTypes in '..\Source\GLS.VectorTypes.pas',
   GLS.ScriptBase in '..\Source\GLS.ScriptBase.pas',
   GLS.Spline in '..\Source\GLS.Spline.pas',
-  GLS.Strings in '..\Source\GLS.Strings.pas',
+  Scene.Strings in '..\Source\Scene.Strings.pas',
   GLS.XCollection in '..\Source\GLS.XCollection.pas',
   GLS.XOpenGL in '..\Source\GLS.XOpenGL.pas',
   PasGLTF in '..\Source\Common\PasGLTF.pas',

+ 1 - 3
Packages/GLScene_RT.dproj

@@ -215,8 +215,6 @@
         <DCCReference Include="..\Source\GLS.FileMS3D.pas"/>
         <DCCReference Include="..\Source\GLS.FileNMF.pas"/>
         <DCCReference Include="..\Source\GLS.FileNurbs.pas"/>
-        <DCCReference Include="..\Source\GLS.FileO3TC.pas"/>
-        <DCCReference Include="..\Source\GLS.FileO3TCImage.pas"/>
         <DCCReference Include="..\Source\GLS.FileOBJ.pas"/>
         <DCCReference Include="..\Source\GLS.FileOCT.pas"/>
         <DCCReference Include="..\Source\GLS.FilePAK.pas"/>
@@ -367,7 +365,7 @@
         <DCCReference Include="..\Source\GLS.VectorTypes.pas"/>
         <DCCReference Include="..\Source\GLS.ScriptBase.pas"/>
         <DCCReference Include="..\Source\GLS.Spline.pas"/>
-        <DCCReference Include="..\Source\GLS.Strings.pas"/>
+        <DCCReference Include="..\Source\Scene.Strings.pas"/>
         <DCCReference Include="..\Source\GLS.XCollection.pas"/>
         <DCCReference Include="..\Source\GLS.XOpenGL.pas"/>
         <DCCReference Include="..\Source\Common\PasGLTF.pas"/>

+ 8 - 9
Packagex/GLXcene_RT.dpk

@@ -35,16 +35,14 @@ requires
 
 contains
   Formatx.B3D in '..\Source\FMX\Formatx.B3D.pas',
-  Formatx.m3DS in '..\Source\FMX\Formatx.m3DS.pas',
-  Formatx.m3DSConst in '..\Source\FMX\Formatx.m3DSConst.pas',
-  Formatx.m3DSTypes in '..\Source\FMX\Formatx.m3DSTypes.pas',
-  Formatx.m3DSUtils in '..\Source\FMX\Formatx.m3DSUtils.pas',
+  Formats.m3DS in '..\Source\Formats.m3DS.pas',
+  Formats.m3DSConst in '..\Source\Formats.m3DSConst.pas',
+  Formats.m3DSTypes in '..\Source\Formats.m3DSTypes.pas',
+  Formats.m3DSUtils in '..\Source\Formats.m3DSUtils.pas',
   Formatx.DDSImage in '..\Source\FMX\Formatx.DDSImage.pas',
   Formatx.HDRImage in '..\Source\FMX\Formatx.HDRImage.pas',
   Formatx.LWObjects in '..\Source\FMX\Formatx.LWObjects.pas',
   Formatx.MD3 in '..\Source\FMX\Formatx.MD3.pas',
-  Formatx.O3TCImage in '..\Source\FMX\Formatx.O3TCImage.pas',
-  Formatx.OCT in '..\Source\FMX\Formatx.OCT.pas',
   Formatx.Q3MD3 in '..\Source\FMX\Formatx.Q3MD3.pas',
   Formatx.X in '..\Source\FMX\Formatx.X.pas',
   Formatx.DXTC in '..\Source\FMX\Formatx.DXTC.pas',
@@ -116,7 +114,6 @@ contains
   GLX.FileMS3D in '..\Source\FMX\GLX.FileMS3D.pas',
   GLX.FileNMF in '..\Source\FMX\GLX.FileNMF.pas',
   GLX.FileNurbs in '..\Source\FMX\GLX.FileNurbs.pas',
-  GLX.FileO3TC in '..\Source\FMX\GLX.FileO3TC.pas',
   GLX.FileOBJ in '..\Source\FMX\GLX.FileOBJ.pas',
   GLX.FileOCT in '..\Source\FMX\GLX.FileOCT.pas',
   GLX.FilePLY in '..\Source\FMX\GLX.FilePLY.pas',
@@ -249,7 +246,6 @@ contains
   GLX.RGBE in '..\Source\FMX\GLX.RGBE.pas',
   GLX.SpacePartition in '..\Source\FMX\GLX.SpacePartition.pas',
   GLX.Spline in '..\Source\FMX\GLX.Spline.pas',
-  GLX.Strings in '..\Source\FMX\GLX.Strings.pas',
   GLX.VectorTypesExt in '..\Source\FMX\GLX.VectorTypesExt.pas',
   GLX.VectorGeometry in '..\Source\FMX\GLX.VectorGeometry.pas',
   GLX.VectorLists in '..\Source\FMX\GLX.VectorLists.pas',
@@ -259,7 +255,10 @@ contains
   GLX.GeometryBB in '..\Source\FMX\GLX.GeometryBB.pas',
   GLX.GeometryCoordinates in '..\Source\FMX\GLX.GeometryCoordinates.pas',
   GLX.OpenGL in '..\Source\FMX\GLX.OpenGL.pas',
+  Scene.Strings in '..\Source\Scene.Strings.pas',
   Vulkan.Import in '..\Source\Common\Vulkan.Import.pas',
-  GLSLx.Parameter in '..\Source\FMX\GLSLx.Parameter.pas';
+  GLSLx.Parameter in '..\Source\FMX\GLSLx.Parameter.pas',
+  GLX.File3DS in '..\Source\FMX\GLX.File3DS.pas',
+  Formatx.OCT in '..\Source\FMX\Formatx.OCT.pas';
 
 end.

+ 7 - 8
Packagex/GLXcene_RT.dproj

@@ -155,16 +155,14 @@
         <DCCReference Include="rtl.dcp"/>
         <DCCReference Include="fmx.dcp"/>
         <DCCReference Include="..\Source\FMX\Formatx.B3D.pas"/>
-        <DCCReference Include="..\Source\FMX\Formatx.m3DS.pas"/>
-        <DCCReference Include="..\Source\FMX\Formatx.m3DSConst.pas"/>
-        <DCCReference Include="..\Source\FMX\Formatx.m3DSTypes.pas"/>
-        <DCCReference Include="..\Source\FMX\Formatx.m3DSUtils.pas"/>
+        <DCCReference Include="..\Source\Formats.m3DS.pas"/>
+        <DCCReference Include="..\Source\Formats.m3DSConst.pas"/>
+        <DCCReference Include="..\Source\Formats.m3DSTypes.pas"/>
+        <DCCReference Include="..\Source\Formats.m3DSUtils.pas"/>
         <DCCReference Include="..\Source\FMX\Formatx.DDSImage.pas"/>
         <DCCReference Include="..\Source\FMX\Formatx.HDRImage.pas"/>
         <DCCReference Include="..\Source\FMX\Formatx.LWObjects.pas"/>
         <DCCReference Include="..\Source\FMX\Formatx.MD3.pas"/>
-        <DCCReference Include="..\Source\FMX\Formatx.O3TCImage.pas"/>
-        <DCCReference Include="..\Source\FMX\Formatx.OCT.pas"/>
         <DCCReference Include="..\Source\FMX\Formatx.Q3MD3.pas"/>
         <DCCReference Include="..\Source\FMX\Formatx.X.pas"/>
         <DCCReference Include="..\Source\FMX\Formatx.DXTC.pas"/>
@@ -236,7 +234,6 @@
         <DCCReference Include="..\Source\FMX\GLX.FileMS3D.pas"/>
         <DCCReference Include="..\Source\FMX\GLX.FileNMF.pas"/>
         <DCCReference Include="..\Source\FMX\GLX.FileNurbs.pas"/>
-        <DCCReference Include="..\Source\FMX\GLX.FileO3TC.pas"/>
         <DCCReference Include="..\Source\FMX\GLX.FileOBJ.pas"/>
         <DCCReference Include="..\Source\FMX\GLX.FileOCT.pas"/>
         <DCCReference Include="..\Source\FMX\GLX.FilePLY.pas"/>
@@ -369,7 +366,6 @@
         <DCCReference Include="..\Source\FMX\GLX.RGBE.pas"/>
         <DCCReference Include="..\Source\FMX\GLX.SpacePartition.pas"/>
         <DCCReference Include="..\Source\FMX\GLX.Spline.pas"/>
-        <DCCReference Include="..\Source\FMX\GLX.Strings.pas"/>
         <DCCReference Include="..\Source\FMX\GLX.VectorTypesExt.pas"/>
         <DCCReference Include="..\Source\FMX\GLX.VectorGeometry.pas"/>
         <DCCReference Include="..\Source\FMX\GLX.VectorLists.pas"/>
@@ -379,8 +375,11 @@
         <DCCReference Include="..\Source\FMX\GLX.GeometryBB.pas"/>
         <DCCReference Include="..\Source\FMX\GLX.GeometryCoordinates.pas"/>
         <DCCReference Include="..\Source\FMX\GLX.OpenGL.pas"/>
+        <DCCReference Include="..\Source\Scene.Strings.pas"/>
         <DCCReference Include="..\Source\Common\Vulkan.Import.pas"/>
         <DCCReference Include="..\Source\FMX\GLSLx.Parameter.pas"/>
+        <DCCReference Include="..\Source\FMX\GLX.File3DS.pas"/>
+        <DCCReference Include="..\Source\FMX\Formatx.OCT.pas"/>
         <BuildConfiguration Include="Base">
             <Key>Base</Key>
         </BuildConfiguration>

+ 2 - 2
Source/CUDA.APIComps.pas

@@ -7,7 +7,7 @@ unit CUDA.APIComps;
 
 interface
 
-{$I GLScene.inc}
+{$I Scene.inc}
 
 uses
   System.Types,
@@ -21,7 +21,7 @@ uses
   GLS.VectorTypes,
   GLS.VectorLists,
   GLS.Graphics,
-  GLS.Strings,
+  Scene.Strings,
   GLS.Utils,
 
   CUDA.Import,

+ 1 - 1
Source/CUDA.Context.pas

@@ -10,7 +10,7 @@ interface
 uses
   System.Classes,
   System.SysUtils,
-  GLS.Strings,
+  Scene.Strings,
   GLS.BaseClasses,
   GLS.Context,
   GLS.Generics,

+ 2 - 2
Source/CUDA.EditorFm.pas

@@ -7,7 +7,7 @@ unit CUDA.EditorFm;
 
 interface
 
-{$I GLScene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.Windows, 
@@ -27,7 +27,7 @@ uses
   Vcl.ToolWin,
   DesignIntf,
   VCLEditors,
-  GLS.Strings,
+  Scene.Strings,
 
   CUDA.APIComps,
   CUDA.FFTPlan,

+ 2 - 2
Source/CUDA.FFTPlan.pas

@@ -7,7 +7,7 @@ unit CUDA.FFTPlan;
 
 interface
 
-{$I GLScene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,
@@ -18,7 +18,7 @@ uses
   CUDA.APIComps,
   CUDA.FourierTransform,
 
-  GLS.Strings,
+  Scene.Strings,
   GLS.Logger;
 
 type

+ 2 - 2
Source/CUDA.Graphics.pas

@@ -7,7 +7,7 @@ unit CUDA.Graphics;
 
 interface
 
-{$I GLScene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,
@@ -23,7 +23,7 @@ uses
   GLS.Scene,
   GLS.Graphics,
   GLS.Material,
-  GLS.Strings,
+  Scene.Strings,
   GLS.TextureFormat,
   GLS.Texture,
   GLSL.Shader,

+ 2 - 2
Source/Cg.BombShader.pas

@@ -7,7 +7,7 @@ unit Cg.BombShader;
 
 interface
 
-{$I GLScene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,
@@ -16,7 +16,7 @@ uses
   GLS.Texture,
   GLS.Cadencer,
   GLS.Context,
-  GLS.Strings,
+  Scene.Strings,
   GLS.Material,
   GLS.RenderContextInfo,
   GLS.TextureFormat,

+ 1 - 1
Source/Cg.PostTransformationShader.pas

@@ -9,7 +9,7 @@ unit Cg.PostTransformationShader;
 *)
 interface
 
-{$I GLScene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 1 - 1
Source/Cg.Register.pas

@@ -7,7 +7,7 @@ unit Cg.Register;
 
 interface
 
-{$I GLScene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 1 - 1
Source/Cg.Shader.pas

@@ -17,7 +17,7 @@ uses
   GLS.VectorLists,
   GLS.VectorTypes,
   GLS.Texture,
-  GLS.Strings,
+  Scene.Strings,
   GLS.Cadencer,
   GLS.Context,
   GLS.BaseClasses,

+ 1 - 1
Source/Common/FMOD.Import.pas

@@ -25,7 +25,7 @@ unit FMOD.Import;
 
 interface
 
-{$I GLScene.inc}
+{$I Scene.inc}
 
 uses
 

+ 1 - 1
Source/Common/OpenAL.Import.pas

@@ -42,7 +42,7 @@ unit OpenAL.Import;
 
 interface
 
-{$I GLScene.inc}
+{$I Scene.inc}
 
 uses
   System.SysUtils

+ 2 - 2
Source/FMX/CGx.BombShader.pas

@@ -7,7 +7,7 @@ unit CGx.BombShader;
 
 interface
 
-{$I GLScene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,
@@ -16,7 +16,7 @@ uses
   GLX.Texture,
   GLX.Cadencer,
   GLX.Context,
-  GLX.Strings,
+  Scene.Strings,
   GLX.Material,
   GLX.RenderContextInfo,
   GLX.TextureFormat,

+ 1 - 1
Source/FMX/CGx.PostTransformationShader.pas

@@ -9,7 +9,7 @@ unit CGx.PostTransformationShader;
 *)
 interface
 
-{$I GLScene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 1 - 1
Source/FMX/CGx.Register.pas

@@ -7,7 +7,7 @@ unit CGx.Register;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 1 - 1
Source/FMX/CGx.Shader.pas

@@ -17,7 +17,7 @@ uses
   GLX.VectorLists,
   GLX.VectorTypes,
   GLX.Texture,
-  GLX.Strings,
+  Scene.Strings,
   GLX.Cadencer,
   GLX.Context,
   GLX.BaseClasses,

+ 1 - 1
Source/FMX/CUDAx.API.pas

@@ -17,7 +17,7 @@ uses
   GLX.VectorGeometry,
   GLX.VectorTypes,
   GLX.VectorLists,
-  GLX.Strings,
+  Scene.Strings,
   GLX.Context,
   GLX.Graphics,
 

+ 1 - 1
Source/FMX/CUDAx.Compiler.pas

@@ -21,7 +21,7 @@ uses
   FMX.Dialogs,
 
   GLX.ApplicationFileIO,
-  GLX.Strings,
+  Scene.Strings,
   CUDA.Parser;
 
 type

+ 1 - 1
Source/FMX/CUDAx.Context.pas

@@ -15,7 +15,7 @@ uses
   CUDA.Import,
   CUDA.RunTime,
 
-  GLX.Strings,
+  Scene.Strings,
   GLX.Generics,
   GLX.BaseClasses,
   GLX.Context;

+ 1 - 1
Source/FMX/CUDAx.FFTPlan.pas

@@ -17,7 +17,7 @@ uses
 
   CUDAx.API,
   CUDAx.Context,
-  GLX.Strings;
+  Scene.Strings;
 
 type
 

+ 1 - 1
Source/FMX/CUDAx.Graphics.pas

@@ -222,7 +222,7 @@ implementation
 
 uses
   System.SysUtils,
-  GLX.Strings,
+  Scene.Strings,
   GLX.TextureFormat;
 
 

+ 1 - 1
Source/FMX/DWSx.OpenGL.pas

@@ -8,7 +8,7 @@ unit DWSx.OpenGL;
 *)
 interface
 
-{$I GLScene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,

+ 1 - 1
Source/FMX/FMxCUDAEditor.pas

@@ -24,7 +24,7 @@ uses
   FMX.StdCtrls,
   FMX.Controls.Presentation,
 
-  GLX.Strings,
+  Scene.Strings,
   CUDAx.API,
   CUDAx.FFTPlan,
   CUDAx.Graphics;

+ 1 - 1
Source/FMX/FMxInfo.pas

@@ -29,7 +29,7 @@ uses
   GLX.OpenGL,
   GLX.Scene,
   GLX.Context,
-  GLX.Strings;
+  Scene.Strings;
 
 type
   TInfoForm = class(TForm)

+ 1 - 1
Source/FMX/FMxSceneEditor.pas

@@ -36,7 +36,7 @@ uses
   GLX.Scene,
   GLX.SceneViewer,
   GLX.SceneRegister,
-  GLX.Strings,
+  Scene.Strings,
   GLX.XCollection;
 
 type

+ 1 - 1
Source/FMX/FMxShaderUniformEditor.pas

@@ -24,7 +24,7 @@ uses
   GLSLx.Parameter,
   GLX.TextureFormat,
   GLX.VectorGeometry,
-  GLX.Strings;
+  Scene.Strings;
 
 type
   TShaderUniformEditorForm = class(TForm)

+ 1 - 1
Source/FMX/FMxXCollectionEditor.pas

@@ -31,7 +31,7 @@ uses
   FMX.ListView,
 
   GLX.Scene,
-  GLX.Strings,
+  Scene.Strings,
   GLX.Behaviours,
   GLX.XCollection;
 

+ 1 - 1
Source/FMX/Formatx.B3D.pas

@@ -7,7 +7,7 @@ unit Formatx.B3D;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 {$R-}
 
 uses

+ 1 - 1
Source/FMX/Formatx.DDSImage.pas

@@ -14,7 +14,7 @@ unit Formatx.DDSImage;
 *)
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,

+ 1 - 1
Source/FMX/Formatx.DXTC.pas

@@ -7,7 +7,7 @@ unit Formatx.DXTC;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 {$Z4}  // Minimum enum size = dword
 

+ 1 - 1
Source/FMX/Formatx.HDRImage.pas

@@ -8,7 +8,7 @@ unit Formatx.HDRImage;
 *)
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,

+ 1 - 1
Source/FMX/Formatx.LWObjects.pas

@@ -5,7 +5,7 @@ unit Formatx.LWObjects;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 1 - 1
Source/FMX/Formatx.MD2.pas

@@ -8,7 +8,7 @@ unit Formatx.MD2;
 interface
 
 {$R-}
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 0 - 94
Source/FMX/Formatx.O3TCImage.pas

@@ -1,94 +0,0 @@
-//
-// The graphics platform GLXcene https://github.com/glscene
-//
-unit Formatx.O3TCImage;
-(*
-    The format for preview a picture in OpenDialog,
-    so you may include both FileO3TCImage (preview) and GLFileO3TC (loading)
-*)
-interface
-
-{$I GLX.Scene.inc}
-
-uses
-  Winapi.Windows,
-  Winapi.OpenGL,
-  System.Classes,
-  System.SysUtils,
-  FMX.Graphics,
-
-  GLX.VectorGeometry,
-  GLX.Graphics,
-  GLX.FileO3TC,
-  GLX.TextureFormat;
-
-type
-
-  TO3TCImage = class(TBitmap)
-  public
-    procedure LoadFromStream(stream: TStream); //override; -> E2170 Cannot override a non-virtual method override;
-    procedure SaveToStream(stream: TStream); //override; -> E2170 Cannot override a non-virtual method override;
-  end;
-
-//=================================================== 
-implementation
-//=================================================== 
-
-// ------------------
-// ------------------ TO3TCImage ------------------
-// ------------------
-
-procedure TO3TCImage.LoadFromStream(stream: TStream);
-var
-  FullO3TC: TgxO3TCImage;
-  src, dst: PGLubyte;
-  y: Integer;
-  BitmapData: TBitmapData;
-
-begin
-  FullO3TC := TgxO3TCImage.Create;
-  try
-    FullO3TC.LoadFromStream(stream);
-  except
-    FullO3TC.Free;
-    raise;
-  end;
-
-  FullO3TC.Narrow;
-
-  Width := FullO3TC.LevelWidth[0];
-  Height := FullO3TC.LevelHeight[0];
-  {
-  [dcc32 Error] FileO3TCImage.pas(63): E2064 Left side cannot be assigned to
-  Transparent := true;
-  PixelFormat := glpf32bit;
-  }
-  src := PGLubyte(FullO3TC.Data);
-  for y := 0 to Height - 1 do
-  begin
-    dst := BitmapData.GetScanLine(Height - 1 - y);
-    BGRA32ToRGBA32(src, dst, Width);
-    Inc(src, Width * 4);
-  end;
-  FullO3TC.Free;
-end;
-
-procedure TO3TCImage.SaveToStream(stream: TStream);
-begin
-  Assert(False, 'Not supported');
-end;
-
-// ------------------------------------------------------------------
-initialization
-// ------------------------------------------------------------------
-
-///  TPicture.RegisterFileFormat('o3tc', 'oZone3D Texture Compression', TO3TCImage);
-
- // ------------------------------------------------------------------
-finalization
- // ------------------------------------------------------------------
-
-///  TPicture.UnregisterGraphicClass(TO3TCImage);
-
-end.
-

+ 1 - 1
Source/FMX/Formatx.OCT.pas

@@ -7,7 +7,7 @@ unit Formatx.OCT;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 2 - 2
Source/FMX/Formatx.TGA.pas

@@ -7,7 +7,7 @@ unit Formatx.TGA;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,
@@ -16,7 +16,7 @@ uses
   System.SysUtils,
 
   GLX.ApplicationFileIO,
-  GLX.Strings,
+  Scene.Strings,
 
   GLX.Context,
   GLX.Graphics,

+ 1 - 1
Source/FMX/Formatx.VFW.pas

@@ -46,7 +46,7 @@ interface
 
 {.$UNDEF UNICODE}
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
     Winapi.Windows,

+ 2 - 2
Source/FMX/Formatx.VRML.pas

@@ -7,14 +7,14 @@ unit Formatx.VRML;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,
   System.SysUtils,
   GLX.VectorTypes,
   GLX.VectorLists,
-  GLX.Strings;
+  Scene.Strings;
 
 type
   TVRMLNode = class

+ 2 - 2
Source/FMX/Formatx.VfsPAK.pas

@@ -10,13 +10,13 @@ unit Formatx.VfsPAK;
 *)
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,
   System.Contnrs,
   System.SysUtils,
-  GLX.Strings,
+  Scene.Strings,
   GLX.ApplicationFileIO;
 
 const

+ 4 - 3
Source/FMX/Formatx.X.pas

@@ -7,17 +7,18 @@ unit Formatx.X;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,
   System.SysUtils,
 
+  Scene.Strings,
+
   GLX.VectorTypes,
   GLX.VectorGeometry,
   GLX.VectorLists,
-  GLX.PersistentClasses,
-  GLX.Strings;
+  GLX.PersistentClasses;
 
 type
   TDXNode = class;

+ 0 - 2832
Source/FMX/Formatx.m3DS.pas

@@ -1,2832 +0,0 @@
-//
-// The graphics platform GLXcene https://github.com/glscene
-//
-unit Formatx.m3DS;
-
-(*
-  Implementation of an universal 3DS file reader (and writer). This is the main file of the
-  3DS import library. Currently only loading of 3DS files (Mesh files  * .3ds, Project files  * .prj
-  and Material files  * .mli) is supported.
-
-  Note: Be careful when using LoadFromStream, because chunk data (in opposition to the
-  chunk structure) will be loaded on demand, i.e. when it is needed. Therefore the
-  passed stream must be available during load.
-  LoadFromStream does not make a copy of the passed stream, but keeps a reference
-  which must stay valid either during the entire lifetime of TFile3DS or at least
-  'til all chunks have been read (by accessing them all once).
-*)
-
-interface
-
-{$I GLX.Scene.inc}
-
-{$ALIGN ON}
-{$MINENUMSIZE 4}
-{$RANGECHECKS OFF}
-
-uses
-  System.SysUtils,
-  System.Classes,
-
-  Formatx.m3DSTypes,
-  GLX.ApplicationFileIO;
-
-type
-  TFile3DS = class;
-
-  TLoadProgress = procedure(StreamPos, StreamMax: Longint) of object;
-  (* Progress : TProgressBar;
-   This allows to use something like that:
-
-   procedure TSomeForm.CreateForm(Sender: TObject);
-   begin
-   ....
-   3DSReader.OnProgress := LoadProgress;
-   ....
-   end;
-
-   procedure TSomeForm.LoadProgress(StreamPos, StreamMax : Longint);
-   begin
-   if StreamMax <> 0 then
-   Progress.MaxValue := StreamMax;
-   Progress.Position := StreamPos;
-   end; *)
-
-  (* All structure data of a 3DS file is actually held in TFile3DS.FDatabase as a
-     tree with lots of links across the various chunks.
-     For convinience and speed the data of the chunks is collected into some
-     special structures (FMaterialList etc.) and presented to the user
-     by the following helper classes: *)
-  TMaterialList = class
-  private
-    FOwner: TFile3DS;
-    FLocalList: TList;
-    function GetCount: Integer;
-    function GetMaterial(Index: Integer): PMaterial3DS;
-    function GetMaterialByName(const Name: String): PMaterial3DS;
-  public
-    constructor Create(AOwner: TFile3DS); virtual;
-    destructor Destroy; override;
-    procedure ClearList;
-     property Count: Integer read GetCount;
-    property Material[Index: Integer]: PMaterial3DS read GetMaterial; default;
-    property MaterialByName[const Name: String]: PMaterial3DS read GetMaterialByName;
-  end;
-
-  TObjectList = class
-  private
-    FOwner: TFile3DS;
-    FMeshList, 
-	FOmniList, 
-	FSpotList, 
-	FCameraList: TList;
-    function GetCamera(Index: Integer): PCamera3DS;
-    function GetCamCount: Integer;
-    function GetMeshObjectCount: Integer;
-    function GetMesh(Index: Integer): PMesh3DS;
-    function GetOmniCount: Integer;
-    function GetOmniLight(Index: Integer): PLight3DS;
-    function GetSpotCount: Integer;
-    function GetSpotLight(Index: Integer): PLight3DS;
-  public
-    constructor Create(AOwner: TFile3DS); virtual;
-    destructor Destroy; override;
-    procedure ClearLists;
-    property CameraCount: Integer read GetCamCount;
-    property MeshCount: Integer read GetMeshObjectCount;
-    property OmniLightCount: Integer read GetOmniCount;
-    property SpotLightCount: Integer read GetSpotCount;
-    property Mesh[Index: Integer]: PMesh3DS read GetMesh;
-    property Camera[Index: Integer]: PCamera3DS read GetCamera;
-    property OmniLight[Index: Integer]: PLight3DS read GetOmniLight;
-    property SpotLight[Index: Integer]: PLight3DS read GetSpotLight;
-  end;
-
-  TKeyFramer = class
-  private
-    FOwner: TFile3DS;
-    FMeshMotionList, 
-	FOmniMotionList, 
-	FSpotMotionList, 
-	FCameraMotionList: TList;
-    FAmbientMotion: PKFAmbient3DS;
-    function GetAmbientMotion: PKFAmbient3DS;
-    function GetCameraMotion(Index: Integer): PKFCamera3DS;
-    function GetCamMotionCount: Integer;
-    function GetKFSets: TKFSets3DS;
-    function GetMeshMotionCount: Integer;
-    function GetMeshMotion(Index: Integer): PKFMesh3DS;
-    function GetOmniMotionCount: Integer;
-    function GetOmniLightMotion(Index: Integer): PKFOmni3DS;
-    function GetSpotMotionCount: Integer;
-    function GetSpotLightMotion(Index: Integer): PKFSpot3DS;
-  public
-    constructor Create(AOwner: TFile3DS); virtual;
-    destructor Destroy; override;
-    procedure ClearLists;
-    property AmbientLightMotion: PKFAmbient3DS read GetAmbientMotion;
-    property CameraMotionCount: Integer read GetCamMotionCount;
-    property MeshMotionCount: Integer read GetMeshMotionCount;
-    property OmniLightMotionCount: Integer read GetOmniMotionCount;
-    property SpotLightMotionCount: Integer read GetSpotMotionCount;
-    property MeshMotion[Index: Integer]: PKFMesh3DS read GetMeshMotion; default;
-    property CameraMotion[Index: Integer]: PKFCamera3DS read GetCameraMotion;
-    property OmniLightMotion[Index: Integer]: PKFOmni3DS read GetOmniLightMotion;
-    property Settings: TKFSets3DS read GetKFSets;
-    property SpotLightMotion[Index: Integer]: PKFSpot3DS read GetSpotLightMotion;
-  end;
-
-  (* TFile3DS is the  main class and supplies the user with all available data
-   from a specific 3DS file. The data is currently read only, but the class might be
-   finished sometime later... *)
-  TFile3DS = class
-  private
-    FNodeList: PNodeList;
-    FDatabase: TDatabase3DS;
-    FStream: TStream;
-    FOwnStream: Boolean;
-    FMaterialList: TMaterialList;
-    FObjectList: TObjectList;
-    FKeyFramer: TKeyFramer;
-    FFileName: String;
-    FOnLoadProgress: TLoadProgress;
-    function GetAtmosphereData: TAtmosphere3DS;
-    function GetBackgroundData: TBackground3DS;
-    function GetDatabaseType: TDBType3DS;
-    function GetMeshSettings: TMeshSet3DS;
-    function GetViewportData: TViewport3DS;
-    function GetDatabaseRelease: TReleaseLevel;
-    function GetMeshRelease: TReleaseLevel;
-  protected
-    procedure AddToNodeList(Chunk: PChunk3DS);
-    procedure AssignParentNames;
-    procedure CheckListNodeIDs;
-    procedure CreateDatabase;
-    function FindNodeByID(ID: SmallInt): PNodeList;
-    function GetChunkNodeID(Chunk: PChunk3DS): SmallInt;
-    procedure InitDatabase;
-    function IsNode(Tag: Word): Boolean;
-    procedure KFAddParentName(Chunk: PChunk3DS; const Name: String3DS);
-    procedure MakeNode(var Node: PNodeList);
-    procedure ParseDatabase;
-    procedure ReadChildren(Parent: PChunk3DS);
-    procedure ReadXDataEntryChildren(Parent: PChunk3DS);
-    procedure ReleaseDatabase;
-    procedure ReleaseNodeList;
-    procedure ReleaseStream;
-  public
-    constructor Create; virtual;
-    constructor CreateFromFile(const FileName: String); virtual;
-    destructor Destroy; override;
-    procedure ClearLists;
-    // database methods
-    procedure DumpDataBase(Strings: TStrings; DumpLevel: TDumpLevel);
-    procedure LoadFromFile(const FileName: String);
-    procedure LoadFromStream(const aStream: TStream);
-    // basic access methods
-    function ReadByte: Byte;
-    function ReadCardinal: Cardinal;
-    procedure ReadChunkData(Chunk: PChunk3DS);
-    procedure ReadData(Size: Integer; Data: Pointer);
-    function ReadDouble: Double;
-    function ReadFace: TFace3DS;
-    procedure ReadHeader(var ChunkType: Word; var ChunkSize: Cardinal);
-    function ReadInteger: Integer;
-    function ReadKeyHeader: TKeyHeader3DS;
-    function ReadPoint: TPoint3DS;
-    function ReadShort: SmallInt;
-    function ReadSingle: Single;
-    function ReadString: PChar3DS;
-    function ReadTexVert: TTexVert3DS;
-    function ReadTrackHeader: TTrackHeader3DS;
-    function ReadWord: Word;
-    procedure FinishHeader(StartPos, EndPos: Cardinal);
-    function InitChunkData(Chunk: PChunk3DS): Pointer;
-    procedure SeekChild(Chunk: PChunk3DS);
-    procedure Skip(AValue: Integer);
-    procedure WriteByte(AValue: Byte);
-    procedure WriteCardinal(AValue: Cardinal);
-    procedure WriteData(Size: Integer; Data: Pointer);
-    procedure WriteDouble(AValue: Double);
-    procedure WriteFace(const F: TFace3DS);
-    procedure WriteFixedString(const AValue: String3DS; Len: Integer);
-    procedure WriteHeader(ChunkType: Word; ChunkSize: Cardinal);
-    procedure WriteInteger(AValue: Integer);
-    procedure WriteKeyHeader(const K: TKeyHeader3DS);
-    procedure WritePoint(const P: TPoint3DS);
-    procedure WriteShort(AValue: SmallInt);
-    procedure WriteSingle(AValue: Single);
-    procedure WriteString(const AValue: String3DS);
-    procedure WriteTexVertex(const T: TTexVert3DS);
-    procedure WriteTrackHeader(const T: TTrackHeader3DS);
-    procedure WriteWord(AValue: Word);
-    property Atmosphere: TAtmosphere3DS read GetAtmosphereData;
-    property Background: TBackground3DS read GetBackgroundData;
-    property DatabaseRelease: TReleaseLevel read GetDatabaseRelease;
-    property DatabaseType: TDBType3DS read GetDatabaseType;
-    property FileName: String read FFileName;
-    // this is only valid if loaded from a file
-    property KeyFramer: TKeyFramer read FKeyFramer;
-    property Materials: TMaterialList read FMaterialList;
-    property MeshRelease: TReleaseLevel read GetMeshRelease;
-    property MeshSettings: TMeshSet3DS read GetMeshSettings;
-    property Objects: TObjectList read FObjectList;
-    property Viewport: TViewport3DS read GetViewportData;
-    property OnLoadProgress: TLoadProgress read FOnLoadProgress write FOnLoadProgress;
-  end;
-
-
-// ---------------------------------------------------------------------------------------------------------------------
-implementation
-// ---------------------------------------------------------------------------------------------------------------------
-
-uses 
-  Formatx.m3DSConst,
-  Formatx.m3DSUtils;
-
-function StrPasFree(P: PChar3DS): String;
-begin
-  Result := string(StrPas(P));
-  FreeMem(P);
-end;
-
-// ----------------- TMaterialList -------------------------------------------------------------------------------------
-constructor TMaterialList.Create(AOwner: TFile3DS);
-
-begin
-  FOwner := AOwner;
-  FLocalList := TList.Create;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-destructor TMaterialList.Destroy;
-
-begin
-  ClearList;
-  FLocalList.Free;
-  inherited Destroy;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TMaterialList.ClearList;
-
-var
-  I: Integer;
-  Mat: PMaterial3DS;
-
-begin
-  for I := 0 to FLocalList.Count - 1 do
-    if FLocalList[I] <> nil then
-    begin
-      Mat := FLocalList[I];
-      // free structure data
-      ReleaseMaterial(Mat);
-    end;
-  FLocalList.Count := 0;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TMaterialList.GetCount: Integer;
-
-begin
-  if (FLocalList.Count = 0) and (FOwner.FDatabase.MatListDirty) then
-    FLocalList.Count := GetMaterialCount(FOwner, FOwner.FDatabase);;
-  Result := FLocalList.Count;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TMaterialList.GetMaterial(Index: Integer): PMaterial3DS;
-
-var
-  NewEntry: PMaterial3DS;
-
-begin
-  Result := nil;
-  if Count = 0 then
-    Exit; // force reading the list if it was modified
-
-  if FLocalList[Index] = nil then
-  begin
-    New(NewEntry);
-    FillChar(NewEntry^, SizeOf(NewEntry^), 0);
-    NewEntry^ := GetMaterialByIndex(FOwner, FOwner.FDatabase, Index);
-    FLocalList[Index] := NewEntry;
-  end;
-  Result := FLocalList[Index];
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TMaterialList.GetMaterialByName(const Name: String): PMaterial3DS;
-
-var
-  Entry: PMaterial3DS;
-  Index: Integer;
-
-begin
-  Result := nil;
-  for Index := 0 to Count - 1 do
-  begin
-    Entry := GetMaterial(Index);
-    if Entry = nil then
-      Continue;
-    if CompareText(string(Entry.NameStr), Name) = 0 then
-    begin
-      Result := Entry;
-      Break;
-    end;
-  end;
-end;
-
-// ----------------- TObjectList ---------------------------------------------------------------------------------------
-constructor TObjectList.Create(AOwner: TFile3DS);
-
-begin
-  FOwner := AOwner;
-  FMeshList := TList.Create;
-  FOmniList := TList.Create;
-  FSpotList := TList.Create;
-  FCameraList := TList.Create;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-destructor TObjectList.Destroy;
-
-begin
-  ClearLists;
-  FMeshList.Free;
-  FOmniList.Free;
-  FSpotList.Free;
-  FCameraList.Free;
-  inherited Destroy;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TObjectList.ClearLists;
-
-var
-  I: Integer;
-
-begin
-  for I := 0 to FMeshList.Count - 1 do
-    ReleaseMeshObj(FMeshList[I]);
-  FMeshList.Clear;
-
-  for I := 0 to FOmniList.Count - 1 do
-    ReleaseLight(FOmniList[I]);
-  FOmniList.Clear;
-
-  for I := 0 to FSpotList.Count - 1 do
-    ReleaseLight(FSpotList[I]);
-  FSpotList.Clear;
-
-  for I := 0 to FCameraList.Count - 1 do
-    ReleaseCamera(FCameraList[I]);
-  FCameraList.Clear;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TObjectList.GetCamera(Index: Integer): PCamera3DS;
-
-var
-  NewEntry: PCamera3DS;
-
-begin
-  Result := nil;
-  if CameraCount = 0 then
-    Exit; // force reading the list if it was modified
-
-  if FCameraList[Index] = nil then
-  begin
-    New(NewEntry);
-    FillChar(NewEntry^, SizeOf(NewEntry^), 0);
-    NewEntry^ := GetCameraByIndex(FOwner, FOwner.FDatabase, Index);
-    FCameraList[Index] := NewEntry;
-  end;
-  Result := FCameraList[Index];
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TObjectList.GetCamCount: Integer;
-
-begin
-  if FCameraList.Count = 0 then
-    FCameraList.Count := GetCameraCount(FOwner, FOwner.FDatabase);
-  Result := FCameraList.Count;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TObjectList.GetMeshObjectCount: Integer;
-
-begin
-  if FMeshList.Count = 0 then
-    FMeshList.Count := GetMeshCount(FOwner, FOwner.FDatabase);
-  Result := FMeshList.Count;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TObjectList.GetMesh(Index: Integer): PMesh3DS;
-
-var
-  NewEntry: PMesh3DS;
-
-begin
-  Result := nil;
-  if MeshCount = 0 then
-    Exit; // force reading the list if it was modified
-
-  if FMeshList[Index] = nil then
-  begin
-    New(NewEntry);
-    FillChar(NewEntry^, SizeOf(NewEntry^), 0);
-    NewEntry^ := GetMeshByIndex(FOwner, FOwner.FDatabase, Index);
-    FMeshList[Index] := NewEntry;
-  end;
-  Result := FMeshList[Index];
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TObjectList.GetOmniCount: Integer;
-
-begin
-  if FOmniList.Count = 0 then
-    FOmniList.Count := GetOmniLightCount(FOwner, FOwner.FDatabase);
-  Result := FOmniList.Count;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TObjectList.GetOmniLight(Index: Integer): PLight3DS;
-
-var
-  NewEntry: PLight3DS;
-
-begin
-  Result := nil;
-  if OmniLightCount = 0 then
-    Exit; // force reading the list if it was modified
-
-  if FOmniList[Index] = nil then
-  begin
-    New(NewEntry);
-    FillChar(NewEntry^, SizeOf(NewEntry^), 0);
-    NewEntry^ := GetOmniLightByIndex(FOwner, FOwner.FDatabase, Index);
-    FOmniList[Index] := NewEntry;
-  end;
-  Result := FOmniList[Index];
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-
-function TObjectList.GetSpotCount: Integer;
-
-begin
-  if FSpotList.Count = 0 then
-    FSpotList.Count := GetSpotLightCount(FOwner, FOwner.FDatabase);
-  Result := FSpotList.Count;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TObjectList.GetSpotLight(Index: Integer): PLight3DS;
-
-var
-  NewEntry: PLight3DS;
-
-begin
-  Result := nil;
-  if SpotLightCount = 0 then
-    Exit; // force reading the list if it was modified
-
-  if FSpotList[Index] = nil then
-  begin
-    New(NewEntry);
-    FillChar(NewEntry^, SizeOf(NewEntry^), 0);
-    NewEntry^ := GetSpotLightByIndex(FOwner, FOwner.FDatabase, Index);
-    FSpotList[Index] := NewEntry;
-  end;
-  Result := FSpotList[Index];
-end;
-
-// ----------------- TKeyFramer ----------------------------------------------------------------------------------------
-constructor TKeyFramer.Create(AOwner: TFile3DS);
-
-begin
-  FOwner := AOwner;
-  FMeshMotionList := TList.Create;
-  FOmniMotionList := TList.Create;
-  FSpotMotionList := TList.Create;
-  FCameraMotionList := TList.Create;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-destructor TKeyFramer.Destroy;
-
-begin
-  ClearLists;
-  FMeshMotionList.Free;
-  FOmniMotionList.Free;
-  FSpotMotionList.Free;
-  FCameraMotionList.Free;
-  inherited;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TKeyFramer.GetAmbientMotion: PKFAmbient3DS;
-
-begin
-  if FAmbientMotion = nil then
-  begin
-    New(FAmbientMotion);
-    FillChar(FAmbientMotion^, SizeOf(FAmbientMotion^), 0);
-    FAmbientMotion^ := GetAmbientLightMotion(FOwner, FOwner.FDatabase);
-  end;
-  Result := FAmbientMotion;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TKeyFramer.GetCameraMotion(Index: Integer): PKFCamera3DS;
-
-var
-  NewEntry: PKFCamera3DS;
-
-begin
-  Result := nil;
-  if CameraMotionCount = 0 then
-    Exit; // force reading the list if it was modified
-
-  if FCameraMotionList[Index] = nil then
-  begin
-    New(NewEntry);
-    FillChar(NewEntry^, SizeOf(NewEntry^), 0);
-    NewEntry^ := GetCameraMotionByIndex(FOwner, FOwner.FDatabase, Index);
-    FCameraMotionList[Index] := NewEntry;
-  end;
-  Result := FCameraMotionList[Index];
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TKeyFramer.GetCamMotionCount: Integer;
-
-begin
-  if FCameraMotionList.Count = 0 then
-    FCameraMotionList.Count := GetCameraNodeCount(FOwner, FOwner.FDatabase);
-  Result := FCameraMotionList.Count;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TKeyFramer.GetKFSets: TKFSets3DS;
-
-begin
-  Result := GetKFSettings(FOwner, FOwner.FDatabase);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TKeyFramer.GetMeshMotionCount: Integer;
-
-begin
-  if FMeshMotionList.Count = 0 then
-    FMeshMotionList.Count := GetObjectNodeCount(FOwner, FOwner.FDatabase);
-  Result := FMeshMotionList.Count;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TKeyFramer.GetMeshMotion(Index: Integer): PKFMesh3DS;
-
-var
-  NewEntry: PKFMesh3DS;
-
-begin
-  Result := nil;
-  if MeshMotionCount = 0 then
-    Exit; // force reading the list if it was modified
-
-  if FMeshMotionList[Index] = nil then
-  begin
-    New(NewEntry);
-    FillChar(NewEntry^, SizeOf(NewEntry^), 0);
-    NewEntry^ := GetObjectMotionByIndex(FOwner, FOwner.FDatabase, Index);
-    FMeshMotionList[Index] := NewEntry;
-  end;
-  Result := FMeshMotionList[Index];
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TKeyFramer.GetOmniMotionCount: Integer;
-
-begin
-  if FOmniMotionList.Count = 0 then
-    FOmniMotionList.Count := GetOmniLightNodeCount(FOwner, FOwner.FDatabase);
-  Result := FOmniMotionList.Count;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TKeyFramer.GetOmniLightMotion(Index: Integer): PKFOmni3DS;
-
-var
-  NewEntry: PKFOmni3DS;
-
-begin
-  Result := nil;
-  if OmniLightMotionCount = 0 then
-    Exit; // force reading the list if it was modified
-
-  if FOmniMotionList[Index] = nil then
-  begin
-    New(NewEntry);
-    FillChar(NewEntry^, SizeOf(NewEntry^), 0);
-    NewEntry^ := GetOmniLightMotionByIndex(FOwner, FOwner.FDatabase, Index);
-    FOmniMotionList[Index] := NewEntry;
-  end;
-  Result := FOmniMotionList[Index];
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TKeyFramer.GetSpotMotionCount: Integer;
-
-begin
-  if FSpotMotionList.Count = 0 then
-    FSpotMotionList.Count := GetSpotLightNodeCount(FOwner, FOwner.FDatabase);
-  Result := FSpotMotionList.Count;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TKeyFramer.GetSpotLightMotion(Index: Integer): PKFSpot3DS;
-
-var
-  NewEntry: PKFSpot3DS;
-
-begin
-  Result := nil;
-  if SpotLightMotionCount = 0 then
-    Exit; // force reading the list if it was modified
-
-  if FSpotMotionList[Index] = nil then
-  begin
-    New(NewEntry);
-    FillChar(NewEntry^, SizeOf(NewEntry^), 0);
-    NewEntry^ := GetSpotLightMotionByIndex(FOwner, FOwner.FDatabase, Index);
-    FSpotMotionList[Index] := NewEntry;
-  end;
-  Result := FSpotMotionList[Index];
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TKeyFramer.ClearLists;
-var
-  I: Integer;
-begin
-  for I := 0 to FMeshMotionList.Count - 1 do
-    ReleaseObjectMotion(FMeshMotionList[I]);
-  FMeshMotionList.Clear;
-  for I := 0 to FOmniMotionList.Count - 1 do
-    ReleaseOmnilightMotion(FOmniMotionList[I]);
-  FOmniMotionList.Clear;
-  for I := 0 to FSpotMotionList.Count - 1 do
-    ReleaseSpotlightMotion(FSpotMotionList[I]);
-  FSpotMotionList.Clear;
-  for I := 0 to FCameraMotionList.Count - 1 do
-    ReleaseCameraMotion(FCameraMotionList[I]);
-  FCameraMotionList.Clear;
-  if assigned(FAmbientMotion) then
-    ReleaseAmbientLightMotion(FAmbientMotion);
-  FAmbientMotion := nil;
-end;
-
-// ----------------- TFile3DS ------------------------------------------------------------------------------------------
-
-constructor TFile3DS.Create;
-
-begin
-  FMaterialList := TMaterialList.Create(Self);
-  FObjectList := TObjectList.Create(Self);
-  FKeyFramer := TKeyFramer.Create(Self);
-end;
-
-constructor TFile3DS.CreateFromFile(const FileName: String);
-begin
-  Create;
-  FFileName := FileName;
-  FStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
-  InitDatabase;
-  CreateDatabase;
-end;
-
-destructor TFile3DS.Destroy;
-begin
-  FKeyFramer.Free;
-  FObjectList.Free;
-  FMaterialList.Free;
-  ReleaseDatabase;
-  ReleaseStream;
-  inherited Destroy;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.AddToNodeList(Chunk: PChunk3DS);
-// create a node, put node in list and fill-in structure
-var
-  NewNode: PNodeList;
-  HdrChunk, InstChunk: PChunk3DS;
-
-begin
-  MakeNode(NewNode);
-  if NewNode = nil then
-    Exit;
-  HdrChunk := FindChunk(Chunk, NODE_HDR);
-  if HdrChunk = nil then
-    Exit;
-  ReadChunkData(HdrChunk);
-  if HdrChunk = nil then
-    Exit;
-  // fill in node Data
-  NewNode.Name := HdrChunk.Data.NodeHdr.ObjNameStr;
-  NewNode.ID := GetChunkNodeID(Chunk);
-  NewNode.Tag := Chunk.Tag;
-  NewNode.ParentID := HdrChunk.Data.NodeHdr.ParentIndex;
-  NewNode.Next := nil;
-  NewNode.InstStr := '';
-
-  // check for instance
-  if Chunk.Tag = OBJECT_NODE_TAG then
-  begin
-    InstChunk := FindChunk(Chunk, INSTANCE_NAME);
-    if assigned(InstChunk) then
-    begin
-      ReadChunkData(InstChunk);
-      NewNode.InstStr := string(StrPas(InstChunk.Data.InstanceName));
-      FreeChunkData(InstChunk);
-    end;
-  end;
-  HdrChunk.Data.NodeHdr.ObjNameStr := '';
-  FreeChunkData(HdrChunk);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.AssignParentNames;
-
-// traverse keyframe data and assign parent names to its own chunk PARENT_NAME
-// which is a child of NODE_HDR
-
-var
-  Chunk, KfDataChunk, HdrChunk, NameChunk, IdChunk: PChunk3DS;
-  I: Integer;
-  IDNode, IDParentNode: PNodeList;
-  Name, Inst: String3DS;
-
-begin
-  KfDataChunk := FindChunk(FDatabase.TopChunk, KFDATA);
-  if KfDataChunk = nil then
-    Exit;
-
-  // Find chunks in KFRAMER
-  for I := 1 to NodeTagCount do
-  begin
-    Chunk := FindChunk(KfDataChunk, NodeTags[I]);
-    while assigned(Chunk) do
-    begin
-      HdrChunk := FindChunk(Chunk, NODE_HDR);
-      if assigned(HdrChunk) then
-      begin
-        IdChunk := FindChunk(Chunk, NODE_ID);
-        if assigned(IdChunk) then
-        begin
-          ReadChunkData(IdChunk);
-          if assigned(IdChunk.Data.KFID) then
-          begin
-            // Find table entry for node of interest
-            IDNode := FindNodeByID(IdChunk.Data.KFID^);
-            // no ID (bad) or no parent (ok)
-            if assigned(IDNode) and (IDNode.ParentID <> -1) then
-            begin
-              // find table entry for parent
-              IDParentNode := FindNodeByID(IDNode.ParentID);
-              if assigned(IDParentNode) then
-              begin
-                Name := UTF8String(IDParentNode.Name);
-                Inst := UTF8String(IDParentNode.InstStr);
-              end;
-
-              if Length(Name) > 0 then
-              begin
-                // concatenate names if there is an inst name
-                if Length(Inst) > 0 then
-                  Name := Name + '.' + Inst;
-
-                // if PARENT chunk exists, copy into it
-                NameChunk := FindChunk(HdrChunk, PARENT_NAME);
-                if assigned(NameChunk) then
-                begin
-                  ReadChunkData(NameChunk);
-                  if assigned(NameChunk.Data.InstanceName) then
-                  begin
-                    NameChunk.Data.InstanceName := AllocMem(Length(Name) + 1);
-                    Move(Name[1], NameChunk.Data.InstanceName^, Length(Name) + 1);
-                  end;
-                end
-                else
-                  KFAddParentName(HdrChunk, Name); // create PARENT_NAME chunk
-              end;
-            end;
-          end;
-        end;
-      end;
-      Chunk := FindNextChunk(Chunk.Sibling, NodeTags[I]);
-    end;
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.CheckListNodeIDs;
-
-// Earlier versions (pre 3) of 3dStudio had no node ids, they simply used the order
-// in which they came along, if so put in NODE IDs. Assuming that if one node
-// has no ID the whole list get renumbered.
-
-var
-  ID: PNodeList;
-  Index: SmallInt;
-begin
-  ID := FNodeList;
-
-  while assigned(ID) do
-  begin
-    if (ID.ID = KNoID) then // if somebody has no ID renumber list
-    begin
-      Index := 0;
-      ID := FNodeList;
-      while assigned(ID) do
-      begin
-        ID.ID := Index;
-        Inc(Index);
-        ID := ID.Next;
-      end;
-      Break;
-    end;
-    ID := ID.Next;
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-
-function TFile3DS.FindNodeByID(ID: SmallInt): PNodeList;
-
-begin
-  Result := FNodeList;
-  while assigned(Result) do
-  begin
-    if Result.ID = ID then
-      Break;
-    Result := Result.Next;
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.DumpDataBase(Strings: TStrings; DumpLevel: TDumpLevel);
-
-// dumps entire database into the given string class
-var
-  OldSeparator: Char;
-begin
-  OldSeparator := FormatSettings.DecimalSeparator;
-  FormatSettings.DecimalSeparator := '.';
-  try
-    if assigned(FDatabase.TopChunk) then
-      DumpChunk(Self, Strings, FDatabase.TopChunk, 0, DumpLevel);
-  finally
-  	FormatSettings.DecimalSeparator := OldSeparator;
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.GetChunkNodeID(Chunk: PChunk3DS): SmallInt;
-var
-  IdChunk: PChunk3DS;
-begin
-  Result := KNoID;
-  IdChunk := FindChunk(Chunk, NODE_ID);
-  if assigned(IdChunk) then
-  begin
-    ReadChunkData(IdChunk);
-    if assigned(IdChunk.Data.KFID) then
-      Result := IdChunk.Data.KFID^;
-    FreeChunkData(IdChunk);
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.IsNode(Tag: Word): Boolean;
-var
-  I: Integer;
-begin
-  Result := False;
-  for I := 1 to NodeTagCount do
-    if Tag = NodeTags[I] then
-    begin
-      Result := True;
-      Break;
-    end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-
-procedure TFile3DS.KFAddParentName(Chunk: PChunk3DS; const Name: String3DS);
-var
-  Temp: PChunk3DS;
-begin
-  InitChunk(Temp);
-  Temp.Tag := PARENT_NAME;
-  Temp.Data.Dummy := AllocMem(Length(Name) + 1);
-  Move(Name[1], Temp.Data.Dummy^, Length(Name) + 1);
-  AddChildOrdered(Chunk, Temp);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.MakeNode(var Node: PNodeList);
-// add node to linked list (uninitialized)
-var
-  ID: PNodeList;
-begin
-  ID := FNodeList;
-  Node := AllocMem(SizeOf(TNodeList));
-  if assigned(Node) then
-  begin
-    // first node ?
-    if ID = nil then
-      FNodeList := Node
-    else // add to list
-    begin
-      while assigned(ID.Next) do
-        ID := ID.Next;
-      ID.Next := Node;
-    end;
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.ParseDatabase;
-var
-  Chunk, KfDataChunk: PChunk3DS;
-begin
-  KfDataChunk := FindChunk(FDatabase.TopChunk, KFDATA);
-  if assigned(KfDataChunk) then
-  begin
-    Chunk := KfDataChunk.Children;
-    while assigned(Chunk) do
-    begin
-      if IsNode(Chunk.Tag) then
-        AddToNodeList(Chunk);
-      Chunk := Chunk.Sibling;
-    end;
-    CheckListNodeIDs;
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.ReadXDataEntryChildren(Parent: PChunk3DS);
-var
-  ParentBody: Cardinal;
-  Child: PChunk3DS;
-
-begin
-  SeekChild(Parent);
-  ParentBody := Parent.Position + Parent.Size;
-
-  // satisfy the D4 compiler by castíng the (longint) position to a cardinal
-  while Cardinal(FStream.Position) < ParentBody do
-  begin
-    Child := nil;
-    InitChunk(Child);
-    Child.Position := FStream.Position;
-    ReadHeader(Child.Tag, Child.Size);
-    // Validate the child chunk...
-    // First, is it a valid header?
-    case Child.Tag of
-      XDATA_APPNAME, 
-	  XDATA_STRING, 
-	  XDATA_FLOAT, 
-	  XDATA_DOUBLE, 
-	  XDATA_SHORT,
-      XDATA_LONG, 
-	  XDATA_VOID, 
-	  XDATA_GROUP, 
-	  XDATA_RFU6, 
-	  XDATA_RFU5, 
-	  XDATA_RFU4,
-      XDATA_RFU3, 
-	  XDATA_RFU2, 
-	  XDATA_RFU1:
-        begin
-          // second, does the size fit inside the XDATA_ENTRY chunk?
-          if (Child.Position + Child.Size) <= ParentBody then
-          begin
-            // chances are its a good subchunk, so add it in
-            AddChild(Parent, Child);
-            ReadXDataEntryChildren(Child);
-          end
-          else
-            ReleaseChunk(Child);
-        end
-    else // must not be a valid chunk, seek to the end of the parent then
-      begin
-        ReleaseChunk(Child);
-        FStream.Position := ParentBody;
-      end;
-    end;
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.ReleaseNodeList;
-
-var
-  Next: PNodeList;
-
-begin
-  while assigned(FNodeList) do
-  begin
-    Next := FNodeList.Next;
-    Dispose(FNodeList);
-    FNodeList := Next;
-  end;
-end;
-
-procedure TFile3DS.ReleaseStream;
-begin
-  if FOwnStream then
-    FreeAndNil(FStream)
-  else
-    FStream := nil;
-  FOwnStream := False;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.CreateDatabase;
-
-begin
-  with FDatabase do
-  begin
-    InitChunk(TopChunk);
-    FStream.Position := 0;
-    ReadHeader(TopChunk.Tag, TopChunk.Size);
-
-    // test header to determine whether it is a top level chunk type
-    if (TopChunk.Tag = M3DMAGIC) or (TopChunk.Tag = CMAGIC) or
-      (TopChunk.Tag = MLIBMAGIC) then
-    begin
-      // gw: set needed max value for ProgressBar
-      if assigned(FOnLoadProgress) then
-        FOnLoadProgress(0, FStream.Size);
-      // read database structure
-      ReadChildren(TopChunk);
-      ParseDatabase;
-      AssignParentNames;
-      ReleaseNodeList;
-    end;
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.InitDatabase;
-
-begin
-  with FDatabase do
-  begin
-    TopChunk := nil;
-    ObjListDirty := True;
-    MatListDirty := True;
-    NodeListDirty := True;
-    ObjList := nil;
-    MatList := nil;
-    NodeList := nil;
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.ClearLists;
-
-begin
-  FMaterialList.ClearList;
-  FObjectList.ClearLists;
-  FKeyFramer.ClearLists;
-  ReleaseDatabase;
-end;
-
-procedure TFile3DS.LoadFromFile(const FileName: String);
-begin
-  ClearLists;
-  ReleaseStream;
-  FFileName := FileName;
-  FStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
-  FOwnStream := True;
-  InitDatabase;
-  CreateDatabase;
-end;
-
-procedure TFile3DS.LoadFromStream(const aStream: TStream);
-begin
-  ReleaseStream;
-  ClearLists;
-  FFileName := '';
-  FStream := aStream;
-  InitDatabase;
-  CreateDatabase;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.GetAtmosphereData: TAtmosphere3DS;
-begin
-  Result := GetAtmosphere(Self, FDatabase);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.GetBackgroundData: TBackground3DS;
-
-begin
-  Result := GetBackground(Self, FDatabase);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.GetDatabaseType: TDBType3DS;
-
-begin
-  case FDatabase.TopChunk.Tag of
-    M3DMAGIC:
-      Result := dbMeshFile;
-    CMAGIC:
-      Result := dbProjectFile;
-    MLIBMAGIC:
-      Result := dbMaterialFile;
-  else
-    Result := dbUnknown;
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.GetMeshSettings: TMeshSet3DS;
-begin
-  Result := GetMeshSet(Self, FDatabase);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.GetViewportData: TViewport3DS;
-begin
-  Result := GetViewport(Self, FDatabase);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.ReadChildren(Parent: PChunk3DS);
-var
-  ParentBody: Integer;
-  Child: PChunk3DS;
-begin
-  SeekChild(Parent);
-  ParentBody := Parent.Position + Parent.Size;
-  while FStream.Position < ParentBody do
-  begin
-    Child := nil;
-    InitChunk(Child);
-    // gw: set ProgressBar current position
-    if assigned(FOnLoadProgress) then
-      FOnLoadProgress(FStream.Position, 0);
-
-    Child.Position := FStream.Position;
-    ReadHeader(Child.Tag, Child.Size);
-    AddChild(Parent, Child);
-    if Child.Tag = XDATA_ENTRY then
-      ReadXDataEntryChildren(Child)
-    else
-      ReadChildren(Child);
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.ReleaseDatabase;
-begin
-  with FDatabase do
-  begin
-    if assigned(TopChunk) then
-      ReleaseChunk(TopChunk);
-    if assigned(ObjList) then
-      ReleaseChunkList(ObjList);
-    if assigned(MatList) then
-      ReleaseChunkList(MatList);
-    if assigned(NodeList) then
-      ReleaseChunkList(NodeList);
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.InitChunkData(Chunk: PChunk3DS): Pointer;
-begin
-  case Chunk.Tag of
-    COLOR_F:
-      Chunk.Data.ColorF := AllocMem(SizeOf(TColorF));
-    LIN_COLOR_F:
-      Chunk.Data.LinColorF := AllocMem(SizeOf(TLinColorF));
-    COLOR_24:
-      Chunk.Data.Color24 := AllocMem(SizeOf(TColor24));
-    LIN_COLOR_24:
-      Chunk.Data.LinColor24 := AllocMem(SizeOf(TLinColor24));
-    INT_PERCENTAGE:
-      Chunk.Data.IntPercentage := AllocMem(SizeOf(TIntPercentage));
-    FLOAT_PERCENTAGE:
-      Chunk.Data.FloatPercentage := AllocMem(SizeOf(TFloatPercentage));
-    MAT_MAPNAME:
-      Chunk.Data.MatMapname := nil; // AllocMem(SizeOf(TMatMapname));
-    M3D_VERSION:
-      Chunk.Data.M3dVersion := AllocMem(SizeOf(TM3dVersion));
-    MESH_VERSION:
-      Chunk.Data.MeshVersion := AllocMem(SizeOf(TMeshVersion));
-    MASTER_SCALE:
-      Chunk.Data.MasterScale := AllocMem(SizeOf(TMasterScale));
-    LO_SHADOW_BIAS:
-      Chunk.Data.LoShadowBias := AllocMem(SizeOf(TLoShadowBias));
-    SHADOW_FILTER:
-      Chunk.Data.ShadowFilter := AllocMem(SizeOf(TShadowFilter));
-    SHADOW_RANGE:
-      Chunk.Data.ShadowRange := AllocMem(SizeOf(TShadowRange));
-    HI_SHADOW_BIAS:
-      Chunk.Data.HiShadowBias := AllocMem(SizeOf(THiShadowBias));
-    RAY_BIAS:
-      Chunk.Data.RayBias := AllocMem(SizeOf(TRayBias));
-    SHADOW_MAP_SIZE:
-      Chunk.Data.ShadowMapSize := AllocMem(SizeOf(TShadowMapSize));
-    SHADOW_SAMPLES:
-      Chunk.Data.ShadowSamples := AllocMem(SizeOf(TShadowSamples));
-    O_CONSTS:
-      Chunk.Data.OConsts := AllocMem(SizeOf(TOConsts));
-    BIT_MAP:
-      Chunk.Data.BitMapName := nil; // AllocMem(SizeOf(TBitMapName));
-    V_GRADIENT:
-      Chunk.Data.VGradient := AllocMem(SizeOf(TVGradient));
-    FOG:
-      Chunk.Data.FOG := AllocMem(SizeOf(TFog));
-    LAYER_FOG:
-      Chunk.Data.LayerFog := AllocMem(SizeOf(TLayerFog));
-    DISTANCE_CUE:
-      Chunk.Data.DistanceCue := AllocMem(SizeOf(TDistanceCue));
-    VIEW_TOP, 
-	VIEW_BOTTOM, 
-	VIEW_LEFT, 
-	VIEW_RIGHT, 
-	VIEW_FRONT, 
-	VIEW_BACK:
-      Chunk.Data.ViewStandard := AllocMem(SizeOf(TViewStandard));
-    VIEW_USER:
-      Chunk.Data.ViewUser := AllocMem(SizeOf(TViewUser));
-    VIEW_CAMERA:
-      Chunk.Data.ViewCamera := nil; // AllocMem(SizeOf(TViewCamera));
-    MAT_NAME:
-      Chunk.Data.MatName := nil; // AllocMem(SizeOf(TMatName));
-    MAT_SHADING:
-      Chunk.Data.MatShading := AllocMem(SizeOf(TMatShading));
-    MAT_ACUBIC:
-      Chunk.Data.MatAcubic := AllocMem(SizeOf(TMatAcubic));
-    MAT_SXP_TEXT_DATA, 
-	MAT_SXP_TEXT2_DATA, 
-	MAT_SXP_OPAC_DATA, 
-	MAT_SXP_BUMP_DATA,
-    MAT_SXP_SPEC_DATA, 
-	MAT_SXP_SHIN_DATA, 
-	MAT_SXP_SELFI_DATA,
-    MAT_SXP_TEXT_MASKDATA, 
-	MAT_SXP_TEXT2_MASKDATA, 
-	MAT_SXP_OPAC_MASKDATA,
-    MAT_SXP_BUMP_MASKDATA, 
-	MAT_SXP_SPEC_MASKDATA, 
-	MAT_SXP_SHIN_MASKDATA,
-    MAT_SXP_SELFI_MASKDATA, 
-	MAT_SXP_REFL_MASKDATA, 
-	PROC_DATA:
-      Chunk.Data.IpasData := AllocMem(SizeOf(TIpasData));
-    MAT_WIRESIZE:
-      Chunk.Data.MatWireSize := AllocMem(SizeOf(TMatWireSize));
-    MAT_MAP_TILING:
-      Chunk.Data.MatMapTiling := AllocMem(SizeOf(TMatMapTiling));
-    MAT_MAP_TEXBLUR:
-      Chunk.Data.MatMapTexblur := AllocMem(SizeOf(TMatMapTexblur));
-    MAT_MAP_USCALE:
-      Chunk.Data.MatMapUScale := AllocMem(SizeOf(TMatMapUScale));
-    MAT_MAP_VSCALE:
-      Chunk.Data.MatMapVScale := AllocMem(SizeOf(TMatMapVScale));
-    MAT_MAP_UOFFSET:
-      Chunk.Data.MatMapUOffset := AllocMem(SizeOf(TMatMapUOffset));
-    MAT_MAP_VOFFSET:
-      Chunk.Data.MatMapVOffset := AllocMem(SizeOf(TMatMapVOffset));
-    MAT_MAP_ANG:
-      Chunk.Data.MatMapAng := AllocMem(SizeOf(TMatMapAng));
-    MAT_MAP_COL1:
-      Chunk.Data.MatMapCol1 := AllocMem(SizeOf(TMatMapCol1));
-    MAT_MAP_COL2:
-      Chunk.Data.MatMapCol2 := AllocMem(SizeOf(TMatMapCol2));
-    MAT_MAP_RCOL:
-      Chunk.Data.MatMapRCol := AllocMem(SizeOf(TMatMapRCol));
-    MAT_MAP_GCOL:
-      Chunk.Data.MatMapGCol := AllocMem(SizeOf(TMatMapGCol));
-    MAT_MAP_BCOL:
-      Chunk.Data.MatMapBCol := AllocMem(SizeOf(TMatMapBCol));
-    MAT_BUMP_PERCENT:
-      Chunk.Data.MatBumpPercent := AllocMem(SizeOf(TMatBumpPercent));
-    NAMED_OBJECT:
-      Chunk.Data.NamedObject := nil; // AllocMem(SizeOf(TNamedObject));
-    POINT_ARRAY:
-      Chunk.Data.PointArray := AllocMem(SizeOf(TPointArray));
-    POINT_FLAG_ARRAY:
-      Chunk.Data.PointFlagArray := AllocMem(SizeOf(TPointFlagArray));
-    FACE_ARRAY:
-      Chunk.Data.FaceArray := AllocMem(SizeOf(TFaceArray));
-    MSH_MAT_GROUP:
-      Chunk.Data.MshMatGroup := AllocMem(SizeOf(TMshMatGroup));
-    MSH_BOXMAP:
-      Chunk.Data.MshBoxmap := AllocMem(SizeOf(TMshBoxmap));
-    SMOOTH_GROUP:
-      Chunk.Data.SmoothGroup := AllocMem(SizeOf(TSmoothGroup));
-    TEX_VERTS:
-      Chunk.Data.TexVerts := AllocMem(SizeOf(TTexVerts));
-    MESH_MATRIX:
-      Chunk.Data.MeshMatrix := AllocMem(SizeOf(TMeshMatrix));
-    MESH_COLOR:
-      Chunk.Data.MeshColor := AllocMem(SizeOf(TMeshColor));
-    MESH_TEXTURE_INFO:
-      Chunk.Data.MeshTextureInfo := AllocMem(SizeOf(TMeshTextureInfo));
-    PROC_NAME:
-      Chunk.Data.ProcName := nil; // AllocMem(SizeOf(TProcName));
-    N_DIRECT_LIGHT:
-      Chunk.Data.NDirectLight := AllocMem(SizeOf(TNDirectLight));
-    DL_EXCLUDE:
-      Chunk.Data.DlExclude := nil; // AllocMem(SizeOf(TDlExclude));
-    DL_INNER_RANGE:
-      Chunk.Data.DlInnerRange := AllocMem(SizeOf(TDlInnerRange));
-    DL_OUTER_RANGE:
-      Chunk.Data.DlOuterRange := AllocMem(SizeOf(TDlOuterRange));
-    DL_MULTIPLIER:
-      Chunk.Data.DlMultiplier := AllocMem(SizeOf(TDlMultiplier));
-    DL_SPOTLIGHT:
-      Chunk.Data.DlSpotlight := AllocMem(SizeOf(TDlSpotlight));
-    DL_LOCAL_SHADOW2:
-      Chunk.Data.DlLocalShadow2 := AllocMem(SizeOf(TDlLocalShadow2));
-    DL_SPOT_ROLL:
-      Chunk.Data.DlSpotRoll := AllocMem(SizeOf(TDlSpotRoll));
-    DL_SPOT_ASPECT:
-      Chunk.Data.DlSpotAspect := AllocMem(SizeOf(TDlSpotAspect));
-    DL_SPOT_PROJECTOR:
-      Chunk.Data.DlSpotProjector := nil; // AllocMem(SizeOf(TDlSpotProjector));
-    DL_RAY_BIAS:
-      Chunk.Data.DlRayBias := AllocMem(SizeOf(TDlRayBias));
-    N_CAMERA:
-      Chunk.Data.NCamera := AllocMem(SizeOf(TNCamera));
-    CAM_RANGES:
-      Chunk.Data.CamRanges := AllocMem(SizeOf(TCamRanges));
-    VIEWPORT_LAYOUT:
-      Chunk.Data.ViewportLayout := AllocMem(SizeOf(TViewportLayout));
-    VIEWPORT_SIZE:
-      Chunk.Data.ViewportSize := AllocMem(SizeOf(TViewportSize));
-    VIEWPORT_DATA_3, 
-	VIEWPORT_DATA:
-      Chunk.Data.ViewportData := AllocMem(SizeOf(TViewportData));
-    XDATA_ENTRY:
-      Chunk.Data.XDataEntry := AllocMem(SizeOf(TXDataEntry));
-    XDATA_APPNAME:
-      Chunk.Data.XDataAppName := nil; // AllocMem(SizeOf(TXDataAppName));
-    XDATA_STRING:
-      Chunk.Data.XDataString := nil; // AllocMem(SizeOf(TXDataString));
-    KFHDR:
-      Chunk.Data.KFHDR := AllocMem(SizeOf(TKFHdr));
-    KFSEG:
-      Chunk.Data.KFSEG := AllocMem(SizeOf(TKFSeg));
-    KFCURTIME:
-      Chunk.Data.KFCURTIME := AllocMem(SizeOf(TKFCurtime));
-    NODE_ID:
-      Chunk.Data.KFID := AllocMem(SizeOf(TKFId));
-    NODE_HDR:
-      Chunk.Data.NodeHdr := AllocMem(SizeOf(TNodeHdr));
-    PIVOT:
-      Chunk.Data.PIVOT := AllocMem(SizeOf(TPivot));
-    INSTANCE_NAME, PARENT_NAME:
-      Chunk.Data.InstanceName := nil; // AllocMem(SizeOf(TInstanceName));
-    MORPH_SMOOTH:
-      Chunk.Data.MorphSmooth := AllocMem(SizeOf(TMorphSmooth));
-    BOUNDBOX:
-      Chunk.Data.BOUNDBOX := AllocMem(SizeOf(TBoundBox));
-    POS_TRACK_TAG:
-      Chunk.Data.PosTrackTag := AllocMem(SizeOf(TPosTrackTag));
-    COL_TRACK_TAG:
-      Chunk.Data.ColTrackTag := AllocMem(SizeOf(TColTrackTag));
-    ROT_TRACK_TAG:
-      Chunk.Data.RotTrackTag := AllocMem(SizeOf(TRotTrackTag));
-    SCL_TRACK_TAG:
-      Chunk.Data.ScaleTrackTag := AllocMem(SizeOf(TScaleTrackTag));
-    MORPH_TRACK_TAG:
-      Chunk.Data.MorphTrackTag := AllocMem(SizeOf(TMorphTrackTag));
-    FOV_TRACK_TAG:
-      Chunk.Data.FovTrackTag := AllocMem(SizeOf(TFovTrackTag));
-    ROLL_TRACK_TAG:
-      Chunk.Data.RollTrackTag := AllocMem(SizeOf(TRollTrackTag));
-    HOT_TRACK_TAG:
-      Chunk.Data.HotTrackTag := AllocMem(SizeOf(THotTrackTag));
-    FALL_TRACK_TAG:
-      Chunk.Data.FallTrackTag := AllocMem(SizeOf(TFallTrackTag));
-    HIDE_TRACK_TAG:
-      Chunk.Data.HideTrackTag := AllocMem(SizeOf(THideTrackTag));
-    M3DMAGIC, // Chunks who consist entirely of children
-    MLIBMAGIC, 
-	MDATA, 
-	AMBIENT_LIGHT, 
-	SOLID_BGND, 
-	DEFAULT_VIEW, 
-	MAT_ENTRY,
-    MAT_AMBIENT, 
-	MAT_DIFFUSE, 
-	MAT_SPECULAR, 
-	MAT_SHININESS, 
-	MAT_SHIN2PCT,
-    MAT_SHIN3PCT, 
-	MAT_TRANSPARENCY, 
-	MAT_XPFALL, 
-	MAT_REFBLUR, 
-	MAT_SELF_ILPCT,
-    MAT_TEXMAP, 
-	MAT_TEXMASK, 
-	MAT_TEX2MAP, 
-	MAT_TEX2MASK, 
-	MAT_OPACMAP,
-    MAT_OPACMASK, 
-	MAT_REFLMAP, 
-	MAT_REFLMASK, 
-	MAT_BUMPMAP, 
-	MAT_BUMPMASK,
-    MAT_SPECMAP, 
-	MAT_SPECMASK, 
-	MAT_SHINMAP, 
-	MAT_SHINMASK, 
-	MAT_SELFIMAP,
-    MAT_SELFIMASK, 
-	N_TRI_OBJECT, 
-	KFDATA, 
-	AMBIENT_NODE_TAG, 
-	OBJECT_NODE_TAG,
-    CAMERA_NODE_TAG, 
-	TARGET_NODE_TAG, 
-	LIGHT_NODE_TAG, 
-	SPOTLIGHT_NODE_TAG,
-    L_TARGET_NODE_TAG, 
-	CMAGIC, 
-	XDATA_SECTION, 
-	XDATA_GROUP:
-      Chunk.Data.Dummy := nil;
-  else // A truely hideous thing to do but it helps with unknown chunks
-    // Don't mess with dataless chunks
-    if Chunk.Size > 6 then
-      Chunk.Data.Dummy := AllocMem(Chunk.Size - 6)
-    else
-      Chunk.Data.Dummy := nil;
-  end; // end of case
-  Result := Chunk.Data.Dummy; // returns the pointer should someone want it
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.WriteByte(AValue: Byte);
-begin
-  FStream.WriteBuffer(AValue, 1);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.ReadByte: Byte;
-
-begin
-  FStream.ReadBuffer(Result, 1);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.WriteShort(AValue: SmallInt);
-begin
-  FStream.WriteBuffer(AValue, SizeOf(AValue));
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.ReadShort: SmallInt;
-
-begin
-  FStream.ReadBuffer(Result, SizeOf(Result));
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.ReadCardinal: Cardinal;
-
-begin
-  FStream.ReadBuffer(Result, SizeOf(Result));
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.ReadDouble: Double;
-begin
-  FStream.ReadBuffer(Result, SizeOf(Result));
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-
-function TFile3DS.ReadInteger: Integer;
-begin
-  FStream.ReadBuffer(Result, SizeOf(Result));
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.ReadSingle: Single;
-begin
-  FStream.ReadBuffer(Result, SizeOf(Result));
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.ReadWord: Word;
-begin
-  FStream.ReadBuffer(Result, SizeOf(Result));
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.WriteCardinal(AValue: Cardinal);
-begin
-  FStream.WriteBuffer(AValue, SizeOf(AValue));
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.WriteDouble(AValue: Double);
-begin
-  FStream.WriteBuffer(AValue, SizeOf(AValue));
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.WriteInteger(AValue: Integer);
-begin
-  FStream.WriteBuffer(AValue, SizeOf(AValue));
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.WriteSingle(AValue: Single);
-begin
-  FStream.WriteBuffer(AValue, SizeOf(AValue));
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.WriteWord(AValue: Word);
-begin
-  FStream.WriteBuffer(AValue, SizeOf(AValue));
-end;
-
-procedure TFile3DS.WriteData(Size: Integer; Data: Pointer);
-begin
-  if assigned(Data) then
-    FStream.WriteBuffer(Data^, Size);
-end;
-
-procedure TFile3DS.ReadData(Size: Integer; Data: Pointer);
-begin
-  FStream.ReadBuffer(Data^, Size);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.Skip(AValue: Integer);
-begin
-  FStream.Seek(soFromCurrent, AValue);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.WriteString(const AValue: String3DS);
-begin
-  WriteData(Length(AValue), @AValue[1]);
-  WriteByte(0); // Write a null on the end of the string
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.WriteFixedString(const AValue: String3DS; Len: Integer);
-var
-  I: Integer;
-begin
-  // len is the length of the target string space including null
-  WriteString(AValue); // 1 null byte will also be written
-  for I := 1 to Len - Length(AValue) - 1 do
-    WriteByte(0); // fill the remaining space with nulls
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.ReadString: PChar3DS;
-var
-  Len, LB: Integer;
-  Buffer: String3DS;
-begin
-  Len := 0;
-  LB := 0;
-  repeat
-    if Len >= LB then
-    begin
-      Inc(LB, 50);
-      SetLength(Buffer, LB);
-    end;
-    Inc(Len);
-    FStream.Read(Buffer[Len], 1);
-  until Buffer[Len] = #0;
-  Result := AllocMem(Len);
-  Move(Buffer[1], Result^, Len);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.WriteHeader(ChunkType: Word; ChunkSize: Cardinal);
-
-begin
-  WriteWord(ChunkType);
-  WriteCardinal(ChunkSize);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.ReadHeader(var ChunkType: Word; var ChunkSize: Cardinal);
-
-begin
-  ChunkType := ReadWord;
-  ChunkSize := ReadCardinal;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.FinishHeader(StartPos, EndPos: Cardinal);
-
-begin
-  FStream.Position := StartPos + 2;
-  WriteCardinal(EndPos - StartPos);
-  FStream.Position := EndPos;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-
-procedure TFile3DS.WritePoint(const P: TPoint3DS);
-
-begin
-  WriteSingle(P.X);
-  WriteSingle(P.Y);
-  WriteSingle(P.Z);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.ReadPoint: TPoint3DS;
-begin
-  Result := DefPoint3DS;
-  FStream.ReadBuffer(Result, SizeOf(Result));
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-
-procedure TFile3DS.WriteTexVertex(const T: TTexVert3DS);
-
-begin
-  WriteSingle(T.U);
-  WriteSingle(T.V);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.ReadTexVert: TTexVert3DS;
-begin
-  Result := DefTextVert3DS;
-  Result.U := ReadSingle;
-  Result.V := ReadSingle;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-
-procedure TFile3DS.WriteFace(const F: TFace3DS);
-
-begin
-  WriteWord(F.v1);
-  WriteWord(F.v2);
-  WriteWord(F.v3);
-  WriteWord(F.flag);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.ReadFace: TFace3DS;
-begin
-  Result := DefFace3DS;
-  Result.v1 := ReadWord;
-  Result.v2 := ReadWord;
-  Result.v3 := ReadWord;
-  Result.flag := ReadWord;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-
-procedure TFile3DS.WriteTrackHeader(const T: TTrackHeader3DS);
-
-begin
-  WriteWord(T.Flags);
-  WriteCardinal(T.nu1);
-  WriteCardinal(T.nu2);
-  WriteCardinal(T.KeyCount);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.ReadTrackHeader: TTrackHeader3DS;
-begin
-  Result := DefTrackHeader3DS;
-  Result.Flags := ReadWord;
-  Result.nu1 := ReadCardinal;
-  Result.nu2 := ReadCardinal;
-  Result.KeyCount := ReadCardinal;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-
-procedure TFile3DS.WriteKeyHeader(const K: TKeyHeader3DS);
-
-begin
-  WriteCardinal(K.time);
-  WriteWord(K.rflags);
-  if (K.rflags and KeyUsesTension3DS) > 0 then
-    WriteSingle(K.tension);
-  if (K.rflags and KeyUsesCont3DS) > 0 then
-    WriteSingle(K.continuity);
-  if (K.rflags and KeyUsesBias3DS) > 0 then
-    WriteSingle(K.bias);
-  if (K.rflags and KeyUsesEaseTo3DS) > 0 then
-    WriteSingle(K.easeto);
-  if (K.rflags and KeyUsesEaseFrom3DS) > 0 then
-    WriteSingle(K.easefrom);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.ReadKeyHeader: TKeyHeader3DS;
-begin
-  Result := DefKeyHeader3DS;
-  Result.time := ReadCardinal;
-  Result.rflags := ReadWord;
-  if (Result.rflags and KeyUsesTension3DS) > 0 then
-    Result.tension := ReadSingle;
-  if (Result.rflags and KeyUsesCont3DS) > 0 then
-    Result.continuity := ReadSingle;
-  if (Result.rflags and KeyUsesBias3DS) > 0 then
-    Result.bias := ReadSingle;
-  if (Result.rflags and KeyUsesEaseTo3DS) > 0 then
-    Result.easeto := ReadSingle;
-  if (Result.rflags and KeyUsesEaseFrom3DS) > 0 then
-    Result.easefrom := ReadSingle;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.ReadChunkData(Chunk: PChunk3DS);
-
-// Reads the data out of the chunk detailed in Chunk and places a pointer to
-// the data into the PChunk3DS structure, it will also return that pointer.
-
-var
-  I: Integer;
-begin
-  if Chunk.Data.Dummy = nil then
-  // don't try to read the data if its already been read
-  begin
-    // seek to the beginning of the Chunk's data (harmless if the Chunk has no data)
-    FStream.Position := Chunk.Position + 6;
-    case Chunk.Tag of
-      COLOR_F:
-        begin
-          Chunk.Data.ColorF := AllocMem(SizeOf(TColorF));
-          // allocate the memory to hold the data
-          with Chunk.Data.ColorF^ do
-          begin
-            Red := ReadSingle; // Read the data out of the file
-            Green := ReadSingle;
-            Blue := ReadSingle;
-          end;
-        end;
-      LIN_COLOR_F:
-        begin
-          Chunk.Data.LinColorF := AllocMem(SizeOf(TLinColorF));
-          with Chunk.Data.LinColorF^ do
-          begin
-            Red := ReadSingle;
-            Green := ReadSingle;
-            Blue := ReadSingle;
-          end;
-        end;
-      COLOR_24:
-        begin
-          Chunk.Data.Color24 := AllocMem(SizeOf(TColor24));
-          with Chunk.Data.Color24^ do
-          begin
-            Red := ReadByte;
-            Green := ReadByte;
-            Blue := ReadByte;
-          end;
-        end;
-      LIN_COLOR_24:
-        begin
-          Chunk.Data.LinColor24 := AllocMem(SizeOf(TLinColor24));
-          with Chunk.Data.LinColor24^ do
-          begin
-            Red := ReadByte;
-            Green := ReadByte;
-            Blue := ReadByte;
-          end;
-        end;
-      INT_PERCENTAGE:
-        begin
-          Chunk.Data.IntPercentage := AllocMem(SizeOf(TIntPercentage));
-          Chunk.Data.IntPercentage^ := ReadShort;
-        end;
-      FLOAT_PERCENTAGE:
-        begin
-          Chunk.Data.FloatPercentage := AllocMem(SizeOf(TFloatPercentage));
-          Chunk.Data.FloatPercentage^ := ReadSingle;
-        end;
-      MAT_MAPNAME:
-        begin
-          // Chunk.Data.MatMapname := AllocMem(SizeOf(TMatMapname));
-          Chunk.Data.MatMapname := ReadString;
-        end;
-      M3D_VERSION:
-        begin
-          Chunk.Data.M3dVersion := AllocMem(SizeOf(TM3dVersion));
-          Chunk.Data.M3dVersion^ := ReadInteger;
-        end;
-      MESH_VERSION:
-        begin
-          Chunk.Data.MeshVersion := AllocMem(SizeOf(TMeshVersion));
-          Chunk.Data.MeshVersion^ := ReadInteger;
-        end;
-      MASTER_SCALE:
-        begin
-          Chunk.Data.MasterScale := AllocMem(SizeOf(TMasterScale));
-          Chunk.Data.MasterScale^ := ReadSingle;
-        end;
-      LO_SHADOW_BIAS:
-        begin
-          Chunk.Data.LoShadowBias := AllocMem(SizeOf(TLoShadowBias));
-          Chunk.Data.LoShadowBias^ := ReadSingle;
-        end;
-      SHADOW_FILTER:
-        begin
-          Chunk.Data.ShadowFilter := AllocMem(SizeOf(TShadowFilter));
-          Chunk.Data.ShadowFilter^ := ReadSingle;
-        end;
-      SHADOW_RANGE:
-        begin
-          Chunk.Data.ShadowRange := AllocMem(SizeOf(TShadowRange));
-          Chunk.Data.ShadowRange^ := ReadInteger;
-        end;
-      HI_SHADOW_BIAS:
-        begin
-          Chunk.Data.HiShadowBias := AllocMem(SizeOf(THiShadowBias));
-          Chunk.Data.HiShadowBias^ := ReadSingle;
-        end;
-      RAY_BIAS:
-        begin
-          Chunk.Data.RayBias := AllocMem(SizeOf(TRayBias));
-          Chunk.Data.RayBias^ := ReadSingle;
-        end;
-      SHADOW_MAP_SIZE:
-        begin
-          Chunk.Data.ShadowMapSize := AllocMem(SizeOf(TShadowMapSize));
-          Chunk.Data.ShadowMapSize^ := ReadShort;
-        end;
-      SHADOW_SAMPLES:
-        begin
-          Chunk.Data.ShadowSamples := AllocMem(SizeOf(TShadowSamples));
-          Chunk.Data.ShadowSamples^ := ReadShort;
-        end;
-      O_CONSTS:
-        begin
-          Chunk.Data.OConsts := AllocMem(SizeOf(TOConsts));
-          Chunk.Data.OConsts^ := ReadPoint;
-        end;
-      BIT_MAP:
-        begin
-          // Chunk.Data.BitMapName := AllocMem(SizeOf(TBitMapName));
-          Chunk.Data.BitMapName := ReadString;
-        end;
-      V_GRADIENT:
-        begin
-          Chunk.Data.VGradient := AllocMem(SizeOf(TVGradient));
-          Chunk.Data.VGradient^ := ReadSingle;
-        end;
-      FOG:
-        begin
-          Chunk.Data.FOG := AllocMem(SizeOf(TFog));
-          with Chunk.Data.FOG^ do
-          begin
-            NearPlaneDist := ReadSingle;
-            NearPlaneDensity := ReadSingle;
-            FarPlaneDist := ReadSingle;
-            FarPlaneDensity := ReadSingle;
-          end;
-        end;
-      LAYER_FOG:
-        begin
-          Chunk.Data.LayerFog := AllocMem(SizeOf(TLayerFog));
-          with Chunk.Data.LayerFog^ do
-          begin
-            ZMin := ReadSingle;
-            ZMax := ReadSingle;
-            Density := ReadSingle;
-            AType := ReadCardinal;
-          end;
-        end;
-      DISTANCE_CUE:
-        begin
-          Chunk.Data.DistanceCue := AllocMem(SizeOf(TDistanceCue));
-          with Chunk.Data.DistanceCue^ do
-          begin
-            NearPlaneDist := ReadSingle;
-            NearPlaneDimming := ReadSingle;
-            FarPlaneDist := ReadSingle;
-            FarPlaneDimming := ReadSingle;
-          end;
-        end;
-      VIEW_TOP, 
-	  VIEW_BOTTOM, 
-	  VIEW_LEFT, 
-	  VIEW_RIGHT, 
-	  VIEW_FRONT, 
-	  VIEW_BACK:
-        begin
-          Chunk.Data.ViewStandard := AllocMem(SizeOf(TViewStandard));
-          with Chunk.Data.ViewStandard^ do
-          begin
-            ViewWidth := ReadSingle;
-            ViewTargetCoord := ReadPoint;
-          end;
-        end;
-      VIEW_USER:
-        begin
-          Chunk.Data.ViewUser := AllocMem(SizeOf(TViewUser));
-          with Chunk.Data.ViewUser^ do
-          begin
-            ViewWidth := ReadSingle;
-            XYViewAngle := ReadSingle;
-            YZViewAngle := ReadSingle;
-            BankAngle := ReadSingle;
-            ViewTargetCoord := ReadPoint;
-          end;
-        end;
-      VIEW_CAMERA:
-        begin
-          // Chunk.Data.ViewCamera := AllocMem(SizeOf(TViewCamera));
-          Chunk.Data.ViewCamera := ReadString;
-        end;
-      MAT_NAME:
-        begin
-          // Chunk.Data.MatName := AllocMem(SizeOf(TMatName));
-          Chunk.Data.MatName := ReadString;
-        end;
-      MAT_SHADING:
-        begin
-          Chunk.Data.MatShading := AllocMem(SizeOf(TMatShading));
-          FStream.Position := Chunk.Position + 6;
-          Chunk.Data.MatShading^ := ReadShort;
-        end;
-      MAT_ACUBIC:
-        begin
-          Chunk.Data.MatAcubic := AllocMem(SizeOf(TMatAcubic));
-          with Chunk.Data.MatAcubic^ do
-          begin
-            ShadeLevel := ReadByte;
-            AntiAlias := ReadByte;
-            Flags := ReadShort;
-            MapSize := ReadCardinal;
-            FrameInterval := ReadCardinal;
-          end;
-        end;
-      MAT_SXP_TEXT_DATA, 
-	  MAT_SXP_TEXT2_DATA, 
-	  MAT_SXP_OPAC_DATA,
-      MAT_SXP_BUMP_DATA, 
-	  MAT_SXP_SPEC_DATA, 
-	  MAT_SXP_SHIN_DATA,
-      MAT_SXP_SELFI_DATA, 
-	  MAT_SXP_TEXT_MASKDATA, 
-	  MAT_SXP_TEXT2_MASKDATA,
-      MAT_SXP_OPAC_MASKDATA, 
-	  MAT_SXP_BUMP_MASKDATA, 
-	  MAT_SXP_SPEC_MASKDATA,
-      MAT_SXP_SHIN_MASKDATA, 
-	  MAT_SXP_SELFI_MASKDATA, 
-	  MAT_SXP_REFL_MASKDATA,
-        PROC_DATA:
-        begin
-          Chunk.Data.IpasData := AllocMem(SizeOf(TIpasData));
-          with Chunk.Data.IpasData^ do
-          begin
-            Size := Chunk.Size - 6;
-            Data := AllocMem(Size);
-            ReadData(Size, Data);
-          end;
-        end;
-      MAT_WIRESIZE:
-        begin
-          Chunk.Data.MatWireSize := AllocMem(SizeOf(TMatWireSize));
-          Chunk.Data.MatWireSize^ := ReadSingle;
-        end;
-      MAT_MAP_TILING:
-        begin
-          Chunk.Data.MatMapTiling := AllocMem(SizeOf(TMatMapTiling));
-          Chunk.Data.MatMapTiling^ := ReadWord;
-        end;
-      MAT_MAP_TEXBLUR:
-        begin
-          Chunk.Data.MatMapTexblur := AllocMem(SizeOf(TMatMapTexblur));
-          Chunk.Data.MatMapTexblur^ := ReadSingle;
-        end;
-      MAT_MAP_USCALE:
-        begin
-          Chunk.Data.MatMapUScale := AllocMem(SizeOf(TMatMapUScale));
-          Chunk.Data.MatMapUScale^ := ReadSingle;
-        end;
-      MAT_MAP_VSCALE:
-        begin
-          Chunk.Data.MatMapVScale := AllocMem(SizeOf(TMatMapVScale));
-          Chunk.Data.MatMapVScale^ := ReadSingle;
-        end;
-      MAT_MAP_UOFFSET:
-        begin
-          Chunk.Data.MatMapUOffset := AllocMem(SizeOf(TMatMapUOffset));
-          Chunk.Data.MatMapUOffset^ := ReadSingle;
-        end;
-      MAT_MAP_VOFFSET:
-        begin
-          Chunk.Data.MatMapVOffset := AllocMem(SizeOf(TMatMapVOffset));
-          Chunk.Data.MatMapVOffset^ := ReadSingle;
-        end;
-      MAT_MAP_ANG:
-        begin
-          Chunk.Data.MatMapAng := AllocMem(SizeOf(TMatMapAng));
-          Chunk.Data.MatMapAng^ := ReadSingle;
-        end;
-      MAT_MAP_COL1:
-        begin
-          Chunk.Data.MatMapCol1 := AllocMem(SizeOf(TMatMapCol1));
-          with Chunk.Data.MatMapCol1^ do
-          begin
-            Red := ReadByte;
-            Green := ReadByte;
-            Blue := ReadByte;
-          end;
-        end;
-      MAT_MAP_COL2:
-        begin
-          Chunk.Data.MatMapCol2 := AllocMem(SizeOf(TMatMapCol2));
-          with Chunk.Data.MatMapCol2^ do
-          begin
-            Red := ReadByte;
-            Green := ReadByte;
-            Blue := ReadByte;
-          end;
-        end;
-      MAT_MAP_RCOL:
-        begin
-          Chunk.Data.MatMapRCol := AllocMem(SizeOf(TMatMapRCol));
-          with Chunk.Data.MatMapRCol^ do
-          begin
-            Red := ReadByte;
-            Green := ReadByte;
-            Blue := ReadByte;
-          end;
-        end;
-      MAT_MAP_GCOL:
-        begin
-          Chunk.Data.MatMapGCol := AllocMem(SizeOf(TMatMapGCol));
-          with Chunk.Data.MatMapGCol^ do
-          begin
-            Red := ReadByte;
-            Green := ReadByte;
-            Blue := ReadByte;
-          end;
-        end;
-      MAT_MAP_BCOL:
-        begin
-          Chunk.Data.MatMapBCol := AllocMem(SizeOf(TMatMapBCol));
-          with Chunk.Data.MatMapBCol^ do
-          begin
-            Red := ReadByte;
-            Green := ReadByte;
-            Blue := ReadByte;
-          end;
-        end;
-      MAT_BUMP_PERCENT:
-        begin
-          Chunk.Data.MatBumpPercent := AllocMem(SizeOf(TMatBumpPercent));
-          Chunk.Data.MatBumpPercent^ := ReadShort;
-        end;
-      NAMED_OBJECT:
-        begin
-          // Chunk.Data.NamedObject := AllocMem(SizeOf(TNamedObject));
-          Chunk.Data.NamedObject := ReadString;
-        end;
-      POINT_ARRAY:
-        begin
-          Chunk.Data.PointArray := AllocMem(SizeOf(TPointArray));
-          with Chunk.Data.PointArray^ do
-          begin
-            Vertices := ReadWord;
-            PointList := AllocMem(Vertices * SizeOf(TPoint3DS));
-            // for I := 0 to Vertices - 1 do PointList[I] := ReadPoint;
-            ReadData(Vertices * SizeOf(TPoint3DS), PointList);
-          end;
-        end;
-      POINT_FLAG_ARRAY:
-        begin
-          Chunk.Data.PointFlagArray := AllocMem(SizeOf(TPointFlagArray));
-          with Chunk.Data.PointFlagArray^ do
-          begin
-            Flags := ReadWord;
-            FlagList := AllocMem(Flags * SizeOf(SmallInt));
-            // for I := 0 to Flags - 1 do FlagList[I] := ReadShort;
-            ReadData(Flags * SizeOf(SmallInt), FlagList);
-          end;
-        end;
-      FACE_ARRAY:
-        begin
-          Chunk.Data.FaceArray := AllocMem(SizeOf(TFaceArray));
-          with Chunk.Data.FaceArray^ do
-          begin
-            Faces := ReadWord;
-            FaceList := AllocMem(Faces * SizeOf(TFace3DS));
-            // for I := 0 to Faces - 1 do FaceList[I] := ReadFace;
-            ReadData(Faces * SizeOf(TFace3DS), FaceList);
-          end;
-        end;
-      MSH_MAT_GROUP:
-        begin
-          Chunk.Data.MshMatGroup := AllocMem(SizeOf(TMshMatGroup));
-          with Chunk.Data.MshMatGroup^ do
-          begin
-            MatNameStr := AnsiString(StrPasFree(ReadString));
-            Faces := ReadWord;
-            if Faces > 0 then
-            begin
-              FaceList := AllocMem(Faces * SizeOf(Word));
-              // for I := 0 to Faces - 1 do FaceList[I] := ReadWord;
-              ReadData(Faces * SizeOf(Word), FaceList);
-            end
-            else
-              FaceList := nil;
-          end;
-        end;
-      MSH_BOXMAP:
-        begin
-          Chunk.Data.MshBoxmap := AllocMem(SizeOf(TMshBoxmap));
-          for I := 0 to 5 do
-            Chunk.Data.MshBoxmap[I] := ReadString;
-        end;
-      SMOOTH_GROUP:
-        begin
-          Chunk.Data.SmoothGroup := AllocMem(SizeOf(TSmoothGroup));
-          with Chunk.Data.SmoothGroup^ do
-          begin
-            Groups := (Chunk.Size - 6) div 4;
-            GroupList := AllocMem(Groups * SizeOf(Cardinal));
-            // for I := 0 to Groups - 1 do GroupList[I] := ReadCardinal;
-            ReadData(Groups * SizeOf(Cardinal), GroupList);
-          end;
-        end;
-      TEX_VERTS:
-        begin
-          Chunk.Data.TexVerts := AllocMem(SizeOf(TTexVerts));
-          with Chunk.Data.TexVerts^ do
-          begin
-            NumCoords := ReadWord;
-            TextVertList := AllocMem(NumCoords * SizeOf(TTexVert3DS));
-            // for I := 0 to NumCoords - 1 do TextVertList[I] := ReadTexVert;
-            ReadData(NumCoords * SizeOf(TTexVert3DS), TextVertList);
-          end;
-        end;
-      MESH_MATRIX:
-        begin
-          Chunk.Data.MeshMatrix := AllocMem(SizeOf(TMeshMatrix));
-          for I := 0 to 11 do
-            Chunk.Data.MeshMatrix[I] := ReadSingle;
-        end;
-      MESH_COLOR:
-        begin
-          Chunk.Data.MeshColor := AllocMem(SizeOf(TMeshColor));
-          Chunk.Data.MeshColor^ := ReadByte;
-        end;
-      MESH_TEXTURE_INFO:
-        begin
-          Chunk.Data.MeshTextureInfo := AllocMem(SizeOf(TMeshTextureInfo));
-          with Chunk.Data.MeshTextureInfo^ do
-          begin
-            MapType := ReadWord;
-            XTiling := ReadSingle;
-            YTiling := ReadSingle;
-            IconPos := ReadPoint();
-            IconScaling := ReadSingle;
-            for I := 0 to 11 do
-              XMatrix[I] := ReadSingle;
-            IconWidth := ReadSingle;
-            IconHeight := ReadSingle;
-            CylIconHeight := ReadSingle;
-          end;
-        end;
-      PROC_NAME:
-        begin
-          // Chunk.Data.ProcName := AllocMem(SizeOf(TProcName));
-          Chunk.Data.ProcName := ReadString;
-        end;
-      N_DIRECT_LIGHT:
-        begin
-          Chunk.Data.NDirectLight := AllocMem(SizeOf(TNDirectLight));
-          Chunk.Data.NDirectLight^ := ReadPoint;
-        end;
-      DL_EXCLUDE:
-        begin
-          // Chunk.Data.DlExclude := AllocMem(SizeOf(TDlExclude));
-          Chunk.Data.DlExclude := ReadString;
-        end;
-      DL_INNER_RANGE:
-        begin
-          Chunk.Data.DlInnerRange := AllocMem(SizeOf(TDlInnerRange));
-          Chunk.Data.DlInnerRange^ := ReadSingle;
-        end;
-      DL_OUTER_RANGE:
-        begin
-          Chunk.Data.DlOuterRange := AllocMem(SizeOf(TDlOuterRange));
-          Chunk.Data.DlOuterRange^ := ReadSingle;
-        end;
-      DL_MULTIPLIER:
-        begin
-          Chunk.Data.DlMultiplier := AllocMem(SizeOf(TDlMultiplier));
-          Chunk.Data.DlMultiplier^ := ReadSingle;
-        end;
-      DL_SPOTLIGHT:
-        begin
-          Chunk.Data.DlSpotlight := AllocMem(SizeOf(TDlSpotlight));
-          with Chunk.Data.DlSpotlight^ do
-          begin
-            SpotlightTarg := ReadPoint;
-            HotspotAngle := ReadSingle;
-            FalloffAngle := ReadSingle;
-          end;
-        end;
-      DL_LOCAL_SHADOW2:
-        begin
-          Chunk.Data.DlLocalShadow2 := AllocMem(SizeOf(TDlLocalShadow2));
-          with Chunk.Data.DlLocalShadow2^ do
-          begin
-            LocalShadowBias := ReadSingle;
-            LocalShadowFilter := ReadSingle;
-            LocalShadowMapSize := ReadShort;
-          end;
-        end;
-      DL_SPOT_ROLL:
-        begin
-          Chunk.Data.DlSpotRoll := AllocMem(SizeOf(TDlSpotRoll));
-          Chunk.Data.DlSpotRoll^ := ReadSingle;
-        end;
-      DL_SPOT_ASPECT:
-        begin
-          Chunk.Data.DlSpotAspect := AllocMem(SizeOf(TDlSpotAspect));
-          Chunk.Data.DlSpotAspect^ := ReadSingle;
-        end;
-      DL_SPOT_PROJECTOR:
-        begin
-          // Chunk.Data.DlSpotProjector := AllocMem(SizeOf(TDlSpotProjector));
-          Chunk.Data.DlSpotProjector := ReadString;
-        end;
-      DL_RAY_BIAS:
-        begin
-          Chunk.Data.DlRayBias := AllocMem(SizeOf(TDlRayBias));
-          Chunk.Data.DlRayBias^ := ReadSingle;
-        end;
-      N_CAMERA:
-        begin
-          Chunk.Data.NCamera := AllocMem(SizeOf(TNCamera));
-          with Chunk.Data.NCamera^ do
-          begin
-            CameraPos := ReadPoint;
-            TargetPos := ReadPoint;
-            CameraBank := ReadSingle;
-            CameraFocalLength := ReadSingle;
-          end;
-        end;
-      CAM_RANGES:
-        begin
-          Chunk.Data.CamRanges := AllocMem(SizeOf(TCamRanges));
-          with Chunk.Data.CamRanges^ do
-          begin
-            NearPlane := ReadSingle;
-            FarPlane := ReadSingle;
-          end;
-        end;
-      VIEWPORT_LAYOUT:
-        begin
-          Chunk.Data.ViewportLayout := AllocMem(SizeOf(TViewportLayout));
-          with Chunk.Data.ViewportLayout^ do
-          begin
-            Form := ReadShort;
-            Top := ReadShort;
-            Ready := ReadShort;
-            WState := ReadShort;
-            SwapWS := ReadShort;
-            SwapPort := ReadShort;
-            SwapCur := ReadShort;
-          end;
-        end;
-      VIEWPORT_SIZE:
-        begin
-          Chunk.Data.ViewportSize := AllocMem(SizeOf(TViewportSize));
-          with Chunk.Data.ViewportSize^ do
-          begin
-            XPos := ReadWord;
-            YPos := ReadWord;
-            Width := ReadWord;
-            Height := ReadWord;
-          end;
-        end;
-      VIEWPORT_DATA_3, 
-	  VIEWPORT_DATA:
-        begin
-          Chunk.Data.ViewportData := AllocMem(SizeOf(TViewportData));
-          with Chunk.Data.ViewportData^ do
-          begin
-            Flags := ReadShort;
-            AxisLockout := ReadShort;
-            WinXPos := ReadShort;
-            WinYPos := ReadShort;
-            WinWidth := ReadShort;
-            WinHeight := ReadShort;
-            View := ReadShort;
-            ZoomFactor := ReadSingle;
-            Center := ReadPoint;
-            HorizAng := ReadSingle;
-            VertAng := ReadSingle;
-            CamNameStr := AnsiString(StrPasFree(ReadString));
-          end;
-        end;
-      XDATA_ENTRY:
-        begin
-          InitChunkData(Chunk);
-          with Chunk.Data.XDataEntry^ do
-          begin
-            Size := (Chunk.Size) - 6;
-            Data := AllocMem(Size);
-            ReadData(Size, Data);
-          end;
-        end;
-      XDATA_APPNAME:
-        begin
-          Chunk.Data.XDataAppName := ReadString;
-        end;
-      XDATA_STRING:
-        begin
-          Chunk.Data.XDataString := ReadString;
-        end;
-      KFHDR:
-        begin
-          Chunk.Data.KFHDR := AllocMem(SizeOf(TKFHdr));
-          with Chunk.Data.KFHDR^ do
-          begin
-            Revision := ReadShort;
-            FileName := StrPasFree(ReadString);
-            AnimLength := ReadInteger;
-          end;
-        end;
-      KFSEG:
-        begin
-          Chunk.Data.KFSEG := AllocMem(SizeOf(TKFSeg));
-          with Chunk.Data.KFSEG^ do
-          begin
-            First := ReadInteger;
-            Last := ReadInteger;
-          end;
-        end;
-      KFCURTIME:
-        begin
-          Chunk.Data.KFCURTIME := AllocMem(SizeOf(TKFCurtime));
-          Chunk.Data.KFCURTIME^ := ReadInteger;
-        end;
-      NODE_ID:
-        begin
-          Chunk.Data.KFID := AllocMem(SizeOf(TKFId));
-          Chunk.Data.KFID^ := ReadShort;
-        end;
-      NODE_HDR:
-        begin
-          Chunk.Data.NodeHdr := AllocMem(SizeOf(TNodeHdr));
-          with Chunk.Data.NodeHdr^ do
-          begin
-            ObjNameStr := StrPasFree(ReadString);
-            Flags1 := ReadWord;
-            Flags2 := ReadWord;
-            ParentIndex := ReadShort;
-          end;
-        end;
-      PIVOT:
-        begin
-          Chunk.Data.PIVOT := AllocMem(SizeOf(TPivot));
-          Chunk.Data.PIVOT^ := ReadPoint;
-        end;
-      INSTANCE_NAME:
-        begin
-          Chunk.Data.InstanceName := ReadString;
-        end;
-      PARENT_NAME:
-        ; // do nothing
-      MORPH_SMOOTH:
-        begin
-          Chunk.Data.MorphSmooth := AllocMem(SizeOf(TMorphSmooth));
-          Chunk.Data.MorphSmooth^ := ReadSingle;
-        end;
-      BOUNDBOX:
-        begin
-          Chunk.Data.BOUNDBOX := AllocMem(SizeOf(TBoundBox));
-          with Chunk.Data.BOUNDBOX^ do
-          begin
-            Min := ReadPoint;
-            Max := ReadPoint;
-          end;
-        end;
-      POS_TRACK_TAG:
-        begin
-          Chunk.Data.PosTrackTag := AllocMem(SizeOf(TPosTrackTag));
-          with Chunk.Data.PosTrackTag^ do
-          begin
-            TrackHdr := ReadTrackHeader;
-            KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
-            PositionList := AllocMem(TrackHdr.KeyCount * SizeOf(TPoint3DS));
-            for I := 0 to TrackHdr.KeyCount - 1 do
-            begin
-              KeyHdrList[I] := ReadKeyHeader;
-              PositionList[I] := ReadPoint;
-            end;
-          end;
-        end;
-      COL_TRACK_TAG:
-        begin
-          Chunk.Data.ColTrackTag := AllocMem(SizeOf(TColTrackTag));
-          with Chunk.Data.ColTrackTag^ do
-          begin
-            TrackHdr := ReadTrackHeader;
-            ColorList := AllocMem(TrackHdr.KeyCount * SizeOf(TFColor3DS));
-            KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
-            for I := 0 to TrackHdr.KeyCount - 1 do
-            begin
-              KeyHdrList[I] := ReadKeyHeader;
-              ColorList[I].R := ReadSingle;
-              ColorList[I].G := ReadSingle;
-              ColorList[I].B := ReadSingle;
-            end;
-          end;
-        end;
-      ROT_TRACK_TAG:
-        begin
-          Chunk.Data.RotTrackTag := AllocMem(SizeOf(TRotTrackTag));
-          with Chunk.Data.RotTrackTag^ do
-          begin
-            TrackHdr := ReadTrackHeader;
-            KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
-            RotationList := AllocMem(TrackHdr.KeyCount * SizeOf(TKFrotkey3DS));
-            for I := 0 to TrackHdr.KeyCount - 1 do
-            begin
-              KeyHdrList[I] := ReadKeyHeader;
-              RotationList[I].Angle := ReadSingle;
-              RotationList[I].X := ReadSingle;
-              RotationList[I].Y := ReadSingle;
-              RotationList[I].Z := ReadSingle;
-            end;
-          end;
-        end;
-      SCL_TRACK_TAG:
-        begin
-          Chunk.Data.ScaleTrackTag := AllocMem(SizeOf(TScaleTrackTag));
-          with Chunk.Data.ScaleTrackTag^ do
-          begin
-            TrackHdr := ReadTrackHeader;
-            KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
-            ScaleList := AllocMem(TrackHdr.KeyCount * SizeOf(TPoint3DS));
-            for I := 0 to TrackHdr.KeyCount - 1 do
-            begin
-              KeyHdrList[I] := ReadKeyHeader;
-              ScaleList[I].X := ReadSingle;
-              ScaleList[I].Y := ReadSingle;
-              ScaleList[I].Z := ReadSingle;
-            end;
-          end;
-        end;
-      MORPH_TRACK_TAG:
-        begin
-          Chunk.Data.MorphTrackTag := AllocMem(SizeOf(TMorphTrackTag));
-          with Chunk.Data.MorphTrackTag^ do
-          begin
-            TrackHdr := ReadTrackHeader;
-            KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
-            MorphList := AllocMem(TrackHdr.KeyCount * SizeOf(TKFmorphKey3DS));
-            for I := 0 to TrackHdr.KeyCount - 1 do
-            begin
-              KeyHdrList[I] := ReadKeyHeader;
-              MorphList[I] := StrPasFree(ReadString);
-            end;
-          end;
-        end;
-      FOV_TRACK_TAG:
-        begin
-          Chunk.Data.FovTrackTag := AllocMem(SizeOf(TFovTrackTag));
-          with Chunk.Data.FovTrackTag^ do
-          begin
-            TrackHdr := ReadTrackHeader;
-            KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
-            FOVAngleList := AllocMem(TrackHdr.KeyCount * SizeOf(Single));
-            for I := 0 to TrackHdr.KeyCount - 1 do
-            begin
-              KeyHdrList[I] := ReadKeyHeader;
-              FOVAngleList[I] := ReadSingle;
-            end;
-          end;
-        end;
-      ROLL_TRACK_TAG:
-        begin
-          Chunk.Data.RollTrackTag := AllocMem(SizeOf(TRollTrackTag));
-          with Chunk.Data.RollTrackTag^ do
-          begin
-            TrackHdr := ReadTrackHeader;
-            KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
-            RollAngleList := AllocMem(TrackHdr.KeyCount * SizeOf(Single));
-            for I := 0 to TrackHdr.KeyCount - 1 do
-            begin
-              KeyHdrList[I] := ReadKeyHeader;
-              RollAngleList[I] := ReadSingle;
-            end;
-          end;
-        end;
-      HOT_TRACK_TAG:
-        begin
-          Chunk.Data.HotTrackTag := AllocMem(SizeOf(THotTrackTag));
-          with Chunk.Data.HotTrackTag^ do
-          begin
-            TrackHdr := ReadTrackHeader;
-            KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
-            HotspotAngleList := AllocMem(TrackHdr.KeyCount * SizeOf(Single));
-            for I := 0 to TrackHdr.KeyCount - 1 do
-            begin
-              KeyHdrList[I] := ReadKeyHeader;
-              HotspotAngleList[I] := ReadSingle;
-            end;
-          end;
-        end;
-      FALL_TRACK_TAG:
-        begin
-          Chunk.Data.FallTrackTag := AllocMem(SizeOf(TFallTrackTag));
-          with Chunk.Data.FallTrackTag^ do
-          begin
-            TrackHdr := ReadTrackHeader;
-            KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
-            FalloffAngleList := AllocMem(TrackHdr.KeyCount * SizeOf(Single));
-            for I := 0 to TrackHdr.KeyCount - 1 do
-            begin
-              KeyHdrList[I] := ReadKeyHeader;
-              FalloffAngleList[I] := ReadSingle;
-            end;
-          end;
-        end;
-      HIDE_TRACK_TAG:
-        begin
-          Chunk.Data.HideTrackTag := AllocMem(SizeOf(THideTrackTag));
-          with Chunk.Data.HideTrackTag^ do
-          begin
-            TrackHdr := ReadTrackHeader;
-            KeyHdrList := AllocMem(TrackHdr.KeyCount * SizeOf(TKeyHeader3DS));
-            for I := 0 to TrackHdr.KeyCount - 1 do
-              KeyHdrList[I] := ReadKeyHeader;
-          end;
-        end;
-      M3DMAGIC, // Chunks that do not contain data, or only contain children
-      MLIBMAGIC, 
-	  MDATA, 
-	  AMBIENT_LIGHT, 
-	  SOLID_BGND, 
-	  DEFAULT_VIEW, 
-	  MAT_ENTRY,
-      MAT_AMBIENT, 
-	  MAT_DIFFUSE, 
-	  MAT_SPECULAR, 
-	  MAT_SHININESS, 
-	  MAT_SHIN2PCT,
-      MAT_SHIN3PCT, 
-	  MAT_TRANSPARENCY, 
-	  MAT_XPFALL, 
-	  MAT_REFBLUR, 
-	  MAT_SELF_ILPCT,
-      MAT_TEXMAP, 
-	  MAT_TEXMASK, 
-	  MAT_TEX2MAP, 
-	  MAT_TEX2MASK, 
-	  MAT_OPACMAP,
-      MAT_OPACMASK, 
-	  MAT_REFLMAP, 
-	  MAT_REFLMASK, 
-	  MAT_BUMPMAP, 
-	  MAT_BUMPMASK,
-      MAT_SPECMAP, 
-	  MAT_SPECMASK, 
-	  MAT_SHINMAP, 
-	  MAT_SHINMASK, 
-	  MAT_SELFIMAP,
-      MAT_SELFIMASK, 
-	  N_TRI_OBJECT, 
-	  KFDATA, 
-	  AMBIENT_NODE_TAG, 
-	  OBJECT_NODE_TAG,
-      CAMERA_NODE_TAG, 
-	  TARGET_NODE_TAG, 
-	  LIGHT_NODE_TAG, 
-	  SPOTLIGHT_NODE_TAG,
-      L_TARGET_NODE_TAG, 
-	  CMAGIC, 
-	  XDATA_SECTION, 
-	  XDATA_GROUP:
-        ; // do nothing
-    else // a truely hideous thing to do, but it helps with unknown chunks
-      if Chunk.Size > 6 then // don't mess with dataless chunks
-      begin
-        Chunk.Data.Dummy := AllocMem(Chunk.Size - 6);
-        ReadData(Chunk.Size - 6, Chunk.Data.Dummy);
-      end;
-    end; // end of case
-  end;
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-procedure TFile3DS.SeekChild(Chunk: PChunk3DS);
-// Function skips to next Chunk on disk by seeking the next file position
-var
-  Offset: Integer;
-begin
-  Offset := 0;
-  case Chunk.Tag of
-    M3DMAGIC, 
-    SMAGIC, 
-    LMAGIC, 
-    MATMAGIC, 
-    MLIBMAGIC, 
-    MDATA, 
-    AMBIENT_LIGHT, 
-    SOLID_BGND, 
-    DEFAULT_VIEW, 
-    MAT_ENTRY, 
-    MAT_AMBIENT, 
-    MAT_DIFFUSE, 
-    MAT_SPECULAR, 
-    MAT_SHININESS, 
-    MAT_SHIN2PCT, 
-    MAT_SHIN3PCT, 
-    MAT_TRANSPARENCY, 
-    MAT_XPFALL, 
-    MAT_REFBLUR, 
-    MAT_SELF_ILPCT, 
-    MAT_TEXMAP, 
-    MAT_TEXMASK, 
-    MAT_TEX2MAP, 
-    MAT_TEX2MASK, 
-    MAT_OPACMAP, 
-    MAT_OPACMASK, 
-    MAT_REFLMAP, 
-    MAT_REFLMASK, 
-    MAT_BUMPMAP, 
-    MAT_BUMPMASK, 
-    MAT_SPECMAP, 
-    MAT_SPECMASK, 
-    MAT_SHINMAP, 
-    MAT_SHINMASK, 
-    MAT_SELFIMAP, 
-    MAT_SELFIMASK, 
-    N_TRI_OBJECT, 
-    XDATA_SECTION, 
-    XDATA_ENTRY, 
-    KFDATA, 
-    OBJECT_NODE_TAG, 
-    CAMERA_NODE_TAG, 
-    TARGET_NODE_TAG, 
-    LIGHT_NODE_TAG, 
-    SPOTLIGHT_NODE_TAG, 
-    L_TARGET_NODE_TAG, 
-    AMBIENT_NODE_TAG, 
-    CMAGIC :
-      ; // do nothing
-    M3D_VERSION:
-      Offset := SizeOf(Integer);
-    COLOR_F:
-      Offset := 3 * SizeOf(Single);
-    COLOR_24:
-      Offset := 3 * SizeOf(Byte);
-    INT_PERCENTAGE:
-      Offset := SizeOf(SmallInt);
-    FLOAT_PERCENTAGE:
-      Offset := SizeOf(Single);
-    MAT_MAPNAME:
-      FreeMem(ReadString);
-    MESH_VERSION:
-      Offset := SizeOf(Integer);
-    MASTER_SCALE:
-      Offset := SizeOf(Single);
-    LO_SHADOW_BIAS:
-      Offset := SizeOf(Single);
-    HI_SHADOW_BIAS:
-      Offset := SizeOf(Single);
-    SHADOW_MAP_SIZE:
-      Offset := SizeOf(SmallInt);
-    SHADOW_SAMPLES:
-      Offset := SizeOf(SmallInt);
-    O_CONSTS:
-      Offset := 12;
-    V_GRADIENT:
-      Offset := SizeOf(Single);
-    NAMED_OBJECT:
-      FreeMem(ReadString);
-    BIT_MAP:
-      FreeMem(ReadString);
-    FOG:
-      Offset := 4 * SizeOf(Single);
-    LAYER_FOG:
-      Offset := 3 * SizeOf(Single) + SizeOf(Integer);
-    DISTANCE_CUE:
-      Offset := 4 * SizeOf(Single);
-    N_DIRECT_LIGHT:
-      Offset := 12;
-    DL_SPOTLIGHT:
-      Offset := 12 + 2 * SizeOf(Single);
-    N_CAMERA:
-      Offset := 24 + 2 * SizeOf(Single);
-    VIEWPORT_LAYOUT:
-      Offset := 7 * SizeOf(SmallInt);
-    VIEW_TOP,
-    VIEW_BOTTOM,
-    VIEW_LEFT,
-    VIEW_RIGHT,
-    VIEW_FRONT,
-    VIEW_BACK:
-      Offset := 12 + SizeOf(Single);
-    VIEW_USER:
-      Offset := 12 + 4 * SizeOf(Single);
-    VIEW_CAMERA:
-      FreeMem(ReadString);
-    MAT_NAME:
-      FreeMem(ReadString);
-    MAT_ACUBIC:
-      Offset := 2 * SizeOf(Byte) + 2 * SizeOf(Integer) + SizeOf(SmallInt);
-    POINT_ARRAY,
-    POINT_FLAG_ARRAY:
-      Offset := Chunk.Size - 6;
-    FACE_ARRAY:
-      Offset := ReadWord * SizeOf(SmallInt) * 4;
-    MSH_MAT_GROUP:
-      Offset := Chunk.Size - 6;
-    SMOOTH_GROUP:
-      Offset := Chunk.Size - 6;
-    TEX_VERTS:
-      Offset := Chunk.Size - 6;
-    MESH_MATRIX:
-      Offset := 12 * SizeOf(Single);
-    MESH_TEXTURE_INFO:
-      Offset := Chunk.Size - 6;
-    PROC_NAME:
-      FreeMem(ReadString);
-    DL_LOCAL_SHADOW2:
-      Offset := 2 * SizeOf(Single) + SizeOf(SmallInt);
-    KFHDR:
-      begin
-        ReadShort;
-        FreeMem(ReadString);
-        ReadInteger;
-      end;
-    KFSEG:
-      Offset := 2 * SizeOf(Integer);
-    KFCURTIME:
-      Offset := SizeOf(Integer);
-    NODE_HDR:
-      begin
-        FreeMem(ReadString);
-        Offset := 2 * SizeOf(SmallInt) + SizeOf(SmallInt);
-      end;
-    NODE_ID:
-      Offset := SizeOf(SmallInt);
-    PIVOT:
-      Offset := 12;
-    INSTANCE_NAME:
-      FreeMem(ReadString);
-    MORPH_SMOOTH:
-      Offset := SizeOf(Single);
-    BOUNDBOX:
-      Offset := 24;
-    VPDATA:
-      Offset := SizeOf(Integer);
-  else
-    Offset := Chunk.Size - 6;
-  end;
-  FStream.Seek(Offset, soFromCurrent);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.GetDatabaseRelease: TReleaseLevel;
-begin
-  Result := Formatx.m3DSUtils.GetDatabaseRelease(Self, FDatabase);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-function TFile3DS.GetMeshRelease: TReleaseLevel;
-begin
-  Result := Formatx.m3DSUtils.GetMeshRelease(Self, FDatabase);
-end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-
-end.

+ 0 - 971
Source/FMX/Formatx.m3DSConst.pas

@@ -1,971 +0,0 @@
-//
-// The graphics platform GLXcene https://github.com/glscene
-//
-unit Formatx.m3DSConst;
-
-(* Constants for commonly used structures *)
-
-interface
-
-uses
-  Formatx.m3DSTypes;
-
-const // Flags used by the flag field of the Mesh3DS structure
-      FaceCAVisable3DS = $0001;                  // flags the CA edge as visible
-      FaceBCVisable3DS = $0002;                  // flags the BC edge as visible
-      FaceABVisable3DS = $0004;                  // flags the AB edge as visible
-      FaceUWrap3DS     = $0008;                  // flags the face as being at
-                                                 // a texture coord u wrap seam
-      FaceVWrap3DS     = $0010;                  // flags the face as being at
-                                                 // a texture coord v wrap seam
-
-      // flags used by the rflags field of the keyheader3DS structure
-      KeyUsesTension3DS  = $01;
-      KeyUsesCont3DS     = $02;
-      KeyUsesBias3DS     = $04;
-      KeyUsesEaseTo3DS   = $08;
-      KeyUsesEaseFrom3DS = $10;
-
-      // flags used by the track flags field
-      TrackSingle3DS  = $0000;
-      TrackLoops3DS   = $0003;
-      TrackRepeats3DS = $0002;
-      TrackLockX3DS   = $0008;
-      TrackLockY3DS   = $0010;
-      TrackLockZ3DS   = $0020;
-      TrackNoLinkX3DS = $0100;
-      TrackNoLinkY3DS = $0200;
-      TrackNoLinkZ3DS = $0400;
-
-      // Basic structure default contents for ease of initialization 
-      DefPoint3DS       : TPoint3DS       = (X: 0; Y: 0; Z: 0);
-      DefTextVert3DS    : TTexVert3DS     = (U: 0; V: 0);
-      DefFace3DS        : TFace3DS        = (v1: 0; v2: 1; v3: 2; Flag: 0);
-      DefTrackHeader3DS : TTrackHeader3DS = (Flags: 0; nu1: 0; nu2: 0; KeyCount: 1);
-      DefKeyHeader3DS   : TKeyHeader3DS   = (Time: 0; RFlags: 0; Tension: 0; Continuity: 0; Bias: 0; EaseTo: 0; EaseFrom: 0);
-      DefObjMat3DS      : TObjMat3DS      = (NameStr: ''; NFaces: 0; FaceIndex: nil);
-      DefKFRotKey3DS    : TKFRotKey3DS    = (Angle: 0; X: 0; Y: 0; Z: 1);
-
-
-      // Fog Flags
-      LayerFogBgnd    = $100000;
-      NoFalloff       = $0;
-      TopFalloff      = $2;
-      BottomFalloff   = $1;
-
-      // Flags for initflags parameter
-      InitNoExtras3DS    = $0000;
-      InitVertexArray3DS = $0001;
-      InitTextArray3DS   = $0002;
-      InitFaceArray3DS   = $0004;
-      InitMatArray3DS    = $0008;
-      InitSmoothArray3DS = $0010;
-      InitProcData3DS    = $0020;
-      InitVFlagArray3DS  = $0040;
-
-      // field codes for RelMeshObjField3ds
-      RelVertexArray3ds  = $0001;
-      RelTextArray3ds    = $0002;
-      RelFaceArray3ds    = $0004;
-      RelMatArray3ds     = $0008;
-      RelSmoothArray3ds  = $0010;
-      RelProcData3ds     = $0020;
-      RelVFlagArray3ds   = $0040;
-      RelAll3DS          = $FFFF;
-
-      // Smoothing group Flags used in the smootharray field of the TMesh3DS structure
-      Smooth01Group3DS = $00000001;
-      Smooth02Group3DS = $00000002;
-      Smooth03Group3DS = $00000004;
-      Smooth04Group3DS = $00000008;
-      Smooth05Group3DS = $00000010;
-      Smooth06Group3DS = $00000020;
-      Smooth07Group3DS = $00000030;
-      Smooth08Group3DS = $00000080;
-      Smooth09Group3DS = $00000100;
-      Smooth10Group3DS = $00000200;
-      Smooth11Group3DS = $00000400;
-      Smooth12Group3DS = $00000800;
-      Smooth13Group3DS = $00001000;
-      Smooth14Group3DS = $00002000;
-      Smooth15Group3DS = $00004000;
-      Smooth16Group3DS = $00008000;
-      Smooth17Group3DS = $00010000;
-      Smooth18Group3DS = $00020000;
-      Smooth19Group3DS = $00040000;
-      Smooth20Group3DS = $00080000;
-      Smooth21Group3DS = $00100000;
-      Smooth22Group3DS = $00200000;
-      Smooth23Group3DS = $00400000;
-      Smooth24Group3DS = $00800000;
-      Smooth25Group3DS = $01000000;
-      Smooth26Group3DS = $02000000;
-      Smooth27Group3DS = $04000000;
-      Smooth28Group3DS = $08000000;
-      Smooth29Group3DS = $10000000;
-      Smooth30Group3DS = $20000000;
-      Smooth31Group3DS = $40000000;
-      Smooth32Group3DS = $80000000;
-
-      DummyName3DS     = '$$$DUMMY';
-
-      // flag settings for TKFMesh3DS, TKFOmni3DS, TKFCamera3DS, TKFAmbient and TKFSpot3DS
-      // ml: these flags correspond directly to NODE_RENDOB_HIDE etc. (see below), I don't know
-      //     what these duplications are for...
-
-      // for the flags field
-      KfNodeOff3DS        = 1 shl 3;
-      KfHideNode3DS       = 1 shl 11;
-      KfFastNode3DS       = 1 shl 12;
-
-      // For the flags2 field 
-      KfNodeHasPath3DS    = 1;
-      KfNodeAutoSmooth3DS = 1 shl 1;
-      KfNodeFrozen3DS     = 1 shl 2;
-      KfMotionBlur3DS     = 1 shl 4;
-      KfBlurBranch3DS     = 1 shl 5;
-      KfMorphMtl3DS       = 1 shl 6;
-      KfMorphOb3DS        = 1 shl 7;
-
-//-------------- constants that define various value ranges for specific chunks
-
-      // 3DS filename 
-      FileNameStrMax3DS     = 512;
-
-      // 3DS file attributes
-      FileAttrStrMax3DS     = 128;
-
-      // MASTER_SCALE chunk 
-      MasterScaleMin3DS     = 0;                 // noninclusive minimum value for master scale 
-
-      // LO_SHADOW_BIAS chunk 
-      LoShadowBiasMin3DS    = 0;                 // noninclusive minimum value for low shadow bias setting 
-
-      // HI_SHADOW_BIAS chunk
-      HiShadowBiasMin3DS    = 0;                 // noninclusive minimum value for high shadow bias setting 
-
-      // SHADOW_MAP_SIZE chunk 
-      ShadowMapSizeMin3DS   = 0;                 // noninclusive minimum value for shadow map size
-
-      // SHADOW_SAMPLES chunk
-      ShadowSamplesMin3DS   = 0;                 // noninclusive minimum value for shadow samples
-
-      // SHADOW_RANGE chunk
-      ShadowRangeMin3DS     = 0;                 // noninclusive minimum value for shadow range
-
-      // SHADOW_FILTER chunk
-      ShadowFilterMin3DS    = 1;                 // inclusive minimum value for shadow filter
-      ShadowFilterMax3DS    = 10;                // inclusive maximum value for shadow filter
-
-      // BITMAP chunk
-      BitMapStrMax3DS       = 12;                // maximum string length for filename
-
-      // V_GRADIENT chunk 
-      VGradientMin3DS       = 0;                 // minimum value for gradient midpoint
-      VGradientMax3DS       = 1;                 // maximum value for gradient midpoint
-
-      // FOG chunk 
-      FogMin3DS             = 0;                 // minimum value for fogging plane density
-      FogMax3DS             = 1;                 // maximum value for fogging plane density
-
-      // DISTANCE_CUE 
-      DistanceCueMin3DS     = 0;                 // minimum value for dimming factor
-      DistanceCueMax3DS     = 1;                 // maximum value for dimming factor
-
-      // VIEW_CAMERA 
-      ViewCameraStrMax3DS   = 10;                // maximum string length for filename
-
-      // MAT_NAME
-      MatNameStrMax3DS      = 16;                // maximum string length for material name
-
-      // MAT_SHADING
-      MatShadingMin3DS      = 0;                 // minimum shading value
-      MatShadingMax3DS      = 3;                 // maximum shading value 
-
-      // MAT_ACUBIC_FMIN 
-      MatACubicFMin3DS      = 1;                 // minimum frame skip count
-      MatACubicAMin3DS      = 0;                 // minimum reflection map aliasing
-      MatACubicAMax3DS      = 3;                 // maximum reflection map aliasing
-
-      // used with TAcubic3DS structure
-      ACubicFirst3DS        = $09;
-      ACubicFlat3DS         = $11;
-
-      // POINT_ARRAY
-      PointArrayMin3DS      = 3;                 // minimum number of vertices
-
-      // FACE_ARRAY
-      FaceArrayMin3DS       = 1;                 // minimum number of faces
-
-      // MshMatGroup3DS 
-      MshMatGroupMin3DS     = 1;                 // minimum number of faces per material
-      MshMatGroupStrMax3DS  = 16;                // maximim string length for MshMatGroup 
-
-      // PROC_NAME
-      ProcNameStrMax3DS     = 12;                // maximum string length for axp process 
-
-      // DL_SPOTLIGHT 
-      DLSpotlightMin3DS     = 0;                 // minimum for hotspot and falloff cones
-      DLSpotlightMax3DS     = 160;               // maximum for hotspot and falloff cones
-
-      // DL_LOCAL_SHADOW2
-      DLLocalShadow2SMin3DS = 10;                // minimum shadow map size
-      DLLocalShadow2SMax3DS = 4096;              // maximum shadow map size 
-      DLLocalShadow2FMin3DS = 1;                 // minimum shadow map size
-      DLLocalShadow2FMax3DS = 10;                // maximum shadow map size 
-
-      // COLOR_F 
-      ColorFMin3DS          = 0;                 // minimum color value in a channel
-      ColorFMax3DS          = 1;                 // maximum color value in a channel
-
-      // INT_PERCENTAGE
-      IntPercentageMax3DS   = 100;               // Maximum integer percentage
-
-      // FLOAT_PERCENTAGE
-      FloatPercentageMax3DS = 1;                 // Maximum floating point percentage 
-
-      // MAT_MAPNAME 
-      MatMapNameStrMax3DS   = 12;                // Maximum map name string size
-
-      // NAMED_OBJECT
-      NamedObjectStrMax3DS  = 10;                // Maximum named object string size
-
-      // N_CAMERA
-      NCameraFOVMin3DS      = 0.00025;           // Minimum field of view for camera
-      NCameraFOVMax3DS      = 160;               // Maximum field of view for camera
-      NCameraFocMin3DS      = 10.7813;           // Minimum lens size for camera
-      NCameraFocMax3DS      = 10000000;          // Maximum lens size for camera
-
-      // KFHDR
-      KFHdrStrMax3DS        = 12;                // Maximum keyframe header name string size
-
-      // NODE_HDR
-      NodeHdrStrMax3DS      = 10;                // Maximum node name string size
-
-      // INSTANCE_NAME
-      InstanceNameStrMax3DS = 10;                // Maximum instance name string size
-
-      // MORPH_TRACK
-      MorphTrackStrMax3DS   = 10;                // Maximum morph object name string size
-
-      // MORPH_SMOOTH
-      MorphSmoothMin3DS     = 0;                 // Minimum morph smoothing angle
-      MorphSmoothMax3DS     = 360;               // Maximum morph smoothing angle
-
-      // Keyframe Spline Limits
-      KFTensionMin3DS       = -1;                // Minimum key spline tension 
-      KFTensionMax3DS       = 1;                 // Maximum key spline tension
-      KFContinuityMin3DS    = -1;                // Minimum key spline continuity
-      KFContinuityMax3DS    = 1;                 // Maximum key spline continuity
-      KFBiasMin3DS          = -1;                // Minimum key spline bias
-      KFBiasMax3DS          = 1;                 // Maximum key spline bias
-      KFEaseToMin3DS        = 0;                 // Minimum key spline ease to
-      KFEaseToMax3DS        = 1;                 // Maximum key spline ease to
-      KFEaseFromMin3DS      = 0;                 // Minimum key spline ease from
-      KFEaseFromMax3DS      = 1;                 // Maximum key spline ease from
-
-      // Track header Limits
-      TrackHeaderKeysMin3DS = 1;                 // Minimum number of keys in a track
-
-      // COL_TRACK_TAG_KEY
-      ColTrackTagMin3DS     = 0;                 // Minimum color value
-      ColTrackTagMax3DS     = 1;                 // Maximum color value
-
-      // FOV_TRACK_TAG_KEY
-      FOVTrackTagMin3DS     = NCameraFOVMin3DS;  // Minimum camera FOV
-      FOVTrackTagMax3DS     = NCameraFOVMax3DS;  // Maximum camera FOV
-
-      // HOT_TRACK_TAG_KEY
-      HotTrackTagMin3DS     = 0;                 // Minimum hot spot angle
-      HotTrackTagMax3DS     = 160;               // Maximum hot spot angle
-
-      // FALL_TRACK_TAG_KEY
-      FallTrackTagMin3DS    = 0;                 // Minimum fall off angle
-      FallTrackTagMax3DS    = 160;               // Maximum fall off angle
-
-      KNoID                 = -1;
-      
-      // MAT_TILING
-      TEX_DECAL             = 1;
-      TEX_MIRROR            = 1 shl 1;
-      TEX_UNUSED1           = 1 shl 2;
-      TEX_INVERT            = 1 shl 3;
-      TEX_NOWRAP            = 1 shl 4;
-      TEX_SAT               = 1 shl 5;           // summed area table
-      TEX_ALPHA_SOURCE      = 1 shl 6;           // use ALPHA instead of RGB of map
-      TEX_TINT              = 1 shl 7;           // tint for color
-      TEX_DONT_USE_ALPHA    = 1 shl 8;           // don't use map alpha
-      TEX_RGB_TINT          = 1 shl 9;           // do RGB color transform
-
-      // Values for keyframer flags1
-      NODE_RENDOB_HIDE      = 1 shl  2;
-      NODE_OFF 	            = 1 shl  3;
-      ATKEY1		    = 1 shl  4;
-      ATKEY2		    = 1 shl  5;
-      ATKEY3		    = 1 shl  6;
-      ATKEY4		    = 1 shl  7;
-      ATKEY5		    = 1 shl  8;
-      ATKEYFLAGS            = ATKEY1 or ATKEY2 or ATKEY3 or ATKEY4 or ATKEY5;
-      MARK_NODE	            = 1 shl  9;
-      DISABLE_NODE          = 1 shl 10;
-      HIDE_NODE 	    = 1 shl 11;
-      FAST_NODE 	    = 1 shl 12;          // draw node quickdraw style
-      PRIMARY_NODE          = 1 shl 14;          // corresponds to mesh
-      NODE_CALC_PATH        = 1 shl 15;
-
-      // Values for keyframer flags2
-      NODE_HAS_PATH         = 1;
-      NODE_AUTO_SMOOTH      = 1 shl 1;
-      NODE_FROZEN           = 1 shl 2;
-      NODE_ANI_HIDDEN       = 1 shl 3;
-      NODE_MOTION_BLUR      = 1 shl 4;
-      NODE_BLUR_BRANCH      = 1 shl 5;
-      NODE_MORPH_MTL        = 1 shl 6;
-      NODE_MORPH_OB         = 1 shl 7;
-
-//----------------- List of all chunk IDs -------------------------------------
-
-      NULL_CHUNK             = $0000;
-
-      // Trick Chunk Flags For ChunkSyntax function
-      ChunkType              = $0995;
-      ChunkUnique            = $0996;
-      NotChunk               = $0997;
-      Container              = $0998;
-      IsChunk                = $0999;
-
-      // Dummy Chunk that sometimes appears in 3DS files created by prerelease 3D Studio R2
-      DUMMY                  = $FFFF;
-
-      // Trick Chunk Types For Open, Write, Close functions
-      POINT_ARRAY_ENTRY      = $F110;
-      POINT_FLAG_ARRAY_ENTRY = $F111;
-      FACE_ARRAY_ENTRY       = $F120;
-      MSH_MAT_GROUP_ENTRY    = $F130;
-      TEX_VERTS_ENTRY        = $F140;
-      SMOOTH_GROUP_ENTRY     = $F150;
-      POS_TRACK_TAG_KEY      = $F020;
-      ROT_TRACK_TAG_KEY      = $F021;
-      SCL_TRACK_TAG_KEY      = $F022;
-      FOV_TRACK_TAG_KEY      = $F023;
-      ROLL_TRACK_TAG_KEY     = $F024;
-      COL_TRACK_TAG_KEY      = $F025;
-      MORPH_TRACK_TAG_KEY    = $F026;
-      HOT_TRACK_TAG_KEY      = $F027;
-      FALL_TRACK_TAG_KEY     = $F028;
-
-      // 3DS file Chunk IDs
-      M3DMAGIC               = $4D4D;
-      SMAGIC                 = $2D2D;
-      LMAGIC                 = $2D3D;
-      MLIBMAGIC              = $3DAA;
-      MATMAGIC               = $3DFF;
-      M3D_VERSION            = $0002;
-      M3D_KFVERSION          = $0005;
-
-      // Mesh Chunk Ids
-      MDATA                  = $3D3D;
-      MESH_VERSION           = $3D3E;
-      COLOR_F                = $0010;
-      COLOR_24               = $0011;
-      LIN_COLOR_24           = $0012;
-      LIN_COLOR_F            = $0013;
-      INT_PERCENTAGE         = $0030;
-      FLOAT_PERCENTAGE       = $0031;
-      MASTER_SCALE           = $0100;
-      BIT_MAP                = $1100;
-      USE_BIT_MAP            = $1101;
-      SOLID_BGND             = $1200;
-      USE_SOLID_BGND         = $1201;
-      V_GRADIENT             = $1300;
-      USE_V_GRADIENT         = $1301;
-      LO_SHADOW_BIAS         = $1400;
-      HI_SHADOW_BIAS         = $1410;
-      SHADOW_MAP_SIZE        = $1420;
-      SHADOW_SAMPLES         = $1430;
-      SHADOW_RANGE           = $1440;
-      SHADOW_FILTER          = $1450;
-      RAY_BIAS               = $1460;
-      O_CONSTS               = $1500;
-      AMBIENT_LIGHT          = $2100;
-      FOG                    = $2200;
-      USE_FOG                = $2201;
-      FOG_BGND               = $2210;
-      DISTANCE_CUE           = $2300;
-      USE_DISTANCE_CUE       = $2301;
-      LAYER_FOG              = $2302;
-      USE_LAYER_FOG          = $2303;
-      DCUE_BGND              = $2310;
-      DEFAULT_VIEW           = $3000;
-      VIEW_TOP               = $3010;
-      VIEW_BOTTOM            = $3020;
-      VIEW_LEFT              = $3030;
-      VIEW_RIGHT             = $3040;
-      VIEW_FRONT             = $3050;
-      VIEW_BACK              = $3060;
-      VIEW_USER              = $3070;
-      VIEW_CAMERA            = $3080;
-      VIEW_WINDOW            = $3090;
-      NAMED_OBJECT           = $4000;
-      OBJ_HIDDEN             = $4010;
-      OBJ_VIS_LOFTER         = $4011;
-      OBJ_DOESNT_CAST        = $4012;
-      OBJ_MATTE              = $4013;
-      OBJ_FAST               = $4014;
-      OBJ_PROCEDURAL         = $4015;
-      OBJ_FROZEN             = $4016;
-      OBJ_DONT_RCVSHADOW     = $4017;
-      N_TRI_OBJECT           = $4100;
-      POINT_ARRAY            = $4110;
-      POINT_FLAG_ARRAY       = $4111;
-      FACE_ARRAY             = $4120;
-      MSH_MAT_GROUP          = $4130;
-      OLD_MAT_GROUP          = $4131;
-      TEX_VERTS              = $4140;
-      SMOOTH_GROUP           = $4150;
-      MESH_MATRIX            = $4160;
-      MESH_COLOR             = $4165;
-      MESH_TEXTURE_INFO      = $4170;
-      PROC_NAME              = $4181;
-      PROC_DATA              = $4182;
-      MSH_BOXMAP             = $4190;
-      N_D_L_OLD              = $4400;
-      N_CAM_OLD              = $4500;
-      N_DIRECT_LIGHT         = $4600;
-      DL_SPOTLIGHT           = $4610;
-      DL_OFF                 = $4620;
-      DL_ATTENUATE           = $4625;
-      DL_RAYSHAD             = $4627;
-      DL_SHADOWED            = $4630;
-      DL_LOCAL_SHADOW        = $4640;
-      DL_LOCAL_SHADOW2       = $4641;
-      DL_SEE_CONE            = $4650;
-      DL_SPOT_RECTANGULAR    = $4651;
-      DL_SPOT_OVERSHOOT      = $4652;
-      DL_SPOT_PROJECTOR      = $4653;
-      DL_EXCLUDE             = $4654;
-      DL_RANGE               = $4655;
-
-      // Not used in R3
-      DL_SPOT_ROLL           = $4656;
-      DL_SPOT_ASPECT         = $4657;
-      DL_RAY_BIAS            = $4658;
-      DL_INNER_RANGE         = $4659;
-      DL_OUTER_RANGE         = $465A;
-      DL_MULTIPLIER          = $465B;
-      N_AMBIENT_LIGHT        = $4680;
-      N_CAMERA               = $4700;
-      CAM_SEE_CONE           = $4710;
-      CAM_RANGES             = $4720;
-      HIERARCHY              = $4F00;
-      PARENT_OBJECT          = $4F10;
-      PIVOT_OBJECT           = $4F20;
-      PIVOT_LIMITS           = $4F30;
-      PIVOT_ORDER            = $4F40;
-      XLATE_RANGE            = $4F50;
-      POLY_2D                = $5000;
-
-      // Flags in shaper AFile that tell whether polys make up an ok shape
-      SHAPE_OK               = $5010;
-      SHAPE_NOT_OK           = $5011;
-      SHAPE_HOOK             = $5020;
-      PATH_3D                = $6000;
-      PATH_MATRIX            = $6005;
-      SHAPE_2D               = $6010;
-      M_SCALE                = $6020;
-      M_TWIST                = $6030;
-      M_TEETER               = $6040;
-      M_FIT                  = $6050;
-      M_BEVEL                = $6060;
-      XZ_CURVE               = $6070;
-      YZ_CURVE               = $6080;
-      INTERPCT               = $6090;
-      DEFORM_LIMIT           = $60A0;
-
-      // Flags for Modeler options
-      USE_CONTOUR            = $6100;
-      USE_TWEEN              = $6110;
-      USE_SCALE              = $6120;
-      USE_TWIST              = $6130;
-      USE_TEETER             = $6140;
-      USE_FIT                = $6150;
-      USE_BEVEL              = $6160;
-
-      // Viewport description chunks
-      VIEWPORT_LAYOUT_OLD    = $7000;
-      VIEWPORT_DATA_OLD      = $7010;
-      VIEWPORT_LAYOUT        = $7001;
-      VIEWPORT_DATA          = $7011;
-      VIEWPORT_DATA_3        = $7012;
-      VIEWPORT_SIZE          = $7020;
-      NETWORK_VIEW           = $7030;
-
-      // External Application Data
-      XDATA_SECTION          = $8000;
-      XDATA_ENTRY            = $8001;
-      XDATA_APPNAME          = $8002;
-      XDATA_STRING           = $8003;
-      XDATA_FLOAT            = $8004;
-      XDATA_DOUBLE           = $8005;
-      XDATA_SHORT            = $8006;
-      XDATA_LONG             = $8007;
-      XDATA_VOID             = $8008;
-      XDATA_GROUP            = $8009;
-      XDATA_RFU6             = $800A;
-      XDATA_RFU5             = $800B;
-      XDATA_RFU4             = $800C;
-      XDATA_RFU3             = $800D;
-      XDATA_RFU2             = $800E;
-      XDATA_RFU1             = $800F;
-      PARENT_NAME            = $80F0;
-
-      // Material Chunk IDs
-      MAT_ENTRY              = $AFFF;
-      MAT_NAME               = $A000;
-      MAT_AMBIENT            = $A010;
-      MAT_DIFFUSE            = $A020;
-      MAT_SPECULAR           = $A030;
-      MAT_SHININESS          = $A040;
-      MAT_SHIN2PCT           = $A041;
-      MAT_SHIN3PCT           = $A042;
-      MAT_TRANSPARENCY       = $A050;
-      MAT_XPFALL             = $A052;
-      MAT_REFBLUR            = $A053;
-      MAT_SELF_ILLUM         = $A080;
-      MAT_TWO_SIDE           = $A081;
-      MAT_DECAL              = $A082;
-      MAT_ADDITIVE           = $A083;
-      MAT_SELF_ILPCT         = $A084;
-      MAT_WIRE               = $A085;
-      MAT_SUPERSMP           = $A086;
-      MAT_WIRESIZE           = $A087;
-      MAT_FACEMAP            = $A088;
-      MAT_XPFALLIN           = $A08A;
-      MAT_PHONGSOFT          = $A08C;
-      MAT_WIREABS            = $A08E;
-      MAT_SHADING            = $A100;
-      MAT_TEXMAP             = $A200;
-      MAT_OPACMAP            = $A210;
-      MAT_REFLMAP            = $A220;
-      MAT_BUMPMAP            = $A230;
-      MAT_SPECMAP            = $A204;
-      MAT_USE_XPFALL         = $A240;
-      MAT_USE_REFBLUR        = $A250;
-      MAT_BUMP_PERCENT       = $A252;
-      MAT_MAPNAME            = $A300;
-      MAT_ACUBIC             = $A310;
-      MAT_SXP_TEXT_DATA      = $A320;
-      MAT_SXP_TEXT2_DATA     = $A321;
-      MAT_SXP_OPAC_DATA      = $A322;
-      MAT_SXP_BUMP_DATA      = $A324;
-      MAT_SXP_SPEC_DATA      = $A325;
-      MAT_SXP_SHIN_DATA      = $A326;
-      MAT_SXP_SELFI_DATA     = $A328;
-      MAT_SXP_TEXT_MASKDATA  = $A32A;
-      MAT_SXP_TEXT2_MASKDATA = $A32C;
-      MAT_SXP_OPAC_MASKDATA  = $A32E;
-      MAT_SXP_BUMP_MASKDATA  = $A330;
-      MAT_SXP_SPEC_MASKDATA  = $A332;
-      MAT_SXP_SHIN_MASKDATA  = $A334;
-      MAT_SXP_SELFI_MASKDATA = $A336;
-      MAT_SXP_REFL_MASKDATA  = $A338;
-      MAT_TEX2MAP            = $A33A;
-      MAT_SHINMAP            = $A33C;
-      MAT_SELFIMAP           = $A33D;
-      MAT_TEXMASK            = $A33E;
-      MAT_TEX2MASK           = $A340;
-      MAT_OPACMASK           = $A342;
-      MAT_BUMPMASK           = $A344;
-      MAT_SHINMASK           = $A346;
-      MAT_SPECMASK           = $A348;
-      MAT_SELFIMASK          = $A34A;
-      MAT_REFLMASK           = $A34C;
-      MAT_MAP_TILINGOLD      = $A350;
-      MAT_MAP_TILING         = $A351;
-      MAT_MAP_TEXBLUR_OLD    = $A352;
-      MAT_MAP_TEXBLUR        = $A353;
-      MAT_MAP_USCALE         = $A354;
-      MAT_MAP_VSCALE         = $A356;
-      MAT_MAP_UOFFSET        = $A358;
-      MAT_MAP_VOFFSET        = $A35A;
-      MAT_MAP_ANG            = $A35C;
-      MAT_MAP_COL1           = $A360;
-      MAT_MAP_COL2           = $A362;
-      MAT_MAP_RCOL           = $A364;
-      MAT_MAP_GCOL           = $A366;
-      MAT_MAP_BCOL           = $A368;
-
-      // Keyframe Chunk IDs
-      KFDATA                 = $B000;
-      KFHDR                  = $B00A;
-      AMBIENT_NODE_TAG       = $B001;
-      OBJECT_NODE_TAG        = $B002;
-      CAMERA_NODE_TAG        = $B003;
-      TARGET_NODE_TAG        = $B004;
-      LIGHT_NODE_TAG         = $B005;
-      L_TARGET_NODE_TAG      = $B006;
-      SPOTLIGHT_NODE_TAG     = $B007;
-      KFSEG                  = $B008;
-      KFCURTIME              = $B009;
-      NODE_HDR               = $B010;
-      INSTANCE_NAME          = $B011;
-      PRESCALE               = $B012;
-      PIVOT                  = $B013;
-      BOUNDBOX               = $B014;
-      MORPH_SMOOTH           = $B015;
-      POS_TRACK_TAG          = $B020;
-      ROT_TRACK_TAG          = $B021;
-      SCL_TRACK_TAG          = $B022;
-      FOV_TRACK_TAG          = $B023;
-      ROLL_TRACK_TAG         = $B024;
-      COL_TRACK_TAG          = $B025;
-      MORPH_TRACK_TAG        = $B026;
-      HOT_TRACK_TAG          = $B027;
-      FALL_TRACK_TAG         = $B028;
-      HIDE_TRACK_TAG         = $B029;
-      NODE_ID                = $B030;
-      CMAGIC                 = $C23D;
-      C_MDRAWER              = $C010;
-      C_TDRAWER              = $C020;
-      C_SHPDRAWER            = $C030;
-      C_MODDRAWER            = $C040;
-      C_RIPDRAWER            = $C050;
-      C_TXDRAWER             = $C060;
-      C_PDRAWER              = $C062;
-      C_MTLDRAWER            = $C064;
-      C_FLIDRAWER            = $C066;
-      C_CUBDRAWER            = $C067;
-      C_MFILE                = $C070;
-      C_SHPFILE              = $C080;
-      C_MODFILE              = $C090;
-      C_RIPFILE              = $C0A0;
-      C_TXFILE               = $C0B0;
-      C_PFILE                = $C0B2;
-      C_MTLFILE              = $C0B4;
-      C_FLIFILE              = $C0B6;
-      C_PALFILE              = $C0B8;
-      C_TX_STRING            = $C0C0;
-      C_CONSTS               = $C0D0;
-      C_SNAPS                = $C0E0;
-      C_GRIDS                = $C0F0;
-      C_ASNAPS               = $C100;
-      C_GRID_RANGE           = $C110;
-      C_RENDTYPE             = $C120;
-      C_PROGMODE             = $C130;
-      C_PREVMODE             = $C140;
-      C_MODWMODE             = $C150;
-      C_MODMODEL             = $C160;
-      C_ALL_LINES            = $C170;
-      C_BACK_TYPE            = $C180;
-      C_MD_CS                = $C190;
-      C_MD_CE                = $C1A0;
-      C_MD_SML               = $C1B0;
-      C_MD_SMW               = $C1C0;
-      C_LOFT_WITH_TEXTURE    = $C1C3;
-      C_LOFT_L_REPEAT        = $C1C4;
-      C_LOFT_W_REPEAT        = $C1C5;
-      C_LOFT_UV_NORMALIZE    = $C1C6;
-      C_WELD_LOFT            = $C1C7;
-      C_MD_PDET              = $C1D0;
-      C_MD_SDET              = $C1E0;
-      C_RGB_RMODE            = $C1F0;
-      C_RGB_HIDE             = $C200;
-      C_RGB_MAPSW            = $C202;
-      C_RGB_TWOSIDE          = $C204;
-      C_RGB_SHADOW           = $C208;
-      C_RGB_AA               = $C210;
-      C_RGB_OVW              = $C220;
-      C_RGB_OVH              = $C230;
-      C_RGB_PICTYPE          = $C240;
-      C_RGB_OUTPUT           = $C250;
-      C_RGB_TODISK           = $C253;
-      C_RGB_COMPRESS         = $C254;
-      C_JPEG_COMPRESSION     = $C255;
-      C_RGB_DISPDEV          = $C256;
-      C_RGB_HARDDEV          = $C259;
-      C_RGB_PATH             = $C25A;
-      C_BITMAP_DRAWER        = $C25B;
-      C_RGB_FILE             = $C260;
-      C_RGB_OVASPECT         = $C270;
-      C_RGB_ANIMTYPE         = $C271;
-      C_RENDER_ALL           = $C272;
-      C_REND_FROM            = $C273;
-      C_REND_TO              = $C274;
-      C_REND_NTH             = $C275;
-      C_PAL_TYPE             = $C276;
-      C_RND_TURBO            = $C277;
-      C_RND_MIP              = $C278;
-      C_BGND_METHOD          = $C279;
-      C_AUTO_REFLECT         = $C27A;
-      C_VP_FROM              = $C27B;
-      C_VP_TO                = $C27C;
-      C_VP_NTH               = $C27D;
-      C_REND_TSTEP           = $C27E;
-      C_VP_TSTEP             = $C27F;
-      C_SRDIAM               = $C280;
-      C_SRDEG                = $C290;
-      C_SRSEG                = $C2A0;
-      C_SRDIR                = $C2B0;
-      C_HETOP                = $C2C0;
-      C_HEBOT                = $C2D0;
-      C_HEHT                 = $C2E0;
-      C_HETURNS              = $C2F0;
-      C_HEDEG                = $C300;
-      C_HESEG                = $C310;
-      C_HEDIR                = $C320;
-      C_QUIKSTUFF            = $C330;
-      C_SEE_LIGHTS           = $C340;
-      C_SEE_CAMERAS          = $C350;
-      C_SEE_3D               = $C360;
-      C_MESHSEL              = $C370;
-      C_MESHUNSEL            = $C380;
-      C_POLYSEL              = $C390;
-      C_POLYUNSEL            = $C3A0;
-      C_SHPLOCAL             = $C3A2;
-      C_MSHLOCAL             = $C3A4;
-      C_NUM_FORMAT           = $C3B0;
-      C_ARCH_DENOM           = $C3C0;
-      C_IN_DEVICE            = $C3D0;
-      C_MSCALE               = $C3E0;
-      C_COMM_PORT            = $C3F0;
-      C_TAB_BASES            = $C400;
-      C_TAB_DIVS             = $C410;
-      C_MASTER_SCALES        = $C420;
-      C_SHOW_1STVERT         = $C430;
-      C_SHAPER_OK            = $C440;
-      C_LOFTER_OK            = $C450;
-      C_EDITOR_OK            = $C460;
-      C_KEYFRAMER_OK         = $C470;
-      C_PICKSIZE             = $C480;
-      C_MAPTYPE              = $C490;
-      C_MAP_DISPLAY          = $C4A0;
-      C_TILE_XY              = $C4B0;
-      C_MAP_XYZ              = $C4C0;
-      C_MAP_SCALE            = $C4D0;
-      C_MAP_MATRIX_OLD       = $C4E0;
-      C_MAP_MATRIX           = $C4E1;
-      C_MAP_WID_HT           = $C4F0;
-      C_OBNAME               = $C500;
-      C_CAMNAME              = $C510;
-      C_LTNAME               = $C520;
-      C_CUR_MNAME            = $C525;
-      C_CURMTL_FROM_MESH     = $C526;
-      C_GET_SHAPE_MAKE_FACES = $C527;
-      C_DETAIL               = $C530;
-      C_VERTMARK             = $C540;
-      C_MSHAX                = $C550;
-      C_MSHCP                = $C560;
-      C_USERAX               = $C570;
-      C_SHOOK                = $C580;
-      C_RAX                  = $C590;
-      C_STAPE                = $C5A0;
-      C_LTAPE                = $C5B0;
-      C_ETAPE                = $C5C0;
-      C_KTAPE                = $C5C8;
-      C_SPHSEGS              = $C5D0;
-      C_GEOSMOOTH            = $C5E0;
-      C_HEMISEGS             = $C5F0;
-      C_PRISMSEGS            = $C600;
-      C_PRISMSIDES           = $C610;
-      C_TUBESEGS             = $C620;
-      C_TUBESIDES            = $C630;
-      C_TORSEGS              = $C640;
-      C_TORSIDES             = $C650;
-      C_CONESIDES            = $C660;
-      C_CONESEGS             = $C661;
-      C_NGPARMS              = $C670;
-      C_PTHLEVEL             = $C680;
-      C_MSCSYM               = $C690;
-      C_MFTSYM               = $C6A0;
-      C_MTTSYM               = $C6B0;
-      C_SMOOTHING            = $C6C0;
-      C_MODICOUNT            = $C6D0;
-      C_FONTSEL              = $C6E0;
-      C_TESS_TYPE            = $C6f0;
-      C_TESS_TENSION         = $C6f1;
-      C_SEG_START            = $C700;
-      C_SEG_END              = $C705;
-      C_CURTIME              = $C710;
-      C_ANIMLENGTH           = $C715;
-      C_PV_FROM              = $C720;
-      C_PV_TO                = $C725;
-      C_PV_DOFNUM            = $C730;
-      C_PV_RNG               = $C735;
-      C_PV_NTH               = $C740;
-      C_PV_TYPE              = $C745;
-      C_PV_METHOD            = $C750;
-      C_PV_FPS               = $C755;
-      C_VTR_FRAMES           = $C765;
-      C_VTR_HDTL             = $C770;
-      C_VTR_HD               = $C771;
-      C_VTR_TL               = $C772;
-      C_VTR_IN               = $C775;
-      C_VTR_PK               = $C780;
-      C_VTR_SH               = $C785;
-
-      // Material chunks
-      C_WORK_MTLS            = $C790;            // Old-style -- now ignored
-      C_WORK_MTLS_2          = $C792;            // Old-style -- now ignored
-      C_WORK_MTLS_3          = $C793;            // Old-style -- now ignored
-      C_WORK_MTLS_4          = $C794;            // Old-style -- now ignored
-      C_WORK_MTLS_5          = $CB00;            // Old-style -- now ignored
-      C_WORK_MTLS_6          = $CB01;            // Old-style -- now ignored
-      C_WORK_MTLS_7          = $CB02;            // Old-style -- now ignored
-      C_WORK_MTLS_8          = $CB03;            // Old-style -- now ignored
-      C_WORKMTL              = $CB04;
-      C_SXP_TEXT_DATA        = $CB10;
-      C_SXP_TEXT2_DATA       = $CB20;
-      C_SXP_OPAC_DATA        = $CB11;
-      C_SXP_BUMP_DATA        = $CB12;
-      C_SXP_SPEC_DATA        = $CB24;
-      C_SXP_SHIN_DATA        = $CB13;
-      C_SXP_SELFI_DATA       = $CB28;
-      C_SXP_TEXT_MASKDATA    = $CB30;
-      C_SXP_TEXT2_MASKDATA   = $CB32;
-      C_SXP_OPAC_MASKDATA    = $CB34;
-      C_SXP_BUMP_MASKDATA    = $CB36;
-      C_SXP_SPEC_MASKDATA    = $CB38;
-      C_SXP_SHIN_MASKDATA    = $CB3A;
-      C_SXP_SELFI_MASKDATA   = $C3CB;
-      C_SXP_REFL_MASKDATA    = $CB3E;
-      C_BGTYPE               = $C7A1;
-      C_MEDTILE              = $C7B0;
-
-      // Contrast
-      C_LO_CONTRAST          = $C7D0;
-      C_HI_CONTRAST          = $C7D1;
-
-      // 3d frozen display
-      C_FROZ_DISPLAY         = $C7E0;
-
-      // Booleans
-      C_BOOLWELD             = $C7f0;
-      C_BOOLTYPE             = $C7f1;
-      C_ANG_THRESH           = $C900;
-      C_SS_THRESH            = $C901;
-      C_TEXTURE_BLUR_DEFAULT = $C903;
-      C_MAPDRAWER            = $CA00;
-      C_MAPDRAWER1           = $CA01;
-      C_MAPDRAWER2           = $CA02;
-      C_MAPDRAWER3           = $CA03;
-      C_MAPDRAWER4           = $CA04;
-      C_MAPDRAWER5           = $CA05;
-      C_MAPDRAWER6           = $CA06;
-      C_MAPDRAWER7           = $CA07;
-      C_MAPDRAWER8           = $CA08;
-      C_MAPDRAWER9           = $CA09;
-      C_MAPDRAWER_ENTRY      = $CA10;
-
-      // system options
-      C_BACKUP_FILE          = $CA20;
-      C_DITHER_256           = $CA21;
-      C_SAVE_LAST            = $CA22;
-      C_USE_ALPHA            = $CA23;
-      C_TGA_DEPTH            = $CA24;
-      C_REND_FIELDS          = $CA25;
-      C_REFLIP               = $CA26;
-      C_SEL_ITEMTOG          = $CA27;
-      C_SEL_RESET            = $CA28;
-      C_STICKY_KEYINF        = $CA29;
-      C_WELD_THRESHOLD       = $CA2A;
-      C_ZCLIP_POINT          = $CA2B;
-      C_ALPHA_SPLIT          = $CA2C;
-      C_KF_SHOW_BACKFACE     = $CA30;
-      C_OPTIMIZE_LOFT        = $CA40;
-      C_TENS_DEFAULT         = $CA42;
-      C_CONT_DEFAULT         = $CA44;
-      C_BIAS_DEFAULT         = $CA46;
-      C_DXFNAME_SRC          = $CA50;
-      C_AUTO_WELD            = $CA60;
-      C_AUTO_UNIFY           = $CA70;
-      C_AUTO_SMOOTH          = $CA80;
-      C_DXF_SMOOTH_ANG       = $CA90;
-      C_SMOOTH_ANG           = $CAA0;
-
-      // Special network-use chunks
-      C_NET_USE_VPOST        = $CC00;
-      C_NET_USE_GAMMA        = $CC10;
-      C_NET_FIELD_ORDER      = $CC20;
-      C_BLUR_FRAMES          = $CD00;
-      C_BLUR_SAMPLES         = $CD10;
-      C_BLUR_DUR             = $CD20;
-      C_HOT_METHOD           = $CD30;
-      C_HOT_CHECK            = $CD40;
-      C_PIXEL_SIZE           = $CD50;
-      C_DISP_GAMMA           = $CD60;
-      C_FBUF_GAMMA           = $CD70;
-      C_FILE_OUT_GAMMA       = $CD80;
-      C_FILE_IN_GAMMA        = $CD82;
-      C_GAMMA_CORRECT        = $CD84;
-      C_APPLY_DISP_GAMMA     = $CD90;            // OBSOLETE
-      C_APPLY_FBUF_GAMMA     = $CDA0;            // OBSOLETE
-      C_APPLY_FILE_GAMMA     = $CDB0;            // OBSOLETE
-      C_FORCE_WIRE           = $CDC0;
-      C_RAY_SHADOWS          = $CDD0;
-      C_MASTER_AMBIENT       = $CDE0;
-      C_SUPER_SAMPLE         = $CDF0;
-      C_OBJECT_MBLUR         = $CE00;
-      C_MBLUR_DITHER         = $CE10;
-      C_DITHER_24            = $CE20;
-      C_SUPER_BLACK          = $CE30;
-      C_SAFE_FRAME           = $CE40;
-      C_VIEW_PRES_RATIO      = $CE50;
-      C_BGND_PRES_RATIO      = $CE60;
-      C_NTH_SERIAL_NUM       = $CE70;
-
-      // Video Post
-      VPDATA                 = $D000;
-      P_QUEUE_ENTRY          = $D100;
-      P_QUEUE_IMAGE          = $D110;
-      P_QUEUE_USEIGAMMA      = $D114;
-      P_QUEUE_PROC           = $D120;
-      P_QUEUE_SOLID          = $D130;
-      P_QUEUE_GRADIENT       = $D140;
-      P_QUEUE_KF             = $D150;
-      P_QUEUE_MOTBLUR        = $D152;
-      P_QUEUE_MB_REPEAT      = $D153;
-      P_QUEUE_NONE           = $D160;
-      P_QUEUE_RESIZE         = $D180;
-      P_QUEUE_OFFSET         = $D185;
-      P_QUEUE_ALIGN          = $D190;
-      P_CUSTOM_SIZE          = $D1a0;
-      P_ALPH_NONE            = $D210;
-      P_ALPH_PSEUDO          = $D220;            // Old Chunk
-      P_ALPH_OP_PSEUDO       = $D221;            // Old Chunk
-      P_ALPH_BLUR            = $D222;            // Replaces pseudo 
-      P_ALPH_PCOL            = $D225;
-      P_ALPH_C0              = $D230;
-      P_ALPH_OP_KEY          = $D231;
-      P_ALPH_KCOL            = $D235;
-      P_ALPH_OP_NOCONV       = $D238;
-      P_ALPH_IMAGE           = $D240;
-      P_ALPH_ALPHA           = $D250;
-      P_ALPH_QUES            = $D260;
-      P_ALPH_QUEIMG          = $D265;
-      P_ALPH_CUTOFF          = $D270;
-      P_ALPHANEG             = $D280;
-      P_TRAN_NONE            = $D300;
-      P_TRAN_IMAGE           = $D310;
-      P_TRAN_FRAMES          = $D312;
-      P_TRAN_FADEIN          = $D320;
-      P_TRAN_FADEOUT         = $D330;
-      P_TRANNEG              = $D340;
-      P_RANGES               = $D400;
-      P_PROC_DATA            = $D500;
-
-                                                  
-      NodeTagCount = 6;                          // number of entries in node tag list
-      NodeTags: array[1..NodeTagCount] of Word =
-        (TARGET_NODE_TAG,
-         OBJECT_NODE_TAG,
-         CAMERA_NODE_TAG,
-         LIGHT_NODE_TAG,
-         L_TARGET_NODE_TAG,
-         SPOTLIGHT_NODE_TAG
-        );
-
-//---------------------------------------------------------------------------------------------------------------------
-implementation
-//---------------------------------------------------------------------------------------------------------------------
-
-end.

+ 0 - 1388
Source/FMX/Formatx.m3DSTypes.pas

@@ -1,1388 +0,0 @@
-//
-// The graphics platform GLXcene https://github.com/glscene
-//
-unit Formatx.m3DSTypes;
-
-(*
-  Implements the standard Teapot, build from evaluators.
-  This unit contains all of the data types used by the core routines.
-  Most of these are only used with the internal database,
-  created when a file is loaded.
-*)
-
-interface
-
-{$I GLX.Scene.inc}
-{$ALIGN ON}
-{$MINENUMSIZE 4}
-
-uses
-  System.Classes; // for TStringList
-
-// ---------------- commonly used structures ----------------------------------
-
-type
-  TDumpLevel = (dlTerseDump, dlMediumDump, dlMaximumDump);
-
-  PChar3DS = PWideChar;
-  String3DS = AnsiString;
-  String64 = string[64];
-
-  PWordList = ^TWordList;
-  TWordList = array [0 .. MaxInt div (2 * SizeOf(Word))] of Word;
-
-  PIntegerArray = ^TIntegerArray;
-  TIntegerArray = array [0 .. MaxInt div (2 * SizeOf(Integer))] of Integer;
-
-  PCardinalArray = ^TCardinalArray;
-  TCardinalArray = array [0 .. MaxInt div (2 * SizeOf(Cardinal))] of Cardinal;
-
-  PSingleList = ^TSingleList;
-  TSingleList = array [0 .. MaxInt div (2 * SizeOf(Single))] of Single;
-
-  PPoint3DS = ^TPoint3DS; // 3D point structure
-  TPoint3DS = record
-    X, Y, Z: Single;
-  end;
-
-  PPointList = ^TPointList;
-  TPointList = array [0 .. MaxInt div (2 * SizeOf(TPoint3DS))] of TPoint3DS;
-
-  PFColor3DS = ^TFColor3DS; // RGB Color components
-  TFColor3DS = record
-    R, G, B: Single;
-  end;
-
-  PFColorList = ^TFColorList;
-  TFColorList = array [0 .. MaxInt div (2 * SizeOf(TFColor3DS))] of TFColor3DS;
-
-  PFace3DS = ^TFace3DS; // Face List element
-  TFace3DS = packed record
-    case Boolean of
-      True:
-        (V1, V2, V3, Flag: Word);
-      False:
-        (FaceRec: array [0 .. 3] of Word);
-  end;
-
-  PFaceList = ^TFaceList;
-  TFaceList = array [0 .. MaxInt div (2 * SizeOf(TFace3DS))] of TFace3DS;
-
-  PTexVert3DS = ^TTexVert3DS; // Texture assignment coordinate
-  TTexVert3DS = record
-    U, V: Single;
-  end;
-
-  PTexVertList = ^TTexVertList;
-  TTexVertList = array [0 .. MaxInt div (2 * SizeOf(TTexVert3DS))
-    ] of TTexVert3DS;
-
-  PTrackHeader3DS = ^TTrackHeader3DS; // Global track settings
-  TTrackHeader3DS = record
-    Flags: Word;
-    nu1, nu2, KeyCount: Integer; // Number of keys in the track
-  end;
-
-  PKeyHeader3DS = ^TKeyHeader3DS; // Animation key settings
-  TKeyHeader3DS = record
-    Time: Integer; // Key's frame position
-    RFlags: Word; // Spline terms used flag
-    Tension: Single; // Flagged with $01
-    Continuity: Single; // Flagged with $02
-    Bias: Single; // Flagged with $04
-    EaseTo: Single; // Flagged with $08
-    EaseFrom: Single; // Flagged with $10
-  end;
-
-  PKeyHeaderList = ^TKeyHeaderList;
-  TKeyHeaderList = array [0 .. MaxInt div (2 * SizeOf(TKeyHeader3DS))
-    ] of TKeyHeader3DS;
-
-  PKFRotKey3DS = ^TKFRotKey3DS; // Rotation key
-  TKFRotKey3DS = record
-    Angle: Single; // Angle of Rotation
-    X, Y, Z: Single; // Rotation axis vector
-  end;
-
-  PKFRotKeyList = ^TKFRotKeyList;
-  TKFRotKeyList = array [0 .. MaxInt div (2 * SizeOf(TKFRotKey3DS))
-    ] of TKFRotKey3DS;
-
-  PKFMorphKey3DS = ^TKFMorphKey3DS; // Object Morph key
-  TKFMorphKey3DS = String; // Name of Target Morph object
-
-  PKFMorphKeyList = ^TKFMorphKeyList;
-  TKFMorphKeyList = array [0 .. MaxInt div (2 * SizeOf(TKFMorphKey3DS))
-    ] of TKFMorphKey3DS;
-
-  // internal database representation of file information
-  PChunk3DS = ^TChunk3DS;
-
-   // cross reference between Name and Chunk
-  PChunkListEntry3DS = ^TChunkListEntry3DS;
-  TChunkListEntry3DS = record
-    NameStr: String; // chunk name list
-    Chunk: PChunk3DS; // corresponding pos
-  end;
-
-  PChunkList = ^TChunkList;
-  TChunkList = array [0 .. MaxInt div (2 * SizeOf(TChunkListEntry3DS))
-    ] of TChunkListEntry3DS;
-
-  PChunkList3DS = ^TChunkList3DS; // list of cross references
-  TChunkList3DS = record
-    Count: Integer; // number of entries in List
-    List: PChunkList; // contents of List
-  end;
-
-  (* replaced by a TStringList
-    PNameList = ^TNameList;
-    TNameList = array[0..0] of String;
-
-    PNameList3DS = ^TNameList3DS;               // list of database object names
-    TNameList3DS = record
-    Count  : Integer;          // how many entries are in list
-    Spaces : Integer;          // how much space for entries
-    Names  : PNameList;        // to access pointers
-    end; *)
-
-  // Database type settings
-  TDBType3DS = (dbUnknown, // database has not been created yet
-    dbMeshFile, // 3D Studio .3DS file
-    dbProjectFile, // 3D Studio .PRJ file
-    dbMaterialFile // 3D Studio .MLI file
-    );
-
-  PNodeList = ^TNodeList;
-  TNodeList = record
-    ID: SmallInt;
-    Tag: Word;
-    Name, InstStr: String;
-    ParentID: SmallInt;
-    Next: PNodeList;
-  end;
-
-  PDatabase3DS = ^TDatabase3DS; // file database
-  TDatabase3DS = record
-    TopChunk: PChunk3DS; // Top chunk in the file
-    ObjListDirty, // If True, than ObjList needs to be recreated
-    MatListDirty, NodeListDirty: Boolean;
-    ObjList, // Quick Cross references between names and database chunks
-    MatList, NodeList: PChunkList3DS;
-  end;
-
-  TViewType3DS = (vtNoView3DS, vtTopView3DS, vtBottomView3DS, vtLeftView3DS,
-    vtRightView3DS, vtFrontView3DS, vtBackView3DS, vtUserView3DS,
-    vtCameraView3DS, vtSpotlightView3DS);
-
-  PViewSize3DS = ^TViewSize3DS;
-  TViewSize3DS = record
-    XPos, YPos, Width, Height: Word;
-  end;
-
-  // Used to describe Top, Bottom, left, right, front and back views
-  POrthoView3DS = ^TOrthoView3DS;
-  TOrthoView3DS = record
-    Center: TPoint3DS; // Center of orthogonal View
-    Zoom: Single; // View Zoom factor
-  end;
-
-  PUserView3DS = ^TUserView3DS;
-  TUserView3DS = record // Used to describe User views
-    Center: TPoint3DS; // Center of User View
-    Zoom: Single; // View Zoom factor
-    HorAng: Single; // Horizontal Angle of View
-    VerAng: Single; // Vertical Angle of View
-  end;
-
-  // Viewport structure details the kind of View in a viewport
-  PViewport3DS = ^TViewport3DS;
-  TViewport3DS = record
-    AType: TViewType3DS;
-    // top, bottom, left, right, front, back, user and camera, spot
-    Size: TViewSize3DS; // size of the viewport
-    Ortho: TOrthoView3DS;
-    // used for top, bottom, left, right, front, and back views
-    User: TUserView3DS; // Used for User views
-    CameraStr: String; // used for camera views
-  end;
-
-  TShadowStyle3DS = (ssUseShadowMap, ssUseRayTraceShadow);
-
-  PShadowSets3DS = ^TShadowSets3DS; // global Shadow settings
-  TShadowSets3DS = record
-    AType: TShadowStyle3DS; // either UseShadowMaps or UseRayTraceShadows
-    Bias: Single; // Shadow Bias factor.
-    RayBias: Single; // Shadow ray Bias factor, Used in R3
-    MapSize: SmallInt; // Shadow Map Size
-    Filter: Single; // Shadow Filter
-  end;
-
-  PMeshSet3DS = ^TMeshSet3DS;
-  TMeshSet3DS = record
-    MasterScale: Single; // master mesh Scale factor
-    Shadow: TShadowSets3DS; // Global Shadow settings
-    AmbientLight: TFColor3DS; // Ambient light Color
-    OConsts: TPoint3DS; // default object constructing axis
-  end;
-
-  TAtmosphereType3DS = (atNoAtmo, // no active atmospherics
-    atUseFog, // Fog atmospheric
-    atUseLayerFog, // layer Fog atmospheric
-    atUseDistanceCue // distance cue atmospheric
-    );
-
-  TLayerFogFalloff3DS = (lfNoFall, // no FallOff
-    lfTopFall, // FallOff to the Top
-    lfBottomFall // FallOff to the Bottom
-    );
-
-  PFogSettings3DS = ^TFogSettings3DS; // Fog atmosphere parameters
-  TFogSettings3DS = record
-    NearPlane: Single; // near radius of Fog effect
-    NearDensity: Single; // near Fog Density
-    FarPlane: Single; // far radius of Fog effect
-    FarDensity: Single; // far Fog Density
-    FogColor: TFColor3DS; // Color of Fog effect
-    FogBgnd: Boolean; // "Fog background" Flag
-  end;
-
-  PLayerFogSettings3DS = ^TLayerFogSettings3DS;   // layered Fog atmosphere parameters
-  TLayerFogSettings3DS = record
-    ZMin: Single; // lower bounds of Fog
-    ZMax: Single; // upper bounds of Fog
-    Density: Single; // Fog Density
-    FogColor: TFColor3DS; // Fog Color
-    FallOff: TLayerFogFalloff3DS; // FallOff style
-    FogBgnd: Boolean; // "Fog background" Flag
-  end;
-
-  PDCueSettings3DS = ^TDCueSettings3DS; // distance cue atmosphere parameters
-  TDCueSettings3DS = record
-    NearPlane: Single; // near radius of effect
-    NearDim: Single; // near dimming factor
-    FarPlane: Single; // far radius of effect
-    FarDim: Single; // far dimming factor
-    DCueBgnd: Boolean; // effect the background Flag
-  end;
-
-  PAtmosphere3DS = ^TAtmosphere3DS;
-  TAtmosphere3DS = record
-    Fog: TFogSettings3DS; // Fog atmosphere settings
-    LayerFog: TLayerFogSettings3DS; // layered Fog atmosphere parameters
-    DCue: TDCueSettings3DS; // distance cue atmosphere parameters
-    ActiveAtmo: TAtmosphereType3DS; // the active atmospheric
-  end;
-
-  // enumerate list of possible backgrounds used in file
-  TBackgroundType3DS = (btNoBgnd, btUseSolidBgnd, btUseVGradientBgnd,
-    btUseBitmapBgnd);
-
-  PBitmapBgnd3DS = ^TBitmapBgnd3DS;
-  TBitmapBgnd3DS = AnsiString; // Name of background Bitmap
-
-  TSolidBgnd3DS = TFColor3DS; // Color of Solid background
-
-  PVGradientBgnd3DS = ^TVGradientBgnd3DS;
-  TVGradientBgnd3DS = record
-    GradPercent: Single; // placement of Mid Color band, Ranges from 0-1
-    Top: TFColor3DS; // color of Top band
-    Mid: TFColor3DS; // color of Mid background band
-    Bottom: TFColor3DS; // color of Bottom band
-  end;
-
-  PBackground3DS = ^TBackground3DS;
-  TBackground3DS = record
-    Bitmap: TBitmapBgnd3DS;
-    Solid: TSolidBgnd3DS;
-    VGradient: TVGradientBgnd3DS;
-    BgndUsed: TBackgroundType3DS; // background in effect
-  end;
-
-  // used for shading field in TMaterial3DS structure
-  TShadeType3DS = (stWire, stFlat, stGouraud, stPhong, stMetal);
-
-  // used for tiling field in TBitmap3DS structure
-  TTileType3DS = (ttTile, ttDecal, ttBoth);
-
-  TFilterType3DS = (ftPyramidal, ftSummedArea);
-
-  TTintType3DS = (ttRGB, ttAlpha, ttRGBLumaTint, ttAlphaTint, ttRGBTint);
-
-  // used by AddMaterial3DS
-  PACubic3DS = ^TACubic3DS;
-  TACubic3DS = record
-    FirstFrame: Boolean; // True for First Frame Only
-    Flat: Boolean; // True for Flat Mirror reflection
-    Size: Integer; // Map resolution
-    nthFrame: Integer; // Map update period
-  end;
-
-  // Cubic reflection Map defintion
-  PBitmap3DS = ^TBitmap3DS;
-  TBitmap3DS = record
-    NameStr: AnsiString; // Bitmap file name
-    Percent: Single; // Strength percentage
-    Tiling: TTileType3DS; // Tile/Decal/Both
-    IgnoreAlpha: Boolean;
-    Filter: TFilterType3DS; // Pyramidal/Summed Area
-    Blur: Single;
-    Mirror: Boolean;
-    Negative: Boolean;
-    UScale: Single;
-    VScale: Single;
-    UOffset: Single;
-    VOffset: Single;
-    Rotation: Single;
-    Source: TTintType3DS; // RGB/RGB Luma Tint/Alpha Tint/RGB Tint
-    Tint1: TFColor3DS;
-    Tint2: TFColor3DS;
-    RedTint: TFColor3DS;
-    GreenTint: TFColor3DS;
-    BlueTint: TFColor3DS;
-    DataSize: Integer; // Size of procedural Data
-    Data: Pointer; // Procedural Data
-  end;
-
-
-  // Bit Map definition
-
-  // Structure to all Map settings
-  PMapSet3DS = ^TMapSet3DS;
-  TMapSet3DS = record
-    Map: TBitmap3DS; // The Map settings
-    Mask: TBitmap3DS; // The Mask settings
-  end;
-
-  TRMapSet3DS = record
-    Map: TBitmap3DS; // The Map settings
-    UseAuto: Boolean; // True if automatic reflections are being used
-    AutoMap: TACubic3DS; // Automatic reflection definitions
-    Mask: TBitmap3DS; // The Mask settings
-  end;
-
-  PMaterial3DS = ^TMaterial3DS;
-  TMaterial3DS = record
-    NameStr: AnsiString; // Name
-    Ambient: TFColor3DS; // Ambient Light Color
-    Diffuse: TFColor3DS; // Diffuse Light Color
-    Specular: TFColor3DS; // Specular Light Color
-    Shininess: Single; // Shininess factor
-    ShinStrength: Single; // Shininess strength
-    Blur: Single; // Blur factor
-    Transparency: Single; // Trasparency factor
-    TransFallOff: Single; // Falloff factor
-    SelfIllumPct: Single; // Self illumination percentage
-    WireSize: Single; // Width of wireframe
-    Shading: TShadeType3DS; // Shading type
-    UseBlur: Boolean; // Blurring Flag
-    UseFall: Boolean; // Transparency FallOff Flag
-    TwoSided: Boolean; // Two sided material Flag
-    SelFillum: Boolean; // Self illumination Flag
-    Additive: Boolean; // Additive Transparency Flag
-    UseWire: Boolean; // Use wireframe rendering
-    UseWireAbs: Boolean; // Wire Size is in units, not pixels.
-    FaceMap: Boolean; // Face mapping switch
-    Soften: Boolean; // Soften switch
-    Texture: TMapSet3DS; // Texture Map settings
-    Texture2: TMapSet3DS; // Second Texture Map settings
-    Opacity: TMapSet3DS; // Opacity Map settings
-    Bump: TMapSet3DS; // Bump Map settings
-    SpecMap: TMapSet3DS; // Specularity Map settings
-    ShinMap: TMapSet3DS; // Shininess Map settings
-    IllumMap: TMapSet3DS; // Self illumination Map settings
-    Reflect: TRMapSet3DS; // Reflection Map settings
-  end;
-
-
-  // Mesh definition
-  PMeshMatrix = ^TMeshMatrix;
-  TMeshMatrix = array [0 .. 11] of Single;
-
-  // Texture Map icon placement
-  PMapInfo3DS = ^TMapInfo3DS;
-  TMapInfo3DS = record
-    MapType: Word; // icon type
-    TileX: Single; // tiling
-    TileY: Single;
-    CenX: Single; // position of center
-    CenY: Single;
-    CenZ: Single;
-    Scale: Single; // icon scaling factor
-    Matrix: TMeshMatrix; // orientation matrix
-    PW: Single; // planar icon width
-    PH: Single; // planar icon height
-    CH: Single; // cylinder icon height
-  end;
-
-  // Material assignments by face
-  PObjMat3DS = ^TObjMat3DS;
-  TObjMat3DS = record
-    NameStr: AnsiString; // material name
-    NFaces: Word; // number of faces using material
-    FaceIndex: PWordList; // list of faces using material
-  end;
-
-  PObjMatList = ^TObjMatList;
-  TObjMatList = array [0 .. MaxInt div (2 * SizeOf(TObjMat3DS))] of TObjMat3DS;
-
-  // Mesh object definition
-  PMesh3DS = ^TMesh3DS;
-  TMesh3DS = record
-    NameStr: AnsiString; // object name
-    IsHidden: Boolean; // hidden object flag
-    IsvisLofter: Boolean; // lofter visibility flag
-    IsMatte: Boolean; // matte object flag
-    IsNoCast: Boolean; // doesn't cast shadows flag
-    IsFast: Boolean; // fast display flag
-    IsNorcvShad: Boolean; // doesn't recieve shadows
-    IsFrozen: Boolean; // frozen object flag
-    NVertices: Word; // vertice count
-    VertexArray: PPointList; // list of vertices
-    NVFlags: Word; // number of vertex flags
-    VFlagArray: PWordList; // list of vertex flags
-    NTextVerts: Word; // number of texture vertices
-    TextArray: PTexVertList; // list of texture coordinates
-    UseMapInfo: Boolean; // for use of mapping icon information
-    Map: TMapInfo3DS; // mapping icon info
-    LocMatrix: TMeshMatrix; // object orientation matrix
-    NFaces: Word; // face count
-    FaceArray: PFaceList; // list of faces
-    SmoothArray: PCardinalArray; // smoothing group assignment list
-    UseBoxMap: Boolean; // used to indicate the use of box mapping
-    BoxMapStr: array [0 .. 5] of String; // material names used in boxmapping
-    MeshColor: Byte; // UI color assigned to the mesh
-    NMats: Word; // assigned materials count
-    MatArray: PObjMatList; // material assignment list
-    UseProc: Boolean; // use animated stand-in flag
-    ProcSize: Integer; // size of animated stand-in data
-    ProcNameStr: String; // name of animated stand-in procedure
-    ProcData: Pointer; // animated stand-in data
-  end;
-
-  // Spotlight projection cone shape
-  TConeStyle3DS = (csCircular, csRectangular);
-
-  // Spotlight shadow settings
-  PSpotShadow3DS = ^TSpotShadow3DS;
-  TSpotShadow3DS = record
-    Cast: Boolean; // True if spotlight casts shadows
-    AType: TShadowStyle3DS; // UseShadow or UseRayTrace
-    Local: Boolean; // True if local shadow settings are being used
-    Bias: Single; // shadow bias
-    Filter: Single; // shadow filter
-    MapSize: Word; // shadow map size
-    RayBias: Single; // Ray tracing shadow bias
-  end;
-
-  // Cone visibility settings
-  PSpotCone3DS = ^TSpotCone3DS;
-  TSpotCone3DS = record
-    AType: TConeStyle3DS; // Circular or rectangular light cone
-    Show: Boolean; // True if cone is visible
-    Overshoot: Boolean; // True if cone overshoot is on
-  end;
-
-  // spotlight projectio Bitmap
-  PSpotProjector3DS = ^TSpotProjector3DS;
-  TSpotProjector3DS = record
-    Use: Boolean; // True if using projector
-    BitmapStr: String; // name of projector bitmap
-  end;
-
-  // spotlight settings
-  PSpotLight3DS = ^TSpotLight3DS;
-  TSpotLight3DS = record
-    Target: TPoint3DS; // Spotlight Target
-    Hotspot: Single; // Hotspot Angle
-    FallOff: Single; // Hotspot FallOff
-    Roll: Single; // Roll Angle
-    Aspect: Single; // Aspect ratio
-    Shadows: TSpotShadow3DS;
-    Cone: TSpotCone3DS;
-    Projector: TSpotProjector3DS;
-  end;
-
-  // Light Attenuation settings
-  PLiteAttenuate3DS = ^TLiteAttenuate3DS;
-  TLiteAttenuate3DS = record
-    IsOn: Boolean; // True if Light Attenuation is on
-    Inner: Single; // Inner range of Attenuation
-    Outer: Single; // Outer range of Attenuation
-  end;
-
-  // omni and spotlight settings
-  PLight3DS = ^TLight3DS;
-  TLight3DS = record
-    NameStr: AnsiString; // light name
-    Pos: TPoint3DS; // light position
-    Color: TFColor3DS; // light color
-    Multiplier: Single; // light intensity multiplier
-    DLOff: Boolean; // True if light is off
-    Attenuation: TLiteAttenuate3DS;
-    Exclude: TStringList;
-    Spot: PSpotLight3DS; // if not nil then struct is a spotlight, else omni
-  end;
-
-  // Camera atomosphere Ranges
-  PCamRanges3DS = ^TCamRanges3DS;
-  TCamRanges3DS = record
-    CamNear: Single; // Nearest effect radius
-    CamFar: Single; // Farthest effect radius
-  end;
-
-  PCamera3DS = ^TCamera3DS;
-  TCamera3DS = record
-    NameStr: AnsiString;
-    Position: TPoint3DS;
-    Target: TPoint3DS;
-    Roll: Single;
-    FOV: Single;
-    ShowCone: Boolean;
-    Ranges: TCamRanges3DS;
-  end;
-
-  PKFKeyInfo3DS = ^TKFKeyInfo3DS;
-  TKFKeyInfo3DS = record
-    Length: Integer;
-    CurFrame: Integer;
-  end;
-
-  PKFSegment3DS = ^TKFSegment3DS;
-  TKFSegment3DS = record
-    Use: Boolean;
-    SegBegin: Integer;
-    SegEnd: Integer;
-  end;
-
-  PKFSets3DS = ^TKFSets3DS;
-  TKFSets3DS = record
-    Anim: TKFKeyInfo3DS;
-    Seg: TKFSegment3DS;
-  end;
-
-  PKFCamera3DS = ^TKFCamera3DS;
-  TKFCamera3DS = record
-    NameStr: AnsiString; // Name of Camera object
-    ParentStr: AnsiString; // Name of Parent object
-    Flags1: Word; // Flags field from node header -fixup later
-    Flags2: Word; // Flags2 field from node header -fixup later
-    NPKeys: Integer; // Number of Camera Position keys
-    NPFlag: Word; // Loop control Flag for Camera Position keys
-    PKeys: PKeyHeaderList; // Spline values for Camera Position keys
-    Pos: PPointList; // Camera Position keys
-    NFKeys: Integer; // Number of Camera FOV keys
-    NFFlag: Word; // Loop control Flag for Camera FOV keys
-    FKeys: PKeyHeaderList; // Spline values for Camera FOV keys
-    FOV: PSingleList; // Camera FOV keys
-    NRKeys: Integer; // Number of Camera Roll keys
-    NRFlag: Word; // Loop control Flag for Camera Roll keys
-    RKeys: PKeyHeaderList; // Spline values for Camera Roll keys
-    Roll: PSingleList; // Camera Roll keys
-    TParentStr: String; // Index of Parent object for Target
-    NTKeys: Integer; // Number of Target Position keys
-    NTFlag: Word; // Loop control Flag for Target Position keys
-    TKeys: PKeyHeaderList; // Spline values for Target Position keys
-    TPos: PPointList; // Target Position keys
-    TFlags1: Word; // Flags field from Target node header
-    TFlags2: Word; // Flags field from Target node header
-  end;
-
-  // Ambient Light animation
-  PKFAmbient3DS = ^TKFAmbient3DS;
-  TKFAmbient3DS = record
-    Flags1: Word; // Flags field from node header -fixup later
-    Flags2: Word; // Flags2 field from node header -fixup later
-    NCKeys: Integer; // Number of Color keys
-    NCFlag: Word; // Loop control Flag for Color keys
-    CKeys: PKeyHeaderList; // Spline values for Position keys
-    Color: PFColorList; // Color keys
-  end;
-
-  // used by ObjectMotion3DS
-  PKFMesh3DS = ^TKFMesh3DS;
-  TKFMesh3DS = record
-    NameStr: AnsiString; // Name of mesh
-    ParentStr: AnsiString; // Name of Parent object
-    Flags1: Word; // Flags field from node header
-    Flags2: Word; // Flags2 field from node header
-    Pivot: TPoint3DS; // Object Pivot point
-    InstanceStr: AnsiString; // Object Instance Name
-    BoundMin: TPoint3DS; // Minimum bounding box point for dummy objects
-    BoundMax: TPoint3DS; // Maximum bounding box point for dummy objects
-    NPKeys: Integer; // Number of Position keys
-    NPFlag: SmallInt; // Loop control Flag for Position keys
-    PKeys: PKeyHeaderList; // Spline values for Position keys
-    Pos: PPointList; // Mesh Position keys
-    NRKeys: Integer; // Number of Rotation keys
-    NRFlag: SmallInt; // Loop control Flag for Rotation keys
-    RKeys: PKeyHeaderList; // Spline values for Rotation keys
-    Rot: PKFRotKeyList; // Rotation keys
-    NSKeys: Integer; // Number of scaling keys
-    NSFlag: SmallInt; // Loop control Flag for scaling keys
-    SKeys: PKeyHeaderList; // Spline values for scaling
-    Scale: PPointList; // Mesh scaling keys
-    NMKeys: Integer; // Number of Morph keys
-    NMFlag: SmallInt; // Loop control Flag for Morph keys
-    MKeys: PKeyHeaderList; // Spline values for Morph keys
-    Morph: PKFMorphKeyList; // Morph keys
-    NHKeys: Integer; // Number of hide keys
-    NHFlag: SmallInt; // Loop control Flag for hide keys
-    HKeys: PKeyHeaderList; // Spline values for hide keys
-    MSAngle: Single; // Morph smoothing group Angle
-  end;
-
-  // used by OmnilightMotion3DS
-  PKFOmni3DS = ^TKFOmni3DS;
-  TKFOmni3DS = record
-    Name: AnsiString; // Name of the Light object node
-    Parent: AnsiString; // Name of the Parent object
-    Flags1: Word; // Flags field from node header -fixup later
-    Flags2: Word; // Flags2 field from node header -fixup later
-    NPKeys: Integer; // Number of Position keys
-    NPFlag: Word; // Loop control Flag for Position keys
-    PKeys: PKeyHeaderList; // Spline values for Position keys
-    Pos: PPointList; // Position keys
-    NCKeys: Integer; // Number of Color keys
-    NCFlag: Word; // Loop control Flag for Color keys
-    CKeys: PKeyHeaderList; // Spline values for Position keys
-    Color: PFColorList; // Color keys
-  end;
-
-  PKFSpot3DS = ^TKFSpot3DS;
-  TKFSpot3DS = record
-    Name: AnsiString; // Name of Camera object
-    Parent: AnsiString; // Parent Name
-    Flags1: Word; // Flags field from node header -fixup later
-    Flags2: Word; // Flags2 field from node header -fixup later
-
-{$IFDEF broken}
-    visible: SmallInt; // Flags to control visibility
-{$ENDIF}
-    NPKeys: Integer; // Number of Light Position keys
-    NPFlag: Word; // Loop control Flag for Position keys
-    PKeys: PKeyHeaderList; // Spline values for Light Position keys
-    Pos: PPointList; // Light Position keys
-    NCKeys: Integer; // Number of Color keys
-    NCFlag: Word; // Loop control Flag Color keys
-    CKeys: PKeyHeaderList; // Spline values for Color keys
-    Color: PFColorList; // Color keys
-    NHKeys: Integer; // Number of Hotspot Angle keys
-    NHFlag: Word; // Loop control Flag for Hotspot Angle keys
-    HKeys: PKeyHeaderList; // Spline values for Hotspot Angle keys
-    Hot: PSingleList; // Hotspot Angle keys
-    NFKeys: Integer; // Number of FallOff Angle keys
-    NFFlag: Word; // Loop control Flag for FallOff Angle keys
-    FKeys: PKeyHeaderList; // Spline values for FallOff Angle keys
-    Fall: PSingleList; // FallOff Angle keys
-    NRKeys: Integer; // Number of Light Roll keys
-    NRFlag: Word; // Loop control Flag for Light Roll keys
-    RKeys: PKeyHeaderList; // Spline values for Light Roll keys
-    Roll: PSingleList; // Light Roll keys
-    TParent: AnsiString; // Name of Target's Parent object
-    NTKeys: Integer; // Number of Target Position keys
-    NTFlag: Word; // Loop control Flag for Target Position keys
-    TKeys: PKeyHeaderList; // Spline values for Target Position keys
-    TPos: PPointList; // Target Position keys
-    TFlags1: Word; // Flags field from Target node header
-    TFlags2: Word; // Flags field from Target node header
-  end;
-
-  PXDataRaw3DS = ^TXDataRaw3DS;
-  TXDataRaw3DS = record
-    Size: Integer;
-    Data: Pointer;
-  end;
-
-  TTargetType3DS = (ttLightTarget, ttCameraTarget);
-
-  PM3dVersion = ^TM3dVersion;
-  TM3dVersion = Cardinal;
-
-
-  (* inner datatypes not followed by a '3DS' to show they are locally used
-    (mostly as a part of another chunk or while collecting specific data) *)
-  PColorF = ^TColorF;
-  TColorF = record
-    Red, Green, Blue: Single;
-  end;
-
-  PLinColorF = ^TLinColorF;
-  TLinColorF = TColorF;
-
-  PColor24 = ^TColor24;
-
-  TColor24 = record
-    Red, Green, Blue: Byte;
-  end;
-
-  PLinColor24 = ^TLinColor24;
-  TLinColor24 = TColor24;
-
-  PMatMapRCol = ^TMatMapRCol;
-  TMatMapRCol = TLinColor24;
-
-  PMatMapGCol = ^TMatMapGCol;
-  TMatMapGCol = TMatMapRCol;
-
-  PMatMapBCol = ^TMatMapBCol;
-  TMatMapBCol = TMatMapGCol;
-
-  PMatMapCol1 = ^TMatMapCol1;
-  TMatMapCol1 = TMatMapBCol;
-
-  PMatMapCol2 = ^TMatMapCol2;
-  TMatMapCol2 = TMatMapCol1;
-
-  PIntPercentage = ^TIntPercentage;
-  TIntPercentage = SmallInt;
-
-  PMatBumpPercent = ^TMatBumpPercent;
-  TMatBumpPercent = TIntPercentage;
-
-  PFloatPercentage = ^TFloatPercentage;
-  TFloatPercentage = Single;
-
-  PMatMapname = PChar3DS;
-
-  PMeshVersion = ^TMeshVersion;
-  TMeshVersion = Integer;
-
-  PMasterScale = ^TMasterScale;
-  TMasterScale = Single;
-
-  PLoShadowBias = ^TLoShadowBias;
-  TLoShadowBias = Single;
-
-  PHiShadowBias = ^THiShadowBias;
-  THiShadowBias = TLoShadowBias;
-
-  PRayBias = ^TRayBias;
-  TRayBias = THiShadowBias;
-
-  PShadowMapSize = ^TShadowMapSize;
-  TShadowMapSize = SmallInt;
-
-  PShadowSamples = ^TShadowSamples;
-  TShadowSamples = SmallInt;
-
-  PShadowRange = ^TShadowRange;
-  TShadowRange = Integer;
-
-  PShadowFilter = ^TShadowFilter;
-  TShadowFilter = Single;
-
-  POConsts = ^TOConsts;
-  TOConsts = TPoint3DS;
-
-  PBitMapName = PChar3DS;
-
-  PVGradient = ^TVGradient;
-  TVGradient = Single;
-
-  PFog = ^TFog;
-  TFog = record
-    NearPlaneDist: Single;
-    NearPlaneDensity: Single;
-    FarPlaneDist: Single;
-    FarPlaneDensity: Single;
-  end;
-
-  PLayerFog = ^TLayerFog;
-  TLayerFog = record
-    ZMin: Single;
-    ZMax: Single;
-    Density: Single;
-    AType: Cardinal;
-  end;
-
-  PDistanceCue = ^TDistanceCue;
-  TDistanceCue = record
-    NearPlaneDist: Single;
-    NearPlaneDimming: Single;
-    FarPlaneDist: Single;
-    FarPlaneDimming: Single;
-  end;
-
-  PViewStandard = ^TViewStandard;
-  TViewStandard = record
-    ViewTargetCoord: TPoint3DS;
-    ViewWidth: Single;
-  end;
-
-  PViewUser = ^TViewUser;
-  TViewUser = record
-    ViewTargetCoord: TPoint3DS;
-    ViewWidth: Single;
-    XYViewangle: Single;
-    YZViewangle: Single;
-    BankAngle: Single;
-  end;
-
-  PViewCamera = PChar3DS;
-
-  PMatName = PChar3DS;
-
-  PMatShading = ^TMatShading;
-  TMatShading = SmallInt;
-
-  PMatAcubic = ^TMatAcubic;
-  TMatAcubic = record
-    ShadeLevel: Byte;
-    Antialias: Byte;
-    Flags: SmallInt;
-    MapSize: Cardinal;
-    FrameInterval: Cardinal;
-  end;
-
-  PIpasData = ^TIpasData;
-  TIpasData = record
-    Size: Integer;
-    Data: Pointer;
-  end;
-
-  PMatWireSize = ^TMatWireSize;
-  TMatWireSize = Single;
-
-  PMatMapTiling = ^TMatMapTiling;
-  TMatMapTiling = Word;
-
-  PMatMapTexblur = ^TMatMapTexblur;
-  TMatMapTexblur = Single;
-
-  PMatMapUScale = ^TMatMapUScale;
-  TMatMapUScale = Single;
-
-  PMatMapVScale = ^TMatMapVScale;
-  TMatMapVScale = TMatMapUScale;
-
-  PMatMapUOffset = ^TMatMapUOffset;
-  TMatMapUOffset = Single;
-
-  PMatMapVOffset = ^TMatMapVOffset;
-  TMatMapVOffset = TMatMapUOffset;
-
-  PMatMapAng = ^TMatMapAng;
-  TMatMapAng = Single;
-
-  PNamedObject = PChar3DS;
-
-  PPointArray = ^TPointArray;
-  TPointArray = record
-    Vertices: Word;
-    PointList: PPointList;
-  end;
-
-  PPointFlagArray = ^TPointFlagArray;
-  TPointFlagArray = record
-    Flags: Word;
-    FlagList: PWordList;
-  end;
-
-  PFaceArray = ^TFaceArray;
-  TFaceArray = record
-    Faces: Word;
-    FaceList: PFaceList;
-  end;
-
-  PMshMatGroup = ^TMshMatGroup;
-  TMshMatGroup = record
-    MatNameStr: AnsiString;
-    Faces: Word;
-    FaceList: PWordList;
-  end;
-
-  PMshBoxmap = ^TMshBoxmap;
-  TMshBoxmap = array [0 .. 5] of AnsiString;
-
-  PSmoothGroup = ^TSmoothGroup;
-  TSmoothGroup = record
-    Groups: Word;
-    GroupList: PCardinalArray;
-  end;
-
-  PTexVerts = ^TTexVerts;
-  TTexVerts = record
-    NumCoords: Word;
-    TextVertList: PTexVertList;
-  end;
-
-  PMeshColor = ^TMeshColor;
-  TMeshColor = Byte;
-
-  PMeshTextureInfo = ^TMeshTextureInfo;
-  TMeshTextureInfo = record
-    MapType: Word;
-    XTiling: Single;
-    YTiling: Single;
-    IconPos: TPoint3DS;
-    IconScaling: Single;
-    XMatrix: TMeshMatrix;
-    IconWidth: Single;
-    IconHeight: Single;
-    CylIconHeight: Single;
-  end;
-
-  PProcName = PChar3DS;
-
-  PNDirectLight = ^TNDirectLight;
-  TNDirectLight = TPoint3DS;
-
-  PDlExclude = PChar3DS;
-
-  PDlSpotlight = ^TDlSpotlight;
-  TDlSpotlight = record
-    SpotLightTarg: TPoint3DS;
-    HotspotAngle: Single;
-    FalloffAngle: Single;
-  end;
-
-  PDlOuterRange = ^TDlOuterRange;
-  TDlOuterRange = Single;
-
-  PDlInnerRange = ^TDlInnerRange;
-  TDlInnerRange = TDlOuterRange;
-
-  PDlMultiplier = ^TDlMultiplier;
-  TDlMultiplier = Single;
-
-  PDlSpotRoll = ^TDlSpotRoll;
-  TDlSpotRoll = Single;
-
-  PDlSpotAspect = ^TDlSpotAspect;
-  TDlSpotAspect = Single;
-
-  PDlSpotProjector = PChar3DS;
-
-  PDlRayBias = ^TDlRayBias;
-  TDlRayBias = Single;
-
-  PDlLocalShadow2 = ^TDlLocalShadow2;
-  TDlLocalShadow2 = record
-    LocalShadowBias: Single;
-    LocalShadowFilter: Single;
-    LocalShadowMapSize: SmallInt end;
-
-    PNCamera = ^TNCamera;
-    TNCamera = record CameraPos: TPoint3DS;
-    TargetPos: TPoint3DS;
-    CameraBank: Single;
-    CameraFocalLength: Single;
-  end;
-
-  PCamRanges = ^TCamRanges;
-  TCamRanges = record
-    NearPlane: Single;
-    FarPlane: Single;
-  end;
-
-  PViewportLayout = ^TViewportLayout;
-  TViewportLayout = record
-    Form: SmallInt; // 0 = single window
-    // 1 = 2 split verticle
-    // 2 = 2 split horizontal
-    // 3 = 4 equal squares
-    // 4 = 2 squares left & 1 rect right
-    // 5 = 1 rect at Top & 2 sqr on bot
-    // 6 = 1 rect left & 2 sqr right
-    // 7 = 2 sqr Top & 1 rect bot
-    // 8 = 3 split vertical
-    // 9 = 2 split horiz
-    // 10 = 3 sqr left and 1 rect right
-    // 11 = 1 rect left & 3 sqr. right
-    // Form becomes 0 during swap and its preswapped value is stored in the SwapPort field
-    Top: SmallInt; // Active window index of 0 to 5
-    Ready: SmallInt;
-    WState: SmallInt;
-    // 0 if no swap window, 1 if in swaped "w" state. During a swap, the old 0 window gets stored as the 4 window
-    SwapWS: SmallInt;
-    SwapPort: SmallInt; // The preswapped value from the Form field
-    SwapCur: SmallInt; // The window index that was swapped
-  end;
-
-  PViewportSize = ^TViewportSize;
-  TViewportSize = record // Values given for 1024x768 resolution
-    XPos: Word; // 0
-    YPos: Word; // 14
-    Width: Word; // 895
-    Height: Word; // 725
-  end;
-
-  PViewportData = ^TViewportData;
-  TViewportData = record
-    Flags: Word;
-    AxisLockout: Word;
-    WinXPos: Word;
-    WinYPos: Word;
-    WinWidth: Word;
-    WinHeight: Word;
-    View: Word; // 0 = No View
-    // 1 = Top View
-    // 2 = Bottom View
-    // 3 = Left View
-    // 4 = Right View
-    // 5 = Front View
-    // 6 = Back View
-    // 7 = User View
-    // 18 = Spotlight View
-    // 65535 = Camera View
-    ZoomFactor: Single;
-    Center: TPoint3DS;
-    HorizAng: Single;
-    VertAng: Single;
-    CamNameStr: AnsiString;
-  end;
-
-  PViewportData3 = ^TViewportData3;
-  TViewportData3 = TViewportData;
-
-  PKFHdr = ^TKFHdr;
-  TKFHdr = record
-    Revision: SmallInt;
-    Filename: String;
-    AnimLength: Integer;
-  end;
-
-  PKFId = ^TKFId;
-  TKFId = SmallInt;
-
-  PKFSeg = ^TKFSeg;
-  TKFSeg = record
-    First: Integer;
-    Last: Integer;
-  end;
-
-  PKFCurtime = ^TKFCurtime;
-  TKFCurtime = Integer;
-
-  PNodeHdr = ^TNodeHdr;
-  TNodeHdr = record
-    ObjNameStr: String;
-    Flags1: Word;
-    Flags2: Word;
-    ParentIndex: SmallInt;
-  end;
-
-  PPivot = ^TPivot;
-  TPivot = TPoint3DS;
-
-  PInstanceName = PChar3DS;
-
-  PMorphSmooth = ^TMorphSmooth;
-  TMorphSmooth = Single;
-
-  PBoundBox = ^TBoundBox;
-  TBoundBox = record
-    Min: TPoint3DS;
-    Max: TPoint3DS;
-  end;
-
-  PPosTrackTag = ^TPosTrackTag;
-  TPosTrackTag = record
-    TrackHdr: TTrackHeader3DS;
-    KeyHdrList: PKeyHeaderList;
-    PositionList: PPointList;
-  end;
-
-  PColTrackTag = ^TColTrackTag;
-  TColTrackTag = record
-    TrackHdr: TTrackHeader3DS;
-    KeyHdrList: PKeyHeaderList;
-    ColorList: PFColorList;
-  end;
-
-  PRotTrackTag = ^TRotTrackTag;
-  TRotTrackTag = record
-    TrackHdr: TTrackHeader3DS;
-    KeyHdrList: PKeyHeaderList;
-    RotationList: PKFRotKeyList;
-  end;
-
-  PScaleTrackTag = ^TScaleTrackTag;
-  TScaleTrackTag = record
-    TrackHdr: TTrackHeader3DS;
-    KeyHdrList: PKeyHeaderList;
-    ScaleList: PPointList;
-  end;
-
-  PMorphTrackTag = ^TMorphTrackTag;
-  TMorphTrackTag = record
-    TrackHdr: TTrackHeader3DS;
-    KeyHdrList: PKeyHeaderList;
-    MorphList: PKFMorphKeyList;
-  end;
-
-  PHideTrackTag = ^THideTrackTag;
-  THideTrackTag = record
-    TrackHdr: TTrackHeader3DS;
-    KeyHdrList: PKeyHeaderList;
-  end;
-
-  PFovTrackTag = ^TFovTrackTag;
-  TFovTrackTag = record
-    TrackHdr: TTrackHeader3DS;
-    KeyHdrList: PKeyHeaderList;
-    FOVAngleList: PSingleList;
-  end;
-
-  PRollTrackTag = ^TRollTrackTag;
-  TRollTrackTag = record
-    TrackHdr: TTrackHeader3DS;
-    KeyHdrList: PKeyHeaderList;
-    RollAngleList: PSingleList;
-  end;
-
-  PHotTrackTag = ^THotTrackTag;
-  THotTrackTag = record
-    TrackHdr: TTrackHeader3DS;
-    KeyHdrList: PKeyHeaderList;
-    HotspotAngleList: PSingleList;
-  end;
-
-  PFallTrackTag = ^TFallTrackTag;
-  TFallTrackTag = record
-    TrackHdr: TTrackHeader3DS;
-    KeyHdrList: PKeyHeaderList;
-    FalloffAngleList: PSingleList;
-  end;
-
-  PXDataEntry = ^TXDataEntry;
-  TXDataEntry = record
-    Size: Integer;
-    Data: Pointer;
-  end;
-
-  PXDataAppName = PChar3DS;
-
-  PXDataString = PChar3DS;
-
-  PXDataFloat = ^TXDataFloat;
-  TXDataFloat = Single;
-
-  PXDataDouble = ^TXDataDouble;
-  TXDataDouble = Double;
-
-  PXDataShort = ^TXDataShort;
-  TXDataShort = SmallInt;
-
-  PXDataLong = ^TXDataLong;
-  TXDataLong = Integer;
-
-  PXDataVoid = ^TXDataVoid;
-  TXDataVoid = Pointer;
-
-  TReleaseLevel = (rlRelease1, rlRelease2, rlRelease3, rlReleaseNotKnown);
-
-  (* To avoid zillion type casts, we use this variant record for
-   chunk data, effectively this defines the same pointer differently
-   for different chunk types
-   this is only possible because all types are just pointers *)
-  TChunkData = record
-    case Integer of
-      0:
-        (ColorF: PColorF);
-      1:
-        (LinColorF: PLinColorF);
-      2:
-        (Color24: PColor24);
-      3:
-        (LinColor24: PLinColor24);
-      4:
-        (IntPercentage: PIntPercentage);
-      5:
-        (FloatPercentage: PFloatPercentage);
-      6:
-        (MatMapname: PMatMapname);
-      7:
-        (M3dVersion: PM3dVersion);
-      8:
-        (MeshVersion: PMeshVersion);
-      9:
-        (MasterScale: PMasterScale);
-      10:
-        (LoShadowBias: PLoShadowBias);
-      11:
-        (ShadowFilter: PShadowFilter);
-      12:
-        (ShadowRange: PShadowRange);
-      13:
-        (HiShadowBias: PHiShadowBias);
-      14:
-        (RayBias: PRayBias);
-      15:
-        (ShadowMapSize: PShadowMapSize);
-      16:
-        (ShadowSamples: PShadowSamples);
-      17:
-        (OConsts: POConsts);
-      18:
-        (BitMapName: PBitMapName);
-      19:
-        (VGradient: PVGradient);
-      20:
-        (Fog: PFog);
-      21:
-        (LayerFog: PLayerFog);
-      22:
-        (DistanceCue: PDistanceCue);
-      23:
-        (ViewStandard: PViewStandard);
-      24:
-        (ViewUser: PViewUser);
-      25:
-        (ViewCamera: PViewCamera);
-      26:
-        (MatName: PMatName);
-      27:
-        (MatShading: PMatShading);
-      28:
-        (MatAcubic: PMatAcubic);
-      29:
-        (IpasData: PIpasData);
-      30:
-        (MatWireSize: PMatWireSize);
-      31:
-        (MatMapTiling: PMatMapTiling);
-      32:
-        (MatMapTexblur: PMatMapTexblur);
-      33:
-        (MatMapUScale: PMatMapUScale);
-      34:
-        (MatMapVScale: PMatMapVScale);
-      35:
-        (MatMapUOffset: PMatMapUOffset);
-      36:
-        (MatMapVOffset: PMatMapVOffset);
-      37:
-        (MatMapAng: PMatMapAng);
-      38:
-        (MatMapCol1: PMatMapCol1);
-      39:
-        (MatMapCol2: PMatMapCol2);
-      40:
-        (MatMapRCol: PMatMapRCol);
-      41:
-        (MatMapGCol: PMatMapGCol);
-      42:
-        (MatMapBCol: PMatMapBCol);
-      43:
-        (MatBumpPercent: PMatBumpPercent);
-      44:
-        (NamedObject: PNamedObject);
-      45:
-        (PointArray: PPointArray);
-      46:
-        (PointFlagArray: PPointFlagArray);
-      47:
-        (FaceArray: PFaceArray);
-      48:
-        (MshMatGroup: PMshMatGroup);
-      49:
-        (MshBoxmap: PMshBoxmap);
-      50:
-        (SmoothGroup: PSmoothGroup);
-      51:
-        (TexVerts: PTexVerts);
-      52:
-        (MeshMatrix: PMeshMatrix);
-      53:
-        (MeshColor: PMeshColor);
-      54:
-        (MeshTextureInfo: PMeshTextureInfo);
-      55:
-        (ProcName: PProcName);
-      56:
-        (NDirectLight: PNDirectLight);
-      57:
-        (DlExclude: PDlExclude);
-      58:
-        (DlInnerRange: PDlInnerRange);
-      59:
-        (DlOuterRange: PDlOuterRange);
-      60:
-        (DlMultiplier: PDlMultiplier);
-      61:
-        (DlSpotlight: PDlSpotlight);
-      62:
-        (DlLocalShadow2: PDlLocalShadow2);
-      63:
-        (DlSpotRoll: PDlSpotRoll);
-      64:
-        (DlSpotAspect: PDlSpotAspect);
-      65:
-        (DlSpotProjector: PDlSpotProjector);
-      66:
-        (DlRayBias: PDlRayBias);
-      67:
-        (NCamera: PNCamera);
-      68:
-        (CamRanges: PCamRanges);
-      69:
-        (ViewportLayout: PViewportLayout);
-      70:
-        (ViewportSize: PViewportSize);
-      71:
-        (ViewportData: PViewportData);
-      72:
-        (XDataEntry: PXDataEntry);
-      73:
-        (XDataAppName: PXDataAppName);
-      74:
-        (XDataString: PXDataString);
-      75:
-        (KFHdr: PKFHdr);
-      76:
-        (KFSeg: PKFSeg);
-      77:
-        (KFCurtime: PKFCurtime);
-      78:
-        (KFId: PKFId);
-      79:
-        (NodeHdr: PNodeHdr);
-      80:
-        (Pivot: PPivot);
-      81:
-        (InstanceName: PInstanceName);
-      82:
-        (MorphSmooth: PMorphSmooth);
-      83:
-        (BoundBox: PBoundBox);
-      84:
-        (PosTrackTag: PPosTrackTag);
-      85:
-        (ColTrackTag: PColTrackTag);
-      86:
-        (RotTrackTag: PRotTrackTag);
-      87:
-        (ScaleTrackTag: PScaleTrackTag);
-      88:
-        (MorphTrackTag: PMorphTrackTag);
-      89:
-        (FovTrackTag: PFovTrackTag);
-      90:
-        (RollTrackTag: PRollTrackTag);
-      91:
-        (HotTrackTag: PHotTrackTag);
-      92:
-        (FallTrackTag: PFallTrackTag);
-      93:
-        (HideTrackTag: PHideTrackTag);
-      99:
-        (Dummy: Pointer);
-  end;
-
-  // finally the chunk definition
-  TChunk3DS = record
-    Tag: Word; // Type of Chunk
-    Size: Cardinal; // Number of bytes used by Chunk
-    Position: Cardinal; // Offset in Source file
-    Data: TChunkData; // Memory copy of file Data
-    Sibling: PChunk3DS; // Next Chunk in database
-    Children: PChunk3DS; // Chunks contained within this Chunk
-  end;
-
-// ---------------------------------------------------------------------------------------------------------------------
-implementation
-// ---------------------------------------------------------------------------------------------------------------------
-
-end.

+ 0 - 6789
Source/FMX/Formatx.m3DSUtils.pas

@@ -1,6789 +0,0 @@
-//
-// The graphics platform GLXcene https://github.com/glscene
-//
-unit Formatx.m3DSUtils;
-(*
-   Utility functions for the universal 3DS file reader and writer (TFile3DS).
-   Essentially, the functions here are the heart of the import library as
-   they deal actually with the database and chunks.
-*)
-interface
-
-{$I GLX.Scene.inc}
-{$R-}
-
-uses
-  System.SysUtils,
-  System.Classes,
-
-  GLX.Strings,
-  Formatx.m3DSConst,
-  Formatx.m3DS,
-  Formatx.m3DSTypes;
-
-// functions to retrieve global settings of a specific 3DS database
-function GetAtmosphere(const Source: TFile3DS; var DB: TDatabase3DS): TAtmosphere3DS;
-function GetBackground(const Source: TFile3DS; var DB: TDatabase3DS): TBackground3DS;
-function GetMeshSet(const Source: TFile3DS; var DB: TDatabase3DS): TMeshSet3DS;
-function GetViewport(const Source: TFile3DS; var DB: TDatabase3DS): TViewport3DS;
-
-// functions to retrieve/modify data related to materials, lights and objects (meshs)
-procedure AddChild(Parent, Child: PChunk3DS);
-procedure AddChildOrdered(Parent, Child: PChunk3DS);
-function FindChunk(Top: PChunk3DS; Tag: word): PChunk3DS;
-function FindNextChunk(Local: PChunk3DS; Tag: word): PChunk3DS;
-procedure FreeChunkData(var Chunk: PChunk3DS);
-function GetCameraByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: integer): TCamera3DS;
-function GetCameraCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-function GetChunkValue(Tag: word): integer;
-function GetMaterialByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: integer): TMaterial3DS;
-function GetMaterialCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-function GetMeshByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: integer): TMesh3DS;
-function GetMeshCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-function GetOmnilightByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: integer): TLight3DS;
-function GetSpotlightByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: integer): TLight3DS;
-function GetOmnilightCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-function GetSpotlightCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-procedure InitChunk(var Chunk: PChunk3DS);
-procedure ReleaseCamera(Camera: PCamera3DS);
-procedure ReleaseChunk(var Chunk: PChunk3DS);
-procedure ReleaseChunkList(var List: PChunkList3DS);
-procedure ReleaseLight(Light: PLight3DS);
-procedure ReleaseMaterial(Mat: PMaterial3DS);
-procedure ReleaseMeshObj(Mesh: PMesh3DS);
-
-// functions to retrieve/modify keyframer (animation) data
-function GetKFSettings(const Source: TFile3DS; var DB: TDatabase3DS): TKFSets3DS;
-
-procedure ReleaseCameraMotion(Camera: PKFCamera3DS);
-procedure GetCameraNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
-  List: TStringList);
-function GetCameraNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-function GetCameraMotion(const Source: TFile3DS;
-  CamChunk, TargetChunk: PChunk3DS): TKFCamera3DS;
-function GetCameraMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: integer): TKFCamera3DS;
-
-procedure ReleaseAmbientLightMotion(Light: PKFAmbient3DS);
-function GetAmbientLightMotion(const Source: TFile3DS;
-  var DB: TDatabase3DS): TKFAmbient3DS;
-
-procedure InitObjectMotion(var Obj: TKFMesh3DS;
-  NewNPKeys, NewNRKeys, NewNSKeys, NewNMKeys, NewNHKeys: cardinal);
-procedure ReleaseObjectMotion(Obj: PKFMesh3DS);
-procedure GetObjectNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
-  List: TStringList);
-function GetObjectNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-function GetObjectMotionByName(const Source: TFile3DS; var DB: TDatabase3DS;
-  Name: string): TKFMesh3DS;
-function GetObjectMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: cardinal): TKFMesh3DS;
-
-procedure ReleaseOmnilightMotion(Light: PKFOmni3DS);
-procedure GetOmnilightNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
-  List: TStringList);
-function GetOmnilightNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): cardinal;
-function GetOmnilightMotionByName(const Source: TFile3DS; var DB: TDatabase3DS;
-  Name: string): TKFOmni3DS;
-function GetOmnilightMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: cardinal): TKFOmni3DS;
-
-procedure ReleaseSpotlightMotion(Spot: PKFSpot3DS);
-procedure GetSpotlightNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
-  List: TStringList);
-function GetSpotlightNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): cardinal;
-function GetSpotlightMotionByName(const Source: TFile3DS; var DB: TDatabase3DS;
-  Name: string): TKFSpot3DS;
-function GetSpotlightMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: cardinal): TKFSpot3DS;
-
-// version information
-function GetM3dMagicRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
-function GetMeshRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
-function GetKfRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
-function GetDatabaseRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
-
-// support functions for text output of chunk and database contents
-procedure ChunkHeaderReport(var Strings: TStrings; Chunk: PChunk3DS;
-  IndentLevel: integer);
-function ChunkTagToString(Tag: word): string;
-procedure DumpChunk(const Source: TFile3DS; var Strings: TStrings;
-  Chunk: PChunk3DS; IndentLevel: integer; DumpLevel: TDumpLevel);
-procedure DumpKeyHeader(Strings: TStrings; Key: TKeyHeader3DS; IndentLevel: integer);
-
-// support functions for chunk handling
-procedure DeleteChunk(var Chunk: PChunk3DS);
-function FindNamedObjectByIndex(Source: TFile3DS; DB: TDatabase3DS;
-  AType: word; Index: integer): PChunk3DS;
-
-// error message routines
-procedure ShowError(strErrorMessage: string);
-procedure ShowErrorFormatted(strErrorMessage: string; const Args: array of const);
-
-//-----------------------------------------------------------------------------
-implementation
-//-----------------------------------------------------------------------------
-
-type
-  E3DSError = class(Exception);
-
-//----------------- error handling ------------------------------------------------------------------------------------
-
-procedure ShowError(strErrorMessage: string);
-begin
-  raise E3DSError.Create(strErrorMessage);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ShowErrorFormatted(strErrorMessage: string; const Args: array of const);
-begin
-  raise E3DSError.CreateFmt(strErrorMessage, Args);
-end;
-
-//----------------- global settings functions -------------------------------------------------------------------------
-
-function InitMeshSet: TMeshSet3DS;
-
-  // initializes a mesh settings structure
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-  with Result do
-  begin
-    MasterScale := 1;
-    Shadow.Bias := 1;
-    Shadow.RayBias := 1;
-    Shadow.MapSize := 512;
-    Shadow.Filter := 3;
-    AmbientLight.R := 0.39216;
-    AmbientLight.G := 0.39216;
-    AmbientLight.B := 0.39216;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetMeshSet(const Source: TFile3DS; var DB: TDatabase3DS): TMeshSet3DS;
-
-  // retrieves the mesh settings from the database
-
-var
-  MDataChunk, ColorChunk, Chunk: PChunk3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  // find the mesh data chunk
-  MDataChunk := FindChunk(DB.TopChunk, MDATA);
-
-  // If the mesh data section is found
-  if Assigned(MDataChunk) then
-  begin
-    Result := InitMeshSet;
-    with Result do
-    begin
-      // Search for a master_scale chunk
-      Chunk := FindNextChunk(MDataChunk^.Children, MASTER_SCALE);
-      if Assigned(Chunk) then
-      begin
-        Source.ReadChunkData(Chunk);
-        MasterScale := Chunk^.Data.MasterScale^;
-        FreeChunkData(Chunk);
-      end;
-
-      // search for Lo_Shadow_Bias chunk
-      Chunk := FindNextChunk(MDataChunk^.Children, LO_SHADOW_BIAS);
-      if Assigned(Chunk) then
-      begin
-        Source.ReadChunkData(Chunk);
-        Shadow.Bias := Chunk^.Data.LoShadowBias^;
-        FreeChunkData(Chunk);
-      end;
-
-      // Search for ray_Bias Chunk
-      Chunk := FindNextChunk(MDataChunk^.Children, RAY_BIAS);
-      if Assigned(Chunk) then
-      begin
-        Source.ReadChunkData(Chunk);
-        Shadow.RayBias := Chunk^.Data.RayBias^;
-        FreeChunkData(Chunk);
-      end;
-
-      // search for MapSize Chunk
-      Chunk := FindNextChunk(MDataChunk^.Children, SHADOW_MAP_SIZE);
-      if Assigned(Chunk) then
-      begin
-        Source.ReadChunkData(Chunk);
-        Shadow.MapSize := Chunk^.Data.ShadowMapSize^;
-        FreeChunkData(Chunk);
-      end;
-
-      // search for Shadow_Filter Chunk
-      Chunk := FindNextChunk(MDataChunk^.Children, SHADOW_FILTER);
-      if Assigned(Chunk) then
-      begin
-        Source.ReadChunkData(Chunk);
-        Shadow.Filter := Chunk^.Data.ShadowFilter^;
-        FreeChunkData(Chunk);
-      end;
-
-      // search for ambient_light Chunk
-      Chunk := FindNextChunk(MDataChunk^.Children, AMBIENT_LIGHT);
-      if Assigned(Chunk) then
-      begin
-        // search for the old style Color chunk inside the ambient Light Chunk
-        ColorChunk := FindChunk(Chunk, COLOR_F);
-        if Assigned(ColorChunk) then
-        begin
-          Source.ReadChunkData(ColorChunk);
-          AmbientLight.R := ColorChunk^.Data.ColorF^.Red;
-          AmbientLight.G := ColorChunk^.Data.ColorF^.Green;
-          AmbientLight.B := ColorChunk^.Data.ColorF^.Blue;
-          FreeChunkData(ColorChunk);
-        end
-        else
-        begin
-          // just for robust completeness, search for the COLOR_24 chunk
-          ColorChunk := FindChunk(Chunk, COLOR_24);
-          if Assigned(ColorChunk) then
-          begin
-            Source.ReadChunkData(ColorChunk);
-            AmbientLight.R := ColorChunk^.Data.Color24^.Red / 255;
-            AmbientLight.G := ColorChunk^.Data.Color24^.Green / 255;
-            AmbientLight.B := ColorChunk^.Data.Color24^.Blue / 255;
-            FreeChunkData(ColorChunk);
-          end;
-        end;
-
-        // search for the newer linear Color Chunk inside the ambient Light chunk
-        ColorChunk := FindChunk(Chunk, LIN_COLOR_F);
-        if Assigned(ColorChunk) then
-        begin
-          Source.ReadChunkData(ColorChunk);
-          AmbientLight.R := ColorChunk^.Data.LinColorF^.Red;
-          AmbientLight.G := ColorChunk^.Data.LinColorF^.Green;
-          AmbientLight.B := ColorChunk^.Data.LinColorF^.Blue;
-          FreeChunkData(ColorChunk);
-        end
-        else
-        begin
-          // just for completeness, search for the LIN_COLOR_24 chunk
-          ColorChunk := FindChunk(Chunk, LIN_COLOR_24);
-          if Assigned(ColorChunk) then
-          begin
-            Source.ReadChunkData(ColorChunk);
-            AmbientLight.R := ColorChunk^.Data.LinColorF^.Red / 255;
-            AmbientLight.G := ColorChunk^.Data.LinColorF^.Green / 255;
-            AmbientLight.B := ColorChunk^.Data.LinColorF^.Blue / 255;
-            FreeChunkData(ColorChunk);
-          end;
-        end;
-      end;
-
-      // Search for the oconst chunk
-      Chunk := FindNextChunk(MDataChunk^.Children, O_CONSTS);
-      if Assigned(Chunk) then
-      begin
-        Source.ReadChunkData(Chunk);
-        oconsts.x := Chunk^.Data.OConsts^.X;
-        oconsts.y := Chunk^.Data.OConsts^.Y;
-        oconsts.z := Chunk^.Data.OConsts^.Z;
-        FreeChunkData(Chunk);
-      end;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function InitAtmosphere: TAtmosphere3DS;
-
-  // initializes a atmosphere structure
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-  with Result do
-  begin
-    Fog.FarPlane := 1000;
-    Fog.FarDensity := 100;
-    Fog.FogBgnd := True;
-
-    LayerFog.ZMax := 100;
-    LayerFog.Density := 50;
-    LayerFog.Falloff := lfNoFall;
-    LayerFog.Fogbgnd := True;
-
-    DCue.FarPlane := 1000;
-    DCue.FarDim := 100;
-
-    ActiveAtmo := atNoAtmo;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetAtmosphere(const Source: TFile3DS; var DB: TDatabase3DS): TAtmosphere3DS;
-
-  // retrieves the atmospheric settings from database
-
-var
-  MDataChunk, FogChunk, BgnChunk, ColorChunk, Chunk: PChunk3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  // find the MDATA chunk
-  MDataChunk := FindChunk(DB.TopChunk, MDATA);
-
-  // if the MDATA chunk was found, then search for the atmospheric chunks
-  if Assigned(MDataChunk) then
-  begin
-    Result := InitAtmosphere;
-    // Search for fog chunk
-    FogChunk := FindChunk(MDataChunk, FOG);
-    if Assigned(FogChunk) then
-      with Result do
-      begin
-        // read the chunk information
-        Source.ReadChunkData(FogChunk);
-
-        // Copy the FogChunk data into the structure
-        Fog.NearPlane := FogChunk^.Data.Fog^.NearPlaneDist;
-        Fog.NearDensity := FogChunk^.Data.Fog^.NearPlaneDensity;
-        Fog.FarPlane := FogChunk^.Data.Fog^.FarPlanedist;
-        Fog.FarDensity := FogChunk^.Data.Fog^.FarPlaneDensity;
-
-        // Search for fog Color chunk
-        ColorChunk := FindChunk(FogChunk, COLOR_F);
-        if Assigned(ColorChunk) then
-        begin
-          Source.ReadChunkData(ColorChunk);
-          Fog.FogColor.R := ColorChunk^.Data.ColorF^.Red;
-          Fog.Fogcolor.G := ColorChunk^.Data.ColorF^.Green;
-          Fog.Fogcolor.B := ColorChunk^.Data.ColorF^.Blue;
-          FreeChunkData(ColorChunk);
-        end;
-
-        // Search for FOG_BGND chunk
-        BgnChunk := FindChunk(FogChunk, FOG_BGND);
-        if Assigned(BgnChunk) then
-          Fog.FogBgnd := True
-        else
-          Fog.FogBgnd := False;
-        FreeChunkData(FogChunk);
-
-        // search for LAYER_FOG chunk
-        FogChunk := FindChunk(MDataChunk, LAYER_FOG);
-        if Assigned(FogChunk) then
-        begin
-          Source.ReadChunkData(FogChunk);
-
-          LayerFog.ZMin := FogChunk^.Data.LayerFog^.ZMin;
-          LayerFog.ZMax := FogChunk^.Data.LayerFog^.ZMax;
-          LayerFog.Density := FogChunk^.Data.LayerFog^.Density;
-
-          if (FogChunk^.Data.LayerFog^.AType and LayerFogBgnd) <> 0 then
-            LayerFog.FogBgnd := True
-          else
-            LayerFog.FogBgnd := False;
-
-          if (FogChunk^.Data.LayerFog^.AType and TopFalloff) <> 0 then
-            LayerFog.Falloff := lfTopFall
-          else if (FogChunk^.Data.LayerFog^.AType and BottomFalloff) <> 0 then
-            LayerFog.Falloff := lfBottomFall
-          else
-            LayerFog.Falloff := lfNoFall;
-
-          ColorChunk := FindChunk(FogChunk, COLOR_F);
-          if Assigned(ColorChunk) then
-          begin
-            Source.ReadChunkData(ColorChunk);
-            LayerFog.FogColor.R := ColorChunk^.Data.ColorF^.Red;
-            LayerFog.Fogcolor.G := ColorChunk^.Data.ColorF^.Green;
-            LayerFog.Fogcolor.B := ColorChunk^.Data.ColorF^.Blue;
-            FreeChunkData(ColorChunk);
-          end;
-          FreeChunkData(FogChunk);
-        end;
-
-        // search for DISTANCE_CUE chunk
-        Chunk := FindChunk(MDataChunk, DISTANCE_CUE);
-        if Assigned(Chunk) then
-        begin
-          Source.ReadChunkData(Chunk);
-
-          DCue.NearPlane := Chunk^.Data.DistanceCue^.NearPlaneDist;
-          DCue.neardim := Chunk^.Data.DistanceCue^.NearPlaneDimming;
-          DCue.FarPlane := Chunk^.Data.DistanceCue^.FarPlaneDist;
-          DCue.FarDim := Chunk^.Data.DistanceCue^.FarPlaneDimming;
-
-          BgnChunk := FindChunk(Chunk, DCUE_BGND);
-          if Assigned(BgnChunk) then
-            DCue.DCueBgnd := True
-          else
-            DCue.DCueBgnd := False;
-          FreeChunkData(Chunk);
-        end;
-
-        // search for USE_FOG, USE_LAYER_FOG or USE_DISTANCE_CUE chunk
-        Chunk := FindChunk(MDataChunk, USE_FOG);
-        if Assigned(Chunk) then
-          ActiveAtmo := atUseFog
-        else
-        begin
-          Chunk := FindChunk(MDataChunk, USE_LAYER_FOG);
-          if Assigned(Chunk) then
-            ActiveAtmo := atUseLayerFog
-          else
-          begin
-            Chunk := FindChunk(MDataChunk, USE_DISTANCE_CUE);
-            if Assigned(Chunk) then
-              ActiveAtmo := atUseDistanceCue
-            else
-              ActiveAtmo := atNoAtmo;
-          end;
-        end;
-      end; // with Result do
-  end; // if Assigned(MDataChunk)
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function InitBackground: TBackground3DS;
-
-  // initializes the TBackground3DS structure
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-  Result.VGradient.GradPercent := 0.5;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetBackground(const Source: TFile3DS; var DB: TDatabase3DS): TBackground3DS;
-
-  // retrieves the background settings from the database
-
-var
-  MDataChunk, ColorChunk, TopColor, MidColor, BotColor, Chunk: PChunk3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  // Find the MDATA chunk
-  MDataChunk := FindChunk(DB.TopChunk, MDATA);
-
-  // only continue with structure filling if an MDATA chunk is found
-  if Assigned(MDataChunk) then
-    with Result do
-    begin
-      Result := InitBackground;
-      // search for bitmap chunk
-      Chunk := FindChunk(MDataChunk, BIT_MAP);
-      if Assigned(Chunk) then
-      begin
-        // read the chunk information
-        Source.ReadChunkData(Chunk);
-        // copy the bitmap filename to the structure
-        if Assigned(Chunk^.Data.BitmapName) then
-          Bitmap := Chunk^.Data.BitmapName^
-        else
-          Bitmap := '';
-        FreeChunkData(Chunk);
-      end;
-
-      Chunk := FindChunk(MDataChunk, SOLID_BGND);
-      if Assigned(Chunk) then
-      begin
-        ColorChunk := FindChunk(Chunk, COLOR_F);
-        if Assigned(ColorChunk) then
-        begin
-          Source.ReadChunkData(ColorChunk);
-          Solid.R := ColorChunk^.Data.ColorF^.Red;
-          Solid.G := ColorChunk^.Data.ColorF^.Green;
-          Solid.B := ColorChunk^.Data.ColorF^.Blue;
-          FreeChunkData(ColorChunk);
-        end;
-
-        ColorChunk := FindChunk(Chunk, LIN_COLOR_F);
-        if Assigned(ColorChunk) then
-        begin
-          Source.ReadChunkData(ColorChunk);
-          Solid.R := ColorChunk^.Data.ColorF^.Red;
-          Solid.G := ColorChunk^.Data.ColorF^.Green;
-          Solid.B := ColorChunk^.Data.ColorF^.Blue;
-          FreeChunkData(ColorChunk);
-        end;
-      end;
-
-      Chunk := FindChunk(MDataChunk, V_GRADIENT);
-      if Assigned(Chunk) then
-      begin
-        // the COLOR_F chunks are the old, non-gamma corrected colors
-        Source.ReadChunkData(Chunk);
-        VGradient.GradPercent := Chunk^.Data.VGradient^;
-        TopColor := FindChunk(Chunk, COLOR_F);
-        if Assigned(TopColor) then
-        begin
-          Source.ReadChunkData(TopColor);
-          VGradient.Top.R := TopColor^.Data.ColorF^.Red;
-          VGradient.Top.G := TopColor^.Data.ColorF^.Green;
-          VGradient.Top.B := TopColor^.Data.ColorF^.Blue;
-          MidColor := FindNextChunk(TopColor^.Sibling, COLOR_F);
-          if Assigned(MidColor) then
-          begin
-            Source.ReadChunkData(MidColor);
-            VGradient.Mid.R := MidColor^.Data.ColorF^.Red;
-            VGradient.Mid.G := MidColor^.Data.ColorF^.Green;
-            VGradient.Mid.B := MidColor^.Data.ColorF^.Blue;
-            BotColor := FindNextChunk(MidColor^.Sibling, COLOR_F);
-            if Assigned(BotColor) then
-            begin
-              Source.ReadChunkData(BotColor);
-              VGradient.Bottom.R := MidColor^.Data.ColorF^.Red;
-              VGradient.Bottom.G := MidColor^.Data.ColorF^.Green;
-              VGradient.Bottom.B := MidColor^.Data.ColorF^.Blue;
-              FreeChunkData(BotColor);
-            end;
-            FreeChunkData(MidColor);
-          end;
-          FreeChunkData(TopColor);
-        end;
-
-        // If the newer, gamma correct colors are available, then use them instead
-        TopColor := FindChunk(Chunk, LIN_COLOR_F);
-        if Assigned(TopColor) then
-        begin
-          Source.ReadChunkData(TopColor);
-          VGradient.Top.R := TopColor^.Data.ColorF^.Red;
-          VGradient.Top.G := TopColor^.Data.ColorF^.Green;
-          VGradient.Top.B := TopColor^.Data.ColorF^.Blue;
-          MidColor := FindNextChunk(TopColor^.Sibling, LIN_COLOR_F);
-          if Assigned(MidColor) then
-          begin
-            Source.ReadChunkData(MidColor);
-            VGradient.Mid.R := MidColor^.Data.ColorF^.Red;
-            VGradient.Mid.G := MidColor^.Data.ColorF^.Green;
-            VGradient.Mid.B := MidColor^.Data.ColorF^.Blue;
-            BotColor := FindNextChunk(MidColor^.Sibling, LIN_COLOR_F);
-            if Assigned(BotColor) then
-            begin
-              Source.ReadChunkData(BotColor);
-              VGradient.Bottom.R := MidColor^.Data.ColorF^.Red;
-              VGradient.Bottom.G := MidColor^.Data.ColorF^.Green;
-              VGradient.Bottom.B := MidColor^.Data.ColorF^.Blue;
-              FreeChunkData(BotColor);
-            end;
-            FreeChunkData(MidColor);
-          end;
-          FreeChunkData(TopColor);
-        end;
-        FreeChunkData(Chunk);
-      end;
-
-      // Search for use_bitmap, use_solid_bgnd and use_v_gradient chunks
-      Chunk := FindChunk(MDataChunk, USE_BIT_MAP);
-      if Assigned(Chunk) then
-        BgndUsed := btUseBitmapBgnd
-      else
-      begin
-        Chunk := FindChunk(MDataChunk, USE_SOLID_BGND);
-        if Assigned(Chunk) then
-          BgndUsed := btUseSolidBgnd
-        else
-        begin
-          Chunk := FindChunk(MDataChunk, USE_V_GRADIENT);
-          if Assigned(Chunk) then
-            BgndUsed := btUseVGradientBgnd
-          else
-            BgndUsed := btNoBgnd;
-        end;
-      end;
-    end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function InitViewport: TViewport3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-  with Result do
-  begin
-    AType := vtTopView3DS;
-    Ortho.Zoom := 0.7395;
-    User.Zoom := 0.7395;
-    User.HorAng := 20;
-    User.VerAng := 30;
-    CameraStr := '';
-    Size.Width := 1000;
-    Size.Height := 1000;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetViewportEntry(Source: TFile3DS; Section: PChunk3DS): TViewport3DS;
-
-var
-  Chunk, VLayout: PChunk3DS;
-  PortIndex: integer;
-  foundV3: boolean;
-
-begin
-  Result := InitViewport;
-  VLayout := FindNextChunk(Section^.Children, VIEWPORT_LAYOUT);
-
-  if Assigned(VLayout) then
-    with Result do
-    begin
-      Source.ReadChunkData(VLayout);
-
-      Chunk := VLayout^.Children;
-      foundV3 := False;
-      PortIndex := 0;
-      while Assigned(Chunk) do
-      begin
-        case Chunk^.Tag of
-          VIEWPORT_SIZE:
-          begin
-            Source.ReadChunkData(Chunk);
-            Size.XPos := Chunk^.Data.ViewportSize^.XPos;
-            Size.YPos := Chunk^.Data.ViewportSize^.YPos;
-            Size.Width := Chunk^.Data.ViewportSize^.Width;
-            Size.Height := Chunk^.Data.ViewportSize^.Height;
-            FreeChunkData(Chunk);
-          end;
-          VIEWPORT_DATA_3:
-          begin
-            foundV3 := True;
-            if PortIndex = VLayout^.Data.ViewportLayout^.Top then
-            begin
-              Source.ReadChunkData(Chunk);
-              case Chunk^.Data.ViewportData^.View of
-                1:
-                  AType := vtTopView3DS;
-                2:
-                  AType := vtBottomView3DS;
-                3:
-                  AType := vtLeftView3DS;
-                4:
-                  AType := vtRightView3DS;
-                5:
-                  AType := vtFrontView3DS;
-                6:
-                  AType := vtBackView3DS;
-                7:
-                  AType := vtUserView3DS;
-                18:
-                  AType := vtSpotlightView3DS;
-                $FFFF:
-                  AType := vtCameraView3DS;
-                else
-                  AType := vtNoView3DS;
-              end;
-
-              Ortho.Zoom := Chunk^.Data.ViewportData^.ZoomFactor;
-              User.Zoom := Chunk^.Data.ViewportData^.ZoomFactor;
-              Ortho.Center.X := Chunk^.Data.ViewportData^.Center.X;
-              User.Center.X := Chunk^.Data.ViewportData^.Center.X;
-              Ortho.Center.Y := Chunk^.Data.ViewportData^.Center.Y;
-              User.Center.y := Chunk^.Data.ViewportData^.Center.Y;
-              Ortho.Center.Z := Chunk^.Data.ViewportData^.Center.Z;
-              User.Center.z := Chunk^.Data.ViewportData^.Center.Z;
-              User.HorAng := Chunk^.Data.ViewportData^.HorizAng;
-              User.VerAng := Chunk^.Data.ViewportData^.VertAng;
-              CameraStr := string(Chunk^.Data.ViewportData^.CamNameStr);
-            end;
-            Inc(PortIndex);
-          end;
-          VIEWPORT_DATA:
-            if not foundV3 then
-            begin
-              if PortIndex = VLayout^.Data.ViewportLayout^.Top then
-              begin
-                Source.ReadChunkData(Chunk);
-                case Chunk^.Data.ViewportData^.View of
-                  1:
-                    AType := vtTopView3DS;
-                  2:
-                    AType := vtBottomView3DS;
-                  3:
-                    AType := vtLeftView3DS;
-                  4:
-                    AType := vtRightView3DS;
-                  5:
-                    AType := vtFrontView3DS;
-                  6:
-                    AType := vtBackView3DS;
-                  7:
-                    AType := vtUserView3DS;
-                  18:
-                    AType := vtSpotlightView3DS;
-                  $FFFF:
-                    AType := vtCameraView3DS;
-                  else
-                    AType := vtNoView3DS;
-                end;
-
-                Ortho.Zoom := Chunk^.Data.ViewportData^.ZoomFactor;
-                User.Zoom := Chunk^.Data.ViewportData^.ZoomFactor;
-                Ortho.Center.X := Chunk^.Data.ViewportData^.Center.X;
-                User.Center.X := Chunk^.Data.ViewportData^.Center.X;
-                Ortho.Center.Y := Chunk^.Data.ViewportData^.Center.Y;
-                User.Center.y := Chunk^.Data.ViewportData^.Center.Y;
-                Ortho.Center.Z := Chunk^.Data.ViewportData^.Center.Z;
-                User.Center.z := Chunk^.Data.ViewportData^.Center.Z;
-                User.HorAng := Chunk^.Data.ViewportData^.HorizAng;
-                User.VerAng := Chunk^.Data.ViewportData^.VertAng;
-                CameraStr := string(Chunk^.Data.ViewportData^.CamNameStr);
-              end;
-              Inc(PortIndex);
-            end;
-        end;
-        Chunk := Chunk^.Sibling;
-      end;
-    end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetViewport(const Source: TFile3DS; var DB: TDatabase3DS): TViewport3DS;
-
-var
-  Data: PChunk3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-  if (DB.TopChunk^.Tag = M3DMAGIC) or (DB.TopChunk^.Tag = CMAGIC) then
-  begin
-    Data := FindNextChunk(DB.TopChunk^.Children, KFDATA);
-    if Assigned(Data) then
-      Result := GetViewportEntry(Source, Data)
-    else
-    begin
-      Data := FindChunk(DB.TopChunk^.Children, MDATA);
-      if Assigned(Data) then
-        Result := GetViewportEntry(Source, Data);
-    end;
-  end;
-end;
-
-//----------------- helper funcs for text output ----------------------------------------------------------------------
-
-function ChunkTagToString(Tag: word): string;
-
-begin
-  case Tag of
-    NULL_CHUNK: Result := 'NULL_CHUNK';
-    ChunkType: Result := 'ChunkType';
-    ChunkUnique: Result := 'ChunkUnique';
-    NotChunk: Result := 'NotChunk';
-    Container: Result := 'Container';
-    IsChunk: Result := 'IsChunk';
-
-    // Dummy Chunk that sometimes appears in 3DS files created by prerelease 3D Studio R2
-    DUMMY: Result := 'DUMMY';
-
-    // Trick Chunk Types
-    POINT_ARRAY_ENTRY: Result := 'POINT_ARRAY_ENTRY';
-    POINT_FLAG_ARRAY_ENTRY: Result := 'POINT_FLAG_ARRAY_ENTRY';
-    FACE_ARRAY_ENTRY: Result := 'FACE_ARRAY_ENTRY';
-    MSH_MAT_GROUP_ENTRY: Result := 'MSH_MAT_GROUP_ENTRY';
-    TEX_VERTS_ENTRY: Result := 'TEX_VERTS_ENTRY';
-    SMOOTH_GROUP_ENTRY: Result := 'SMOOTH_GROUP_ENTRY';
-    POS_TRACK_TAG_KEY: Result := 'POS_TRACK_TAG_KEY';
-    ROT_TRACK_TAG_KEY: Result := 'ROT_TRACK_TAG_KEY';
-    SCL_TRACK_TAG_KEY: Result := 'SCL_TRACK_TAG_KEY';
-    FOV_TRACK_TAG_KEY: Result := 'FOV_TRACK_TAG_KEY';
-    ROLL_TRACK_TAG_KEY: Result := 'ROLL_TRACK_TAG_KEY';
-    COL_TRACK_TAG_KEY: Result := 'COL_TRACK_TAG_KEY';
-    MORPH_TRACK_TAG_KEY: Result := 'MORPH_TRACK_TAG_KEY';
-    HOT_TRACK_TAG_KEY: Result := 'HOT_TRACK_TAG_KEY';
-    FALL_TRACK_TAG_KEY: Result := 'FALL_TRACK_TAG_KEY';
-
-    // 3DS File Chunk IDs
-    M3DMAGIC: Result := 'M3DMAGIC';
-    SMAGIC: Result := 'SMAGIC';
-    LMAGIC: Result := 'LMAGIC';
-    MLIBMAGIC: Result := 'MLIBMAGIC';
-    MATMAGIC: Result := 'MATMAGIC';
-    M3D_VERSION: Result := 'M3D_VERSION';
-    M3D_KFVERSION: Result := 'M3D_KFVERSION';
-
-    // Mesh Chunk Ids
-    MDATA: Result := 'MDATA';
-    MESH_VERSION: Result := 'MESH_VERSION';
-    COLOR_F: Result := 'COLOR_F';
-    COLOR_24: Result := 'COLOR_24';
-    LIN_COLOR_24: Result := 'LIN_COLOR_24';
-    LIN_COLOR_F: Result := 'LIN_COLOR_F';
-    INT_PERCENTAGE: Result := 'INT_PERCENTAGE';
-    FLOAT_PERCENTAGE: Result := 'FLOAT_PERCENTAGE';
-
-    MASTER_SCALE: Result := 'MASTER_SCALE';
-
-    BIT_MAP: Result := 'BIT_MAP';
-    USE_BIT_MAP: Result := 'USE_BIT_MAP';
-    SOLID_BGND: Result := 'SOLID_BGND';
-    USE_SOLID_BGND: Result := 'USE_SOLID_BGND';
-    V_GRADIENT: Result := 'V_GRADIENT';
-    USE_V_GRADIENT: Result := 'USE_V_GRADIENT';
-
-    LO_SHADOW_BIAS: Result := 'LO_SHADOW_BIAS';
-    HI_SHADOW_BIAS: Result := 'HI_SHADOW_BIAS';
-    SHADOW_MAP_SIZE: Result := 'SHADOW_MAP_SIZE';
-    SHADOW_SAMPLES: Result := 'SHADOW_SAMPLES';
-    SHADOW_RANGE: Result := 'SHADOW_RANGE';
-    SHADOW_FILTER: Result := 'SHADOW_FILTER';
-    RAY_BIAS: Result := 'RAY_BIAS';
-
-    O_CONSTS: Result := 'O_CONSTS';
-
-    AMBIENT_LIGHT: Result := 'AMBIENT_LIGHT';
-
-    FOG: Result := 'FOG';
-    USE_FOG: Result := 'USE_FOG';
-    FOG_BGND: Result := 'FOG_BGND';
-    DISTANCE_CUE: Result := 'DISTANCE_CUE';
-    USE_DISTANCE_CUE: Result := 'USE_DISTANCE_CUE';
-    LAYER_FOG: Result := 'LAYER_FOG';
-    USE_LAYER_FOG: Result := 'USE_LAYER_FOG';
-    DCUE_BGND: Result := 'DCUE_BGND';
-
-    DEFAULT_VIEW: Result := 'DEFAULT_VIEW';
-    VIEW_TOP: Result := 'VIEW_TOP';
-    VIEW_BOTTOM: Result := 'VIEW_BOTTOM';
-    VIEW_LEFT: Result := 'VIEW_LEFT';
-    VIEW_RIGHT: Result := 'VIEW_RIGHT';
-    VIEW_FRONT: Result := 'VIEW_FRONT';
-    VIEW_BACK: Result := 'VIEW_BACK';
-    VIEW_USER: Result := 'VIEW_USER';
-    VIEW_CAMERA: Result := 'VIEW_CAMERA';
-    VIEW_WINDOW: Result := 'VIEW_WINDOW';
-
-    NAMED_OBJECT: Result := 'NAMED_OBJECT';
-    OBJ_HIDDEN: Result := 'OBJ_HIDDEN';
-    OBJ_VIS_LOFTER: Result := 'OBJ_VIS_LOFTER';
-    OBJ_DOESNT_CAST: Result := 'OBJ_DOESNT_CAST';
-    OBJ_MATTE: Result := 'OBJ_MATTE';
-    OBJ_FAST: Result := 'OBJ_FAST';
-    OBJ_PROCEDURAL: Result := 'OBJ_PROCEDURAL';
-    OBJ_FROZEN: Result := 'OBJ_FROZEN';
-    OBJ_DONT_RCVSHADOW: Result := 'OBJ_DONT_RCVSHADOW';
-
-    N_TRI_OBJECT: Result := 'N_TRI_OBJECT';
-
-    POINT_ARRAY: Result := 'POINT_ARRAY';
-    POINT_FLAG_ARRAY: Result := 'POINT_FLAG_ARRAY';
-    FACE_ARRAY: Result := 'FACE_ARRAY';
-    MSH_MAT_GROUP: Result := 'MSH_MAT_GROUP';
-    OLD_MAT_GROUP: Result := 'OLD_MAT_GROUP';
-    TEX_VERTS: Result := 'TEX_VERTS';
-    SMOOTH_GROUP: Result := 'SMOOTH_GROUP';
-    MESH_MATRIX: Result := 'MESH_MATRIX';
-    MESH_COLOR: Result := 'MESH_COLOR';
-    MESH_TEXTURE_INFO: Result := 'MESH_TEXTURE_INFO';
-    PROC_NAME: Result := 'PROC_NAME';
-    PROC_DATA: Result := 'PROC_DATA';
-    MSH_BOXMAP: Result := 'MSH_BOXMAP';
-
-    N_D_L_OLD: Result := 'N_D_L_OLD';
-
-    N_CAM_OLD: Result := 'N_CAM_OLD';
-
-    N_DIRECT_LIGHT: Result := 'N_DIRECT_LIGHT';
-    DL_SPOTLIGHT: Result := 'DL_SPOTLIGHT';
-    DL_OFF: Result := 'DL_OFF';
-    DL_ATTENUATE: Result := 'DL_ATTENUATE';
-    DL_RAYSHAD: Result := 'DL_RAYSHAD';
-    DL_SHADOWED: Result := 'DL_SHADOWED';
-    DL_LOCAL_SHADOW: Result := 'DL_LOCAL_SHADOW';
-    DL_LOCAL_SHADOW2: Result := 'DL_LOCAL_SHADOW2';
-    DL_SEE_CONE: Result := 'DL_SEE_CONE';
-    DL_SPOT_RECTANGULAR: Result := 'DL_SPOT_RECTANGULAR';
-    DL_SPOT_OVERSHOOT: Result := 'DL_SPOT_OVERSHOOT';
-    DL_SPOT_PROJECTOR: Result := 'DL_SPOT_PROJECTOR';
-    DL_EXCLUDE: Result := 'DL_EXCLUDE';
-    DL_RANGE: Result := 'DL_RANGE';
-    DL_SPOT_ROLL: Result := 'DL_SPOT_ROLL';
-    DL_SPOT_ASPECT: Result := 'DL_SPOT_ASPECT';
-    DL_RAY_BIAS: Result := 'DL_RAY_BIAS';
-    DL_INNER_RANGE: Result := 'DL_INNER_RANGE';
-    DL_OUTER_RANGE: Result := 'DL_OUTER_RANGE';
-    DL_MULTIPLIER: Result := 'DL_MULTIPLIER';
-
-    N_AMBIENT_LIGHT: Result := 'N_AMBIENT_LIGHT';
-
-    N_CAMERA: Result := 'N_CAMERA';
-    CAM_SEE_CONE: Result := 'CAM_SEE_CONE';
-    CAM_RANGES: Result := 'CAM_RANGES';
-
-    HIERARCHY: Result := 'HIERARCHY';
-    PARENT_OBJECT: Result := 'PARENT_OBJECT';
-    PIVOT_OBJECT: Result := 'PIVOT_OBJECT';
-    PIVOT_LIMITS: Result := 'PIVOT_LIMITS';
-    PIVOT_ORDER: Result := 'PIVOT_ORDER';
-    XLATE_RANGE: Result := 'XLATE_RANGE';
-
-    POLY_2D: Result := 'POLY_2D';
-
-    // Flags in shaper file that tell whether polys make up an ok shape
-    SHAPE_OK: Result := 'SHAPE_OK';
-    SHAPE_NOT_OK: Result := 'SHAPE_NOT_OK';
-
-    SHAPE_HOOK: Result := 'SHAPE_HOOK';
-
-    PATH_3D: Result := 'PATH_3D';
-    PATH_MATRIX: Result := 'PATH_MATRIX';
-    SHAPE_2D: Result := 'SHAPE_2D';
-    M_SCALE: Result := 'M_SCALE';
-    M_TWIST: Result := 'M_TWIST';
-    M_TEETER: Result := 'M_TEETER';
-    M_FIT: Result := 'M_FIT';
-    M_BEVEL: Result := 'M_BEVEL';
-    XZ_CURVE: Result := 'XZ_CURVE';
-    YZ_CURVE: Result := 'YZ_CURVE';
-    INTERPCT: Result := 'INTERPCT';
-    DEFORM_LIMIT: Result := 'DEFORM_LIMIT';
-
-    // Flags for Modeler options
-    USE_CONTOUR: Result := 'USE_CONTOUR';
-    USE_TWEEN: Result := 'USE_TWEEN';
-    USE_SCALE: Result := 'USE_SCALE';
-    USE_TWIST: Result := 'USE_TWIST';
-    USE_TEETER: Result := 'USE_TEETER';
-    USE_FIT: Result := 'USE_FIT';
-    USE_BEVEL: Result := 'USE_BEVEL';
-
-    // Viewport description chunks
-    VIEWPORT_LAYOUT_OLD: Result := 'VIEWPORT_LAYOUT_OLD';
-    VIEWPORT_DATA_OLD: Result := 'VIEWPORT_DATA_OLD';
-    VIEWPORT_LAYOUT: Result := 'VIEWPORT_LAYOUT';
-    VIEWPORT_DATA: Result := 'VIEWPORT_DATA';
-    VIEWPORT_DATA_3: Result := 'VIEWPORT_DATA_3';
-    VIEWPORT_SIZE: Result := 'VIEWPORT_SIZE';
-    NETWORK_VIEW: Result := 'NETWORK_VIEW';
-
-    // External Application Data
-    XDATA_SECTION: Result := 'XDATA_SECTION';
-    XDATA_ENTRY: Result := 'XDATA_ENTRY';
-    XDATA_APPNAME: Result := 'XDATA_APPNAME';
-    XDATA_STRING: Result := 'XDATA_STRING';
-    XDATA_FLOAT: Result := 'XDATA_FLOAT';
-    XDATA_DOUBLE: Result := 'XDATA_DOUBLE';
-    XDATA_SHORT: Result := 'XDATA_SHORT';
-    XDATA_LONG: Result := 'XDATA_LONG';
-    XDATA_VOID: Result := 'XDATA_procedure';
-    XDATA_GROUP: Result := 'XDATA_GROUP';
-    XDATA_RFU6: Result := 'XDATA_RFU6';
-    XDATA_RFU5: Result := 'XDATA_RFU5';
-    XDATA_RFU4: Result := 'XDATA_RFU4';
-    XDATA_RFU3: Result := 'XDATA_RFU3';
-    XDATA_RFU2: Result := 'XDATA_RFU2';
-    XDATA_RFU1: Result := 'XDATA_RFU1';
-
-    // Material Chunk IDs
-    MAT_ENTRY: Result := 'MAT_ENTRY';
-    MAT_NAME: Result := 'MAT_NAME';
-    MAT_AMBIENT: Result := 'MAT_AMBIENT';
-    MAT_DIFFUSE: Result := 'MAT_DIFFUSE';
-    MAT_SPECULAR: Result := 'MAT_SPECULAR';
-    MAT_SHININESS: Result := 'MAT_SHININESS';
-    MAT_SHIN2PCT: Result := 'MAT_SHIN2PCT';
-    MAT_SHIN3PCT: Result := 'MAT_SHIN3PCT';
-    MAT_TRANSPARENCY: Result := 'MAT_TRANSPARENCY';
-    MAT_XPFALL: Result := 'MAT_XPFALL';
-    MAT_REFBLUR: Result := 'MAT_REFBLUR';
-
-    MAT_SELF_ILLUM: Result := 'MAT_SELF_ILLUM';
-    MAT_TWO_SIDE: Result := 'MAT_TWO_SIDE';
-    MAT_DECAL: Result := 'MAT_DECAL';
-    MAT_ADDITIVE: Result := 'MAT_ADDITIVE';
-    MAT_SELF_ILPCT: Result := 'MAT_SELF_ILPCT';
-    MAT_WIRE: Result := 'MAT_WIRE';
-    MAT_SUPERSMP: Result := 'MAT_SUPERSMP';
-    MAT_WIRESIZE: Result := 'MAT_WIRESIZE';
-    MAT_FACEMAP: Result := 'MAT_FACEMAP';
-    MAT_XPFALLIN: Result := 'MAT_XPFALLIN';
-    MAT_PHONGSOFT: Result := 'MAT_PHONGSOFT';
-    MAT_WIREABS: Result := 'MAT_WIREABS';
-
-    MAT_SHADING: Result := 'MAT_SHADING';
-
-    MAT_TEXMAP: Result := 'MAT_TEXMAP';
-    MAT_OPACMAP: Result := 'MAT_OPACMAP';
-    MAT_REFLMAP: Result := 'MAT_REFLMAP';
-    MAT_BUMPMAP: Result := 'MAT_BUMPMAP';
-    MAT_SPECMAP: Result := 'MAT_SPECMAP';
-    MAT_USE_XPFALL: Result := 'MAT_USE_XPFALL';
-    MAT_USE_REFBLUR: Result := 'MAT_USE_REFBLUR';
-    MAT_BUMP_PERCENT: Result := 'MAT_BUMP_PERCENT';
-
-    MAT_MAPNAME: Result := 'MAT_MAPNAME';
-    MAT_ACUBIC: Result := 'MAT_ACUBIC';
-
-    MAT_SXP_TEXT_DATA: Result := 'MAT_SXP_TEXT_DATA';
-    MAT_SXP_TEXT2_DATA: Result := 'MAT_SXP_TEXT2_DATA';
-    MAT_SXP_OPAC_DATA: Result := 'MAT_SXP_OPAC_DATA';
-    MAT_SXP_BUMP_DATA: Result := 'MAT_SXP_BUMP_DATA';
-    MAT_SXP_SPEC_DATA: Result := 'MAT_SXP_SPEC_DATA';
-    MAT_SXP_SHIN_DATA: Result := 'MAT_SXP_SHIN_DATA';
-    MAT_SXP_SELFI_DATA: Result := 'MAT_SXP_SELFI_DATA';
-    MAT_SXP_TEXT_MASKDATA: Result := 'MAT_SXP_TEXT_MASKDATA';
-    MAT_SXP_TEXT2_MASKDATA: Result := 'MAT_SXP_TEXT2_MASKDATA';
-    MAT_SXP_OPAC_MASKDATA: Result := 'MAT_SXP_OPAC_MASKDATA';
-    MAT_SXP_BUMP_MASKDATA: Result := 'MAT_SXP_BUMP_MASKDATA';
-    MAT_SXP_SPEC_MASKDATA: Result := 'MAT_SXP_SPEC_MASKDATA';
-    MAT_SXP_SHIN_MASKDATA: Result := 'MAT_SXP_SHIN_MASKDATA';
-    MAT_SXP_SELFI_MASKDATA: Result := 'MAT_SXP_SELFI_MASKDATA';
-    MAT_SXP_REFL_MASKDATA: Result := 'MAT_SXP_REFL_MASKDATA';
-    MAT_TEX2MAP: Result := 'MAT_TEX2MAP';
-    MAT_SHINMAP: Result := 'MAT_SHINMAP';
-    MAT_SELFIMAP: Result := 'MAT_SELFIMAP';
-    MAT_TEXMASK: Result := 'MAT_TEXMASK';
-    MAT_TEX2MASK: Result := 'MAT_TEX2MASK';
-    MAT_OPACMASK: Result := 'MAT_OPACMASK';
-    MAT_BUMPMASK: Result := 'MAT_BUMPMASK';
-    MAT_SHINMASK: Result := 'MAT_SHINMASK';
-    MAT_SPECMASK: Result := 'MAT_SPECMASK';
-    MAT_SELFIMASK: Result := 'MAT_SELFIMASK';
-    MAT_REFLMASK: Result := 'MAT_REFLMASK';
-    MAT_MAP_TILINGOLD: Result := 'MAT_MAP_TILINGOLD';
-    MAT_MAP_TILING: Result := 'MAT_MAP_TILING';
-    MAT_MAP_TEXBLUR_OLD: Result := 'MAT_MAP_TEXBLUR_OLD';
-    MAT_MAP_TEXBLUR: Result := 'MAT_MAP_TEXBLUR';
-    MAT_MAP_USCALE: Result := 'MAT_MAP_USCALE';
-    MAT_MAP_VSCALE: Result := 'MAT_MAP_VSCALE';
-    MAT_MAP_UOFFSET: Result := 'MAT_MAP_UOFFSET';
-    MAT_MAP_VOFFSET: Result := 'MAT_MAP_VOFFSET';
-    MAT_MAP_ANG: Result := 'MAT_MAP_ANG';
-    MAT_MAP_COL1: Result := 'MAT_MAP_COL1';
-    MAT_MAP_COL2: Result := 'MAT_MAP_COL2';
-    MAT_MAP_RCOL: Result := 'MAT_MAP_RCOL';
-    MAT_MAP_GCOL: Result := 'MAT_MAP_GCOL';
-    MAT_MAP_BCOL: Result := 'MAT_MAP_BCOL';
-
-    // Keyframe Chunk IDs
-    KFDATA: Result := 'KFDATA';
-    KFHDR: Result := 'KFHDR';
-    AMBIENT_NODE_TAG: Result := 'AMBIENT_NODE_TAG';
-    OBJECT_NODE_TAG: Result := 'OBJECT_NODE_TAG';
-    CAMERA_NODE_TAG: Result := 'CAMERA_NODE_TAG';
-    TARGET_NODE_TAG: Result := 'TARGET_NODE_TAG';
-    LIGHT_NODE_TAG: Result := 'LIGHT_NODE_TAG';
-    L_TARGET_NODE_TAG: Result := 'L_TARGET_NODE_TAG';
-    SPOTLIGHT_NODE_TAG: Result := 'SPOTLIGHT_NODE_TAG';
-
-    KFSEG: Result := 'KFSEG';
-    KFCURTIME: Result := 'KFCURTIME';
-    NODE_HDR: Result := 'NODE_HDR';
-    PARENT_NAME: Result := 'PARENT_NAME';
-    INSTANCE_NAME: Result := 'INSTANCE_NAME';
-    PRESCALE: Result := 'PRESCALE';
-    PIVOT: Result := 'PIVOT';
-    BOUNDBOX: Result := 'BOUNDBOX';
-    MORPH_SMOOTH: Result := 'MORPH_SMOOTH';
-    POS_TRACK_TAG: Result := 'POS_TRACK_TAG';
-    ROT_TRACK_TAG: Result := 'ROT_TRACK_TAG';
-    SCL_TRACK_TAG: Result := 'SCL_TRACK_TAG';
-    FOV_TRACK_TAG: Result := 'FOV_TRACK_TAG';
-    ROLL_TRACK_TAG: Result := 'ROLL_TRACK_TAG';
-    COL_TRACK_TAG: Result := 'COL_TRACK_TAG';
-    MORPH_TRACK_TAG: Result := 'MORPH_TRACK_TAG';
-    HOT_TRACK_TAG: Result := 'HOT_TRACK_TAG';
-    FALL_TRACK_TAG: Result := 'FALL_TRACK_TAG';
-    HIDE_TRACK_TAG: Result := 'HIDE_TRACK_TAG';
-    NODE_ID: Result := 'NODE_ID';
-
-    CMAGIC: Result := 'CMAGIC';
-
-    C_MDRAWER: Result := 'C_MDRAWER';
-    C_TDRAWER: Result := 'C_TDRAWER';
-    C_SHPDRAWER: Result := 'C_SHPDRAWER';
-    C_MODDRAWER: Result := 'C_MODDRAWER';
-    C_RIPDRAWER: Result := 'C_RIPDRAWER';
-    C_TXDRAWER: Result := 'C_TXDRAWER';
-    C_PDRAWER: Result := 'C_PDRAWER';
-    C_MTLDRAWER: Result := 'C_MTLDRAWER';
-    C_FLIDRAWER: Result := 'C_FLIDRAWER';
-    C_CUBDRAWER: Result := 'C_CUBDRAWER';
-    C_MFILE: Result := 'C_MFILE';
-    C_SHPFILE: Result := 'C_SHPFILE';
-    C_MODFILE: Result := 'C_MODFILE';
-    C_RIPFILE: Result := 'C_RIPFILE';
-    C_TXFILE: Result := 'C_TXFILE';
-    C_PFILE: Result := 'C_PFILE';
-    C_MTLFILE: Result := 'C_MTLFILE';
-    C_FLIFILE: Result := 'C_FLIFILE';
-    C_PALFILE: Result := 'C_PALFILE';
-    C_TX_STRING: Result := 'C_TX_STRING';
-    C_CONSTS: Result := 'C_CONSTS';
-    C_SNAPS: Result := 'C_SNAPS';
-    C_GRIDS: Result := 'C_GRIDS';
-    C_ASNAPS: Result := 'C_ASNAPS';
-    C_GRID_RANGE: Result := 'C_GRID_RANGE';
-    C_RENDTYPE: Result := 'C_RENDTYPE';
-    C_PROGMODE: Result := 'C_PROGMODE';
-    C_PREVMODE: Result := 'C_PREVMODE';
-    C_MODWMODE: Result := 'C_MODWMODE';
-    C_MODMODEL: Result := 'C_MODMODEL';
-    C_ALL_LINES: Result := 'C_ALL_LINES';
-    C_BACK_TYPE: Result := 'C_BACK_TYPE';
-    C_MD_CS: Result := 'C_MD_CS';
-    C_MD_CE: Result := 'C_MD_CE';
-    C_MD_SML: Result := 'C_MD_SML';
-    C_MD_SMW: Result := 'C_MD_SMW';
-    C_LOFT_WITH_TEXTURE: Result := 'C_LOFT_WITH_TEXTURE';
-    C_LOFT_L_REPEAT: Result := 'C_LOFT_L_REPEAT';
-    C_LOFT_W_REPEAT: Result := 'C_LOFT_W_REPEAT';
-    C_LOFT_UV_NORMALIZE: Result := 'C_LOFT_UV_NORMALIZE';
-    C_WELD_LOFT: Result := 'C_WELD_LOFT';
-    C_MD_PDET: Result := 'C_MD_PDET';
-    C_MD_SDET: Result := 'C_MD_SDET';
-    C_RGB_RMODE: Result := 'C_RGB_RMODE';
-    C_RGB_HIDE: Result := 'C_RGB_HIDE';
-    C_RGB_MAPSW: Result := 'C_RGB_MAPSW';
-    C_RGB_TWOSIDE: Result := 'C_RGB_TWOSIDE';
-    C_RGB_SHADOW: Result := 'C_RGB_SHADOW';
-    C_RGB_AA: Result := 'C_RGB_AA';
-    C_RGB_OVW: Result := 'C_RGB_OVW';
-    C_RGB_OVH: Result := 'C_RGB_OVH';
-    C_RGB_PICTYPE: Result := 'C_RGB_PICTYPE';
-    C_RGB_OUTPUT: Result := 'C_RGB_OUTPUT';
-    C_RGB_TODISK: Result := 'C_RGB_TODISK';
-    C_RGB_COMPRESS: Result := 'C_RGB_COMPRESS';
-    C_JPEG_COMPRESSION: Result := 'C_JPEG_COMPRESSION';
-    C_RGB_DISPDEV: Result := 'C_RGB_DISPDEV';
-    C_RGB_HARDDEV: Result := 'C_RGB_HARDDEV';
-    C_RGB_PATH: Result := 'C_RGB_PATH';
-    C_BITMAP_DRAWER: Result := 'C_BITMAP_DRAWER';
-    C_RGB_FILE: Result := 'C_RGB_FILE';
-    C_RGB_OVASPECT: Result := 'C_RGB_OVASPECT';
-
-    C_RGB_ANIMTYPE: Result := 'C_RGB_ANIMTYPE';
-    C_RENDER_ALL: Result := 'C_RENDER_ALL';
-    C_REND_FROM: Result := 'C_REND_FROM';
-    C_REND_TO: Result := 'C_REND_TO';
-    C_REND_NTH: Result := 'C_REND_NTH';
-    C_REND_TSTEP: Result := 'C_REND_TSTEP';
-    C_VP_TSTEP: Result := 'C_VP_TSTEP';
-
-    C_PAL_TYPE: Result := 'C_PAL_TYPE';
-    C_RND_TURBO: Result := 'C_RND_TURBO';
-    C_RND_MIP: Result := 'C_RND_MIP';
-    C_BGND_METHOD: Result := 'C_BGND_METHOD';
-    C_AUTO_REFLECT: Result := 'C_AUTO_REFLECT';
-    C_VP_FROM: Result := 'C_VP_FROM';
-    C_VP_TO: Result := 'C_VP_TO';
-    C_VP_NTH: Result := 'C_VP_NTH';
-
-    C_SRDIAM: Result := 'C_SRDIAM';
-    C_SRDEG: Result := 'C_SRDEG';
-    C_SRSEG: Result := 'C_SRSEG';
-    C_SRDIR: Result := 'C_SRDIR';
-    C_HETOP: Result := 'C_HETOP';
-    C_HEBOT: Result := 'C_HEBOT';
-    C_HEHT: Result := 'C_HEHT';
-    C_HETURNS: Result := 'C_HETURNS';
-    C_HEDEG: Result := 'C_HEDEG';
-    C_HESEG: Result := 'C_HESEG';
-    C_HEDIR: Result := 'C_HEDIR';
-    C_QUIKSTUFF: Result := 'C_QUIKSTUFF';
-    C_SEE_LIGHTS: Result := 'C_SEE_LIGHTS';
-    C_SEE_CAMERAS: Result := 'C_SEE_CAMERAS';
-    C_SEE_3D: Result := 'C_SEE_3D';
-    C_MESHSEL: Result := 'C_MESHSEL';
-    C_MESHUNSEL: Result := 'C_MESHUNSEL';
-    C_POLYSEL: Result := 'C_POLYSEL';
-    C_POLYUNSEL: Result := 'C_POLYUNSEL';
-    C_SHPLOCAL: Result := 'C_SHPLOCAL';
-    C_MSHLOCAL: Result := 'C_MSHLOCAL';
-    C_NUM_FORMAT: Result := 'C_NUM_FORMAT';
-    C_ARCH_DENOM: Result := 'C_ARCH_DENOM';
-    C_IN_DEVICE: Result := 'C_IN_DEVICE';
-    C_MSCALE: Result := 'C_MSCALE';
-    C_COMM_PORT: Result := 'C_COMM_PORT';
-    C_TAB_BASES: Result := 'C_TAB_BASES';
-    C_TAB_DIVS: Result := 'C_TAB_DIVS';
-    C_MASTER_SCALES: Result := 'C_MASTER_SCALES';
-    C_SHOW_1STVERT: Result := 'C_SHOW_1STVERT';
-    C_SHAPER_OK: Result := 'C_SHAPER_OK';
-    C_LOFTER_OK: Result := 'C_LOFTER_OK';
-    C_EDITOR_OK: Result := 'C_EDITOR_OK';
-    C_KEYFRAMER_OK: Result := 'C_KEYFRAMER_OK';
-    C_PICKSIZE: Result := 'C_PICKSIZE';
-    C_MAPTYPE: Result := 'C_MAPTYPE';
-    C_MAP_DISPLAY: Result := 'C_MAP_DISPLAY';
-    C_TILE_XY: Result := 'C_TILE_XY';
-    C_MAP_XYZ: Result := 'C_MAP_XYZ';
-    C_MAP_SCALE: Result := 'C_MAP_SCALE';
-    C_MAP_MATRIX_OLD: Result := 'C_MAP_MATRIX_OLD';
-    C_MAP_MATRIX: Result := 'C_MAP_MATRIX';
-    C_MAP_WID_HT: Result := 'C_MAP_WID_HT';
-    C_OBNAME: Result := 'C_OBNAME';
-    C_CAMNAME: Result := 'C_CAMNAME';
-    C_LTNAME: Result := 'C_LTNAME';
-    C_CUR_MNAME: Result := 'C_CUR_MNAME';
-    C_CURMTL_FROM_MESH: Result := 'C_CURMTL_FROM_MESH';
-    C_GET_SHAPE_MAKE_FACES: Result := 'C_GET_SHAPE_MAKE_FACES';
-    C_DETAIL: Result := 'C_DETAIL';
-    C_VERTMARK: Result := 'C_VERTMARK';
-    C_MSHAX: Result := 'C_MSHAX';
-    C_MSHCP: Result := 'C_MSHCP';
-    C_USERAX: Result := 'C_USERAX';
-    C_SHOOK: Result := 'C_SHOOK';
-    C_RAX: Result := 'C_RAX';
-    C_STAPE: Result := 'C_STAPE';
-    C_LTAPE: Result := 'C_LTAPE';
-    C_ETAPE: Result := 'C_ETAPE';
-    C_KTAPE: Result := 'C_KTAPE';
-    C_SPHSEGS: Result := 'C_SPHSEGS';
-    C_GEOSMOOTH: Result := 'C_GEOSMOOTH';
-    C_HEMISEGS: Result := 'C_HEMISEGS';
-    C_PRISMSEGS: Result := 'C_PRISMSEGS';
-    C_PRISMSIDES: Result := 'C_PRISMSIDES';
-    C_TUBESEGS: Result := 'C_TUBESEGS';
-    C_TUBESIDES: Result := 'C_TUBESIDES';
-    C_TORSEGS: Result := 'C_TORSEGS';
-    C_TORSIDES: Result := 'C_TORSIDES';
-    C_CONESIDES: Result := 'C_CONESIDES';
-    C_CONESEGS: Result := 'C_CONESEGS';
-    C_NGPARMS: Result := 'C_NGPARMS';
-    C_PTHLEVEL: Result := 'C_PTHLEVEL';
-    C_MSCSYM: Result := 'C_MSCSYM';
-    C_MFTSYM: Result := 'C_MFTSYM';
-    C_MTTSYM: Result := 'C_MTTSYM';
-    C_SMOOTHING: Result := 'C_SMOOTHING';
-    C_MODICOUNT: Result := 'C_MODICOUNT';
-    C_FONTSEL: Result := 'C_FONTSEL';
-    C_TESS_TYPE: Result := 'C_TESS_TYPE';
-    C_TESS_TENSION: Result := 'C_TESS_TENSION';
-
-    C_SEG_START: Result := 'C_SEG_START';
-    C_SEG_END: Result := 'C_SEG_END';
-    C_CURTIME: Result := 'C_CURTIME';
-    C_ANIMLENGTH: Result := 'C_ANIMLENGTH';
-    C_PV_FROM: Result := 'C_PV_FROM';
-    C_PV_TO: Result := 'C_PV_TO';
-    C_PV_DOFNUM: Result := 'C_PV_DOFNUM';
-    C_PV_RNG: Result := 'C_PV_RNG';
-    C_PV_NTH: Result := 'C_PV_NTH';
-    C_PV_TYPE: Result := 'C_PV_TYPE';
-    C_PV_METHOD: Result := 'C_PV_METHOD';
-    C_PV_FPS: Result := 'C_PV_FPS';
-    C_VTR_FRAMES: Result := 'C_VTR_FRAMES';
-    C_VTR_HDTL: Result := 'C_VTR_HDTL';
-    C_VTR_HD: Result := 'C_VTR_HD';
-    C_VTR_TL: Result := 'C_VTR_TL';
-    C_VTR_IN: Result := 'C_VTR_IN';
-    C_VTR_PK: Result := 'C_VTR_PK';
-    C_VTR_SH: Result := 'C_VTR_SH';
-
-    // Material chunks
-    C_WORK_MTLS: Result := 'C_WORK_MTLS';
-    C_WORK_MTLS_2: Result := 'C_WORK_MTLS_2';
-    C_WORK_MTLS_3: Result := 'C_WORK_MTLS_3';
-    C_WORK_MTLS_4: Result := 'C_WORK_MTLS_4';
-    C_WORK_MTLS_5: Result := 'C_WORK_MTLS_5';
-    C_WORK_MTLS_6: Result := 'C_WORK_MTLS_6';
-    C_WORK_MTLS_7: Result := 'C_WORK_MTLS_7';
-    C_WORK_MTLS_8: Result := 'C_WORK_MTLS_8';
-    C_WORKMTL: Result := 'C_WORKMTL';
-    C_SXP_TEXT_DATA: Result := 'C_SXP_TEXT_DATA';
-    C_SXP_TEXT2_DATA: Result := 'C_SXP_TEXT2_DATA';
-    C_SXP_OPAC_DATA: Result := 'C_SXP_OPAC_DATA';
-    C_SXP_BUMP_DATA: Result := 'C_SXP_BUMP_DATA';
-    C_SXP_SPEC_DATA: Result := 'C_SXP_SPEC_DATA';
-    C_SXP_SHIN_DATA: Result := 'C_SXP_SHIN_DATA';
-    C_SXP_SELFI_DATA: Result := 'C_SXP_SELFI_DATA';
-    C_SXP_TEXT_MASKDATA: Result := 'C_SXP_TEXT_MASKDATA';
-    C_SXP_TEXT2_MASKDATA: Result := 'C_SXP_TEXT2_MASKDATA';
-    C_SXP_OPAC_MASKDATA: Result := 'C_SXP_OPAC_MASKDATA';
-    C_SXP_BUMP_MASKDATA: Result := 'C_SXP_BUMP_MASKDATA';
-    C_SXP_SPEC_MASKDATA: Result := 'C_SXP_SPEC_MASKDATA';
-    C_SXP_SHIN_MASKDATA: Result := 'C_SXP_SHIN_MASKDATA';
-    C_SXP_SELFI_MASKDATA: Result := 'C_SXP_SELFI_MASKDATA';
-    C_SXP_REFL_MASKDATA: Result := 'C_SXP_REFL_MASKDATA';
-
-    C_BGTYPE: Result := 'C_BGTYPE';
-    C_MEDTILE: Result := 'C_MEDTILE';
-
-    // Contrast
-    C_LO_CONTRAST: Result := 'C_LO_CONTRAST';
-    C_HI_CONTRAST: Result := 'C_HI_CONTRAST';
-
-    // 3D frozen display
-    C_FROZ_DISPLAY: Result := 'C_FROZ_DISPLAY';
-
-    // Booleans
-    C_BOOLWELD: Result := 'C_BOOLWELD';
-    C_BOOLTYPE: Result := 'C_BOOLTYPE';
-
-    C_ANG_THRESH: Result := 'C_ANG_THRESH';
-    C_SS_THRESH: Result := 'C_SS_THRESH';
-    C_TEXTURE_BLUR_DEFAULT: Result := 'C_TEXTURE_BLUR_DEFAULT';
-
-    C_MAPDRAWER: Result := 'C_MAPDRAWER';
-    C_MAPDRAWER1: Result := 'C_MAPDRAWER1';
-    C_MAPDRAWER2: Result := 'C_MAPDRAWER2';
-    C_MAPDRAWER3: Result := 'C_MAPDRAWER3';
-    C_MAPDRAWER4: Result := 'C_MAPDRAWER4';
-    C_MAPDRAWER5: Result := 'C_MAPDRAWER5';
-    C_MAPDRAWER6: Result := 'C_MAPDRAWER6';
-    C_MAPDRAWER7: Result := 'C_MAPDRAWER7';
-    C_MAPDRAWER8: Result := 'C_MAPDRAWER8';
-    C_MAPDRAWER9: Result := 'C_MAPDRAWER9';
-    C_MAPDRAWER_ENTRY: Result := 'C_MAPDRAWER_ENTRY';
-
-    // system options
-    C_BACKUP_FILE: Result := 'C_BACKUP_FILE';
-    C_DITHER_256: Result := 'C_DITHER_256';
-    C_SAVE_LAST: Result := 'C_SAVE_LAST';
-    C_USE_ALPHA: Result := 'C_USE_ALPHA';
-    C_TGA_DEPTH: Result := 'C_TGA_DEPTH';
-    C_REND_FIELDS: Result := 'C_REND_FIELDS';
-    C_REFLIP: Result := 'C_REFLIP';
-    C_SEL_ITEMTOG: Result := 'C_SEL_ITEMTOG';
-    C_SEL_RESET: Result := 'C_SEL_RESET';
-    C_STICKY_KEYINF: Result := 'C_STICKY_KEYINF';
-    C_WELD_THRESHOLD: Result := 'C_WELD_THRESHOLD';
-    C_ZCLIP_POINT: Result := 'C_ZCLIP_POINT';
-    C_ALPHA_SPLIT: Result := 'C_ALPHA_SPLIT';
-    C_KF_SHOW_BACKFACE: Result := 'C_KF_SHOW_BACKFACE';
-    C_OPTIMIZE_LOFT: Result := 'C_OPTIMIZE_LOFT';
-    C_TENS_DEFAULT: Result := 'C_TENS_DEFAULT';
-    C_CONT_DEFAULT: Result := 'C_CONT_DEFAULT';
-    C_BIAS_DEFAULT: Result := 'C_BIAS_DEFAULT';
-
-    C_DXFNAME_SRC: Result := 'C_DXFNAME_SRC ';
-    C_AUTO_WELD: Result := 'C_AUTO_WELD ';
-    C_AUTO_UNIFY: Result := 'C_AUTO_UNIFY ';
-    C_AUTO_SMOOTH: Result := 'C_AUTO_SMOOTH ';
-    C_DXF_SMOOTH_ANG: Result := 'C_DXF_SMOOTH_ANG ';
-    C_SMOOTH_ANG: Result := 'C_SMOOTH_ANG ';
-
-    // Special network-use chunks
-    C_NET_USE_VPOST: Result := 'C_NET_USE_VPOST';
-    C_NET_USE_GAMMA: Result := 'C_NET_USE_GAMMA';
-    C_NET_FIELD_ORDER: Result := 'C_NET_FIELD_ORDER';
-
-    C_BLUR_FRAMES: Result := 'C_BLUR_FRAMES';
-    C_BLUR_SAMPLES: Result := 'C_BLUR_SAMPLES';
-    C_BLUR_DUR: Result := 'C_BLUR_DUR';
-    C_HOT_METHOD: Result := 'C_HOT_METHOD';
-    C_HOT_CHECK: Result := 'C_HOT_CHECK';
-    C_PIXEL_SIZE: Result := 'C_PIXEL_SIZE';
-    C_DISP_GAMMA: Result := 'C_DISP_GAMMA';
-    C_FBUF_GAMMA: Result := 'C_FBUF_GAMMA';
-    C_FILE_OUT_GAMMA: Result := 'C_FILE_OUT_GAMMA';
-    C_FILE_IN_GAMMA: Result := 'C_FILE_IN_GAMMA';
-    C_GAMMA_CORRECT: Result := 'C_GAMMA_CORRECT';
-    C_APPLY_DISP_GAMMA: Result := 'C_APPLY_DISP_GAMMA';
-    C_APPLY_FBUF_GAMMA: Result := 'C_APPLY_FBUF_GAMMA';
-    C_APPLY_FILE_GAMMA: Result := 'C_APPLY_FILE_GAMMA';
-    C_FORCE_WIRE: Result := 'C_FORCE_WIRE';
-    C_RAY_SHADOWS: Result := 'C_RAY_SHADOWS';
-    C_MASTER_AMBIENT: Result := 'C_MASTER_AMBIENT';
-    C_SUPER_SAMPLE: Result := 'C_SUPER_SAMPLE';
-    C_OBJECT_MBLUR: Result := 'C_OBJECT_MBLUR';
-    C_MBLUR_DITHER: Result := 'C_MBLUR_DITHER';
-    C_DITHER_24: Result := 'C_DITHER_24';
-    C_SUPER_BLACK: Result := 'C_SUPER_BLACK';
-    C_SAFE_FRAME: Result := 'C_SAFE_FRAME';
-    C_VIEW_PRES_RATIO: Result := 'C_VIEW_PRES_RATIO';
-    C_BGND_PRES_RATIO: Result := 'C_BGND_PRES_RATIO';
-    C_NTH_SERIAL_NUM: Result := 'C_NTH_SERIAL_NUM';
-
-    VPDATA: Result := 'VPDATA';
-
-    P_QUEUE_ENTRY: Result := 'P_QUEUE_ENTRY';
-    P_QUEUE_IMAGE: Result := 'P_QUEUE_IMAGE';
-    P_QUEUE_USEIGAMMA: Result := 'P_QUEUE_USEIGAMMA';
-    P_QUEUE_PROC: Result := 'P_QUEUE_PROC';
-    P_QUEUE_SOLID: Result := 'P_QUEUE_SOLID';
-    P_QUEUE_GRADIENT: Result := 'P_QUEUE_GRADIENT';
-    P_QUEUE_KF: Result := 'P_QUEUE_KF';
-    P_QUEUE_MOTBLUR: Result := 'P_QUEUE_MOTBLUR';
-    P_QUEUE_MB_REPEAT: Result := 'P_QUEUE_MB_REPEAT';
-    P_QUEUE_NONE: Result := 'P_QUEUE_NONE';
-
-    P_QUEUE_RESIZE: Result := 'P_QUEUE_RESIZE';
-    P_QUEUE_OFFSET: Result := 'P_QUEUE_OFFSET';
-    P_QUEUE_ALIGN: Result := 'P_QUEUE_ALIGN';
-
-    P_CUSTOM_SIZE: Result := 'P_CUSTOM_SIZE';
-
-    P_ALPH_NONE: Result := 'P_ALPH_NONE';
-    P_ALPH_PSEUDO: Result := 'P_ALPH_PSEUDO';
-    P_ALPH_OP_PSEUDO: Result := 'P_ALPH_OP_PSEUDO';
-    P_ALPH_BLUR: Result := 'P_ALPH_BLUR';
-    P_ALPH_PCOL: Result := 'P_ALPH_PCOL';
-    P_ALPH_C0: Result := 'P_ALPH_C0';
-    P_ALPH_OP_KEY: Result := 'P_ALPH_OP_KEY';
-    P_ALPH_KCOL: Result := 'P_ALPH_KCOL';
-    P_ALPH_OP_NOCONV: Result := 'P_ALPH_OP_NOCONV';
-    P_ALPH_IMAGE: Result := 'P_ALPH_IMAGE';
-    P_ALPH_ALPHA: Result := 'P_ALPH_ALPHA';
-    P_ALPH_QUES: Result := 'P_ALPH_QUES';
-    P_ALPH_QUEIMG: Result := 'P_ALPH_QUEIMG';
-    P_ALPH_CUTOFF: Result := 'P_ALPH_CUTOFF';
-    P_ALPHANEG: Result := 'P_ALPHANEG';
-
-    P_TRAN_NONE: Result := 'P_TRAN_NONE';
-    P_TRAN_IMAGE: Result := 'P_TRAN_IMAGE';
-    P_TRAN_FRAMES: Result := 'P_TRAN_FRAMES';
-    P_TRAN_FADEIN: Result := 'P_TRAN_FADEIN';
-    P_TRAN_FADEOUT: Result := 'P_TRAN_FADEOUT';
-    P_TRANNEG: Result := 'P_TRANNEG';
-
-    P_RANGES: Result := 'P_RANGES';
-
-    P_PROC_DATA: Result := 'P_PROC_DATA'
-    else
-      Result := 'UNKNOWN_CHUNK';
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-const
-  IndentString: string = #9#9#9#9#9#9#9#9#9#9#9#9;
-
-function Indent(Level: integer): string;
-begin
-  Result := Copy(IndentString, 1, Level);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ChunkHeaderReport(var Strings: TStrings; Chunk: PChunk3DS;
-  IndentLevel: integer);
-
-var
-  OutString: string;
-
-begin
-  OutString := Format('%sChunk %s ($%x), Length is %d ($%3:x)',
-    [Indent(IndentLevel), ChunkTagToString(Chunk^.Tag), Chunk^.Tag, Chunk^.Size]);
-  Strings.Add(OutString);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure DumpKeyHeader(Strings: TStrings; Key: TKeyHeader3DS; IndentLevel: integer);
-
-var
-  Output: string;
-
-begin
-  Output := Format('%sFrame %d', [Indent(IndentLevel), Key.Time]);
-  if (Key.rflags and KeyUsesTension3DS) <> 0 then
-    Output := Output + Format(', Tens %.2f', [Key.Tension]);
-  if (Key.rflags and KeyUsesCont3DS) <> 0 then
-    Output := Output + Format(', Cont %.2f', [Key.Continuity]);
-  if (Key.rflags and KeyUsesBias3DS) <> 0 then
-    Output := Output + Format(', Bias %.2f', [Key.Bias]);
-  if (Key.rflags and KeyUsesEaseTo3DS) <> 0 then
-    Output := Output + Format(', Ease to %.2f', [Key.EaseTo]);
-  if (Key.rflags and KeyUsesEaseFrom3DS) <> 0 then
-    Output := Output + Format(', Ease from %.2f', [Key.EaseFrom]);
-  Strings.Add(Output);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure DumpChunk(const Source: TFile3DS; var Strings: TStrings;
-  Chunk: PChunk3DS; IndentLevel: integer; DumpLevel: TDumpLevel);
-
-// retrieves the Data for a Chunk from the given Source, formats the Data into
-// one or more lines of text and puts the lines into the given Strings parameter
-
-var
-  Child: PChunk3DS;
-  Output: string;
-  ID: string;
-  I: integer;
-
-begin
-  ChunkHeaderReport(Strings, Chunk, IndentLevel);
-  ID := Indent(IndentLevel) + #9;
-
-  if DumpLevel <> dlTerseDump then
-  begin
-    case Chunk^.Tag of
-      MESH_VERSION:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sVersion %d', [ID, Chunk^.Data.MeshVersion^]);
-        Strings.Add(Output);
-      end;
-      M3D_VERSION:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sVersion %d', [ID, Chunk^.Data.M3DVersion^]);
-        Strings.Add(Output);
-      end;
-      COLOR_F:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sColor R:  %f, ', [ID, Chunk^.Data.ColorF^.Red]);
-        Output := Output + Format(' G:  %f, ', [Chunk^.Data.ColorF^.Green]);
-        Output := Output + Format(' B:  %f', [Chunk^.Data.ColorF^.Blue]);
-        Strings.Add(Output);
-      end;
-      LIN_COLOR_F:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sColor R:  %f, ', [ID, Chunk^.Data.LinColorF^.Red]);
-        Output := Output + Format(' G:  %f, ', [Chunk^.Data.LinColorF^.Green]);
-        Output := Output + Format(' B:  %f', [Chunk^.Data.LinColorF^.Blue]);
-        Strings.Add(Output);
-      end;
-      COLOR_24:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.Color24^.Red]);
-        Output := Output + Format(' G: %d, ', [Chunk^.Data.Color24^.Green]);
-        Output := Output + Format(' B: %d', [Chunk^.Data.Color24^.Blue]);
-        Strings.Add(Output);
-      end;
-      LIN_COLOR_24:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.LinColor24^.Red]);
-        Output := Output + Format(' G: %d, ', [Chunk^.Data.LinColor24^.Green]);
-        Output := Output + Format(' B: %d', [Chunk^.Data.LinColor24^.Blue]);
-        Strings.Add(Output);
-      end;
-      INT_PERCENTAGE:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sPercentage of %d%%', [ID, Chunk^.Data.IntPercentage^]);
-        Strings.Add(Output);
-      end;
-      FLOAT_PERCENTAGE:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sPercentage of  %f%%', [ID, Chunk^.Data.FloatPercentage^]);
-        Strings.Add(Output);
-      end;
-      MASTER_SCALE:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMaster Scale  %f', [ID, Chunk^.Data.MasterScale^]);
-        Strings.Add(Output);
-      end;
-      BIT_MAP:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sBitmap Name %s', [ID, Chunk^.Data.BitMapName^]);
-        Strings.Add(Output);
-      end;
-      V_GRADIENT:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMidpoint  %f', [ID, Chunk^.Data.VGradient^]);
-        Strings.Add(Output);
-      end;
-      LO_SHADOW_BIAS:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sBias of  %f', [ID, Chunk^.Data.LoShadowBias^]);
-        Strings.Add(Output);
-      end;
-      HI_SHADOW_BIAS:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sBias of  %f', [ID, Chunk^.Data.HiShadowBias^]);
-        Strings.Add(Output);
-      end;
-      RAY_BIAS:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sBias of  %f', [ID, Chunk^.Data.RayBias^]);
-        Strings.Add(Output);
-      end;
-      SHADOW_MAP_SIZE:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sSize of %d', [ID, Chunk^.Data.ShadowMapSize^]);
-        Strings.Add(Output);
-      end;
-      SHADOW_SAMPLES:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sSize of %d', [ID, Chunk^.Data.ShadowSamples^]);
-        Strings.Add(Output);
-      end;
-      SHADOW_RANGE:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sRange of %d', [ID, Chunk^.Data.ShadowRange^]);
-        Strings.Add(Output);
-      end;
-      SHADOW_FILTER:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sFilter of  %f', [ID, Chunk^.Data.ShadowFilter^]);
-        Strings.Add(Output);
-      end;
-      O_CONSTS:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sPlane at  %f,  %f,  %f',
-          [ID, Chunk^.Data.OConsts^.X, Chunk^.Data.OConsts^.Y, Chunk^.Data.OConsts^.Z]);
-        Strings.Add(Output);
-      end;
-      FOG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sNear plane at  %f', [ID, Chunk^.Data.Fog^.NearPlaneDist]);
-        Strings.Add(Output);
-        Output := Format('%sNear Density of  %f',
-          [ID, Chunk^.Data.Fog^.NearPlaneDensity]);
-        Strings.Add(Output);
-        Output := Format('%sFar plane at  %f', [ID, Chunk^.Data.Fog^.FarPlaneDist]);
-        Strings.Add(Output);
-        Output := Format('%sFar Density of  %f',
-          [ID, Chunk^.Data.Fog^.FarPlaneDensity]);
-        Strings.Add(Output);
-      end;
-      LAYER_FOG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sFog Z range is  %f to  %f',
-          [ID, Chunk^.Data.LayerFog^.ZMin, Chunk^.Data.LayerFog^.ZMax]);
-        Strings.Add(Output);
-        Output := Format('%sFog Density is  %f', [ID, Chunk^.Data.LayerFog^.Density]);
-        Strings.Add(Output);
-        Output := Format('%sFog type of $%x', [ID, Chunk^.Data.LayerFog^.AType]);
-        Strings.Add(Output);
-      end;
-      DISTANCE_CUE:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sNear plane at  %f',
-          [ID, Chunk^.Data.DistanceCue^.NearPlaneDist]);
-        Strings.Add(Output);
-        Output := Format('%sNear Density of  %f',
-          [ID, Chunk^.Data.DistanceCue^.NearPlaneDimming]);
-        Strings.Add(Output);
-        Output := Format('%sFar plane at  %f',
-          [ID, Chunk^.Data.DistanceCue^.FarPlaneDist]);
-        Strings.Add(Output);
-        Output := Format('%sFar Density of  %f',
-          [ID, Chunk^.Data.DistanceCue^.FarPlaneDimming]);
-        Strings.Add(Output);
-      end;
-      VIEW_TOP,
-      VIEW_BOTTOM,
-      VIEW_LEFT,
-      VIEW_RIGHT,
-      VIEW_FRONT,
-      VIEW_BACK:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sTarget at  %f,  %f,  %f',
-          [ID, Chunk^.Data.ViewStandard^.ViewTargetCoord.X,
-          Chunk^.Data.ViewStandard^.ViewTargetCoord.Y,
-          Chunk^.Data.ViewStandard^.ViewTargetCoord.Z]);
-        Strings.Add(Output);
-        Output := Format('%sView Width of  %f',
-          [ID, Chunk^.Data.ViewStandard^.ViewWidth]);
-        Strings.Add(Output);
-      end;
-      VIEW_USER:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sTarget at  %f,  %f,  %f',
-          [ID, Chunk^.Data.ViewUser^.ViewTargetCoord.X,
-          Chunk^.Data.ViewUser^.ViewTargetCoord.Y,
-          Chunk^.Data.ViewUser^.ViewTargetCoord.Z]);
-        Strings.Add(Output);
-        Output := Format('%sView Width of  %f', [ID, Chunk^.Data.ViewUser^.ViewWidth]);
-        Strings.Add(Output);
-        Output := Format('%sHorizontal View angle of  %f',
-          [ID, Chunk^.Data.ViewUser^.XYViewAngle]);
-        Strings.Add(Output);
-        Output := Format('%sVertical View angle of  %f',
-          [ID, Chunk^.Data.ViewUser^.YZViewAngle]);
-        Strings.Add(Output);
-        Output := Format('%sBank angle of  %f', [ID, Chunk^.Data.ViewUser^.BankAngle]);
-        Strings.Add(Output);
-      end;
-      VIEW_CAMERA:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sCamera Name %s', [ID, Chunk^.Data.ViewCamera^]);
-        Strings.Add(Output);
-      end;
-      NAMED_OBJECT:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sName: %s', [ID, Chunk^.Data.NamedObject^]);
-        Strings.Add(Output);
-      end;
-      POINT_ARRAY:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Vertices', [ID, Chunk^.Data.PointArray^.Vertices]);
-        Strings.Add(Output);
-        if DumpLevel = dlMaximumDump then
-          for I := 0 to Chunk^.Data.PointArray^.Vertices - 1 do
-          begin
-            Output := Format('%sVertex %d at  %f,  %f,  %f',
-              [ID, I, Chunk^.Data.PointArray^.PointList^[I].X,
-              Chunk^.Data.PointArray^.PointList^[I].Y,
-              Chunk^.Data.PointArray^.PointList^[I].Z]);
-            Strings.Add(Output);
-          end;
-      end;
-      POINT_FLAG_ARRAY:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sFlags: %d', [ID, Chunk^.Data.PointFlagArray^.Flags]);
-        Strings.Add(Output);
-        if DumpLevel = dlMaximumDump then
-          for I := 0 to Chunk^.Data.PointFlagArray^.Flags - 1 do
-          begin
-            Output := Format('%sFlag %d is %d',
-              [ID, I, Chunk^.Data.PointFlagArray^.FlagList^[I]]);
-            Strings.Add(Output);
-          end;
-      end;
-      FACE_ARRAY:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Faces', [ID, Chunk^.Data.FaceArray^.Faces]);
-        Strings.Add(Output);
-        if DumpLevel = dlMaximumDump then
-          for I := 0 to Chunk^.Data.FaceArray^.Faces - 1 do
-          begin
-            Output := Format('%sFace %d Vertices %d, %d, %d and flag $%x',
-              [ID, I, Chunk^.Data.FaceArray^.FaceList^[I].V1,
-              Chunk^.Data.FaceArray^.FaceList^[I].V2,
-              Chunk^.Data.FaceArray^.FaceList^[I].V3,
-              Chunk^.Data.FaceArray^.FaceList^[I].Flag]);
-            Strings.Add(Output);
-          end;
-      end;
-      MSH_MAT_GROUP:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMaterial Name of %s',
-          [ID, Chunk^.Data.MshMatGroup^.MatNameStr]);
-        Strings.Add(Output);
-        Output := Format('%sAssigned to %d Faces',
-          [ID, Chunk^.Data.MshMatGroup^.Faces]);
-        Strings.Add(Output);
-      end;
-      MSH_BOXMAP:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sBoxmap consists of the following materials:', [ID]);
-        Strings.Add(Output);
-        for I := 0 to 5 do
-        begin
-          Output := Format('%s%s', [ID, Chunk^.Data.MshBoxmap^[I]]);
-          Strings.Add(Output);
-        end;
-      end;
-      TEX_VERTS:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Vertices', [ID, Chunk^.Data.TexVerts^.NumCoords]);
-        Strings.Add(Output);
-        if DumpLevel = dlMaximumDump then
-        begin
-          for I := 0 to Chunk^.Data.TexVerts^.NumCoords - 1 do
-          begin
-            Output := Format('%sVertex %d with tex vert of  %f,  %f',
-              [ID, I, Chunk^.Data.TexVerts^.TextVertList^[I].U,
-              Chunk^.Data.TexVerts^.TextVertList^[I].V]);
-            Strings.Add(Output);
-          end;
-        end;
-      end;
-      MESH_TEXTURE_INFO:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMap Type of %d',
-          [ID, Chunk^.Data.MeshTextureInfo^.MapType]);
-        Strings.Add(Output);
-        Output := Format('%sX Tiling of  %f',
-          [ID, Chunk^.Data.MeshTextureInfo^.XTiling]);
-        Strings.Add(Output);
-        Output := Format('%sY Tiling of  %f',
-          [ID, Chunk^.Data.MeshTextureInfo^.YTiling]);
-        Strings.Add(Output);
-        Output := Format('%sIcon position of  %f,  %f,  %f',
-          [ID, Chunk^.Data.MeshTextureInfo^.IconPos.X,
-          Chunk^.Data.MeshTextureInfo^.IconPos.Y,
-          Chunk^.Data.MeshTextureInfo^.IconPos.Z]);
-        Strings.Add(Output);
-        I := 0;
-        while I < 12 do
-        begin
-          Output := Format('%s[%d]  %f [%d]  %f [%d]  %f',
-            [ID, I, Chunk^.Data.MeshTextureInfo^.XMatrix[I], I +
-            1, Chunk^.Data.MeshTextureInfo^.XMatrix[I + 1], I +
-            2, Chunk^.Data.MeshTextureInfo^.XMatrix[I + 2]]);
-          Strings.Add(Output);
-          Inc(I, 3);
-        end;
-        Output := Format('%sScaling Value of  %f',
-          [ID, Chunk^.Data.MeshTextureInfo^.IconScaling]);
-        Strings.Add(Output);
-        Output := Format('%sPlanar Icon Width of  %f',
-          [ID, Chunk^.Data.MeshTextureInfo^.IconWidth]);
-        Strings.Add(Output);
-        Output := Format('%sPlanar Icon Height of  %f',
-          [ID, Chunk^.Data.MeshTextureInfo^.IconHeight]);
-        Strings.Add(Output);
-        Output := Format('%sCylinder Icon Height of  %f',
-          [ID, Chunk^.Data.MeshTextureInfo^.CylIconHeight]);
-        Strings.Add(Output);
-      end;
-      MESH_MATRIX:
-      begin
-        Source.ReadChunkData(Chunk);
-        I := 0;
-        while I < 12 do
-        begin
-          Output := Format('%s[%d]  %f [%d]  %f [%d]  %f',
-            [ID, I, Chunk^.Data.MeshMatrix^[I], I + 1,
-            Chunk^.Data.MeshMatrix^[I + 1], I + 2, Chunk^.Data.MeshMatrix^[I + 2]]);
-          Strings.Add(Output);
-          Inc(I, 3);
-        end;
-      end;
-      PROC_NAME:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sProcedure Name of %s', [ID, Chunk^.Data.ProcName^]);
-        Strings.Add(Output);
-      end;
-      MESH_COLOR:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sColor index of %d', [ID, Chunk^.Data.MeshColor^]);
-        Strings.Add(Output);
-      end;
-      N_DIRECT_LIGHT:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sLight at  %f,  %f,  %f',
-          [ID, Chunk^.Data.NDirectLight^.X, Chunk^.Data.NDirectLight^.Y,
-          Chunk^.Data.NDirectLight^.Z]);
-        Strings.Add(Output);
-      end;
-      DL_EXCLUDE:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sExclude %s', [ID, Chunk^.Data.DLExclude^]);
-        Strings.Add(Output);
-      end;
-      DL_OUTER_RANGE,
-      DL_INNER_RANGE:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sRange of  %f', [ID, Chunk^.Data.DlOuterRange^]);
-        Strings.Add(Output);
-      end;
-      DL_MULTIPLIER:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMultiple of  %f', [ID, Chunk^.Data.DlMultiplier^]);
-        Strings.Add(Output);
-      end;
-      DL_SPOT_ROLL:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sRoll angle of  %f', [ID, Chunk^.Data.DlSpotRoll^]);
-        Strings.Add(Output);
-      end;
-      DL_SPOT_ASPECT:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sSpot aspect of  %f', [ID, Chunk^.Data.DlSpotAspect^]);
-        Strings.Add(Output);
-      end;
-      DL_SPOT_PROJECTOR:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sFilename of projector is %s',
-          [ID, Chunk^.Data.DlSpotProjector^]);
-        Strings.Add(Output);
-      end;
-      DL_RAY_BIAS:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sBias of  %f', [ID, Chunk^.Data.DlRayBias^]);
-        Strings.Add(Output);
-      end;
-      DL_SPOTLIGHT:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sTarget at  %f, %f, %f',
-          [ID, Chunk^.Data.DlSpotlight^.SpotlightTarg.X,
-          Chunk^.Data.DlSpotlight^.SpotlightTarg.Y,
-          Chunk^.Data.DlSpotlight^.SpotlightTarg.Z]);
-        Strings.Add(Output);
-        Output := Format('%sHotspot cone of  %f, ',
-          [ID, Chunk^.Data.DlSpotlight^.HotspotAngle]);
-        Output := Output + Format(' Falloff cone of  %f',
-          [Chunk^.Data.DlSpotlight^.FalloffAngle]);
-        Strings.Add(Output);
-      end;
-      DL_LOCAL_SHADOW2:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sShadow bias of  %f',
-          [ID, Chunk^.Data.DlLocalShadow2^.LocalShadowBias]);
-        Strings.Add(Output);
-        Output := Format('%sShadow filter of  %f',
-          [ID, Chunk^.Data.DlLocalShadow2^.LocalShadowFilter]);
-        Strings.Add(Output);
-        Output := Format('%sShadow Map Size of  %f',
-          [ID, Chunk^.Data.DlLocalShadow2^.LocalShadowMapSize]);
-        Strings.Add(Output);
-      end;
-      N_CAMERA:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sCamera at  %f,  %f,  %f',
-          [ID, Chunk^.Data.NCamera^.CameraPos.X, Chunk^.Data.NCamera^.CameraPos.Y,
-          Chunk^.Data.NCamera^.CameraPos.Z]);
-        Strings.Add(Output);
-        Output := Format('%sTarget at  %f,  %f,  %f',
-          [ID, Chunk^.Data.NCamera^.TargetPos.X, Chunk^.Data.NCamera^.TargetPos.Y,
-          Chunk^.Data.NCamera^.TargetPos.Z]);
-        Strings.Add(Output);
-        Output := Format('%sBank angle of  %f', [ID, Chunk^.Data.NCamera^.CameraBank]);
-        Output := Output + Format(' and a foc of  %f',
-          [Chunk^.Data.NCamera^.CameraFocalLength]);
-        Strings.Add(Output);
-      end;
-      CAM_RANGES:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sCamera near range is  %f and far range is  %f',
-          [ID, Chunk^.Data.CamRanges^.NearPlane, Chunk^.Data.CamRanges^.FarPlane]);
-        Strings.Add(Output);
-      end;
-      VIEWPORT_LAYOUT:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sForm of %d', [ID, Chunk^.Data.ViewportLayout^.Form]);
-        Strings.Add(Output);
-        Output := Format('%sTop of %d', [ID, Chunk^.Data.ViewportLayout^.Top]);
-        Strings.Add(Output);
-        Output := Format('%sReady of %d', [ID, Chunk^.Data.ViewportLayout^.Ready]);
-        Strings.Add(Output);
-        Output := Format('%sWState of %d', [ID, Chunk^.Data.ViewportLayout^.WState]);
-        Strings.Add(Output);
-        Output := Format('%sSwap WS of %d', [ID, Chunk^.Data.ViewportLayout^.SwapWS]);
-        Strings.Add(Output);
-        Output := Format('%sSwap Port of %d',
-          [ID, Chunk^.Data.ViewportLayout^.SwapPort]);
-        Strings.Add(Output);
-        Output := Format('%sSwap Cur of %d',
-          [ID, Chunk^.Data.ViewportLayout^.SwapCur]);
-        Strings.Add(Output);
-      end;
-      VIEWPORT_SIZE:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sWork Area X: %d Y: %d W: %d H: %d',
-          [ID, Chunk^.Data.ViewportSize^.XPos, Chunk^.Data.ViewportSize^.YPos,
-          Chunk^.Data.ViewportSize^.Width,
-          Chunk^.Data.ViewportSize^.Height]);
-        Strings.Add(Output);
-      end;
-      VIEWPORT_DATA_3,
-      VIEWPORT_DATA:
-      begin
-        Source.ReadChunkData(Chunk);
-        with Chunk^.Data.ViewportData^ do
-        begin
-          Output := Format('%sFlags: $%x', [ID, Flags]);
-          Strings.Add(Output);
-          Output := Format('%sAxis Lockouts of $%x', [ID, AxisLockout]);
-          Strings.Add(Output);
-          Output := Format('%sWindow Position of %d, %d', [ID, WinXPos, WinYPos]);
-          Strings.Add(Output);
-          Output := Format('%sWindow Size of %d, %d', [ID, WinWidth, WinHeight]);
-          Strings.Add(Output);
-          Output := Format('%sWindow View of %d', [ID, View]);
-          Strings.Add(Output);
-          Output := Format('%sZoom Factor of  %f', [ID, ZoomFactor]);
-          Strings.Add(Output);
-          Output := Format('%sWorld Center of  %f, %f, %f',
-            [ID, Center.X, Center.Y, Center.Z]);
-          Strings.Add(Output);
-          Output := Format('%sHorizontal Angle of  %f', [ID, HorizAng]);
-          Strings.Add(Output);
-          Output := Format('%sVertical Angle of  %f', [ID, VertAng]);
-          Strings.Add(Output);
-          Output := Format('%sCamera Name of %s', [ID, CamNameStr]);
-          Strings.Add(Output);
-        end;
-      end;
-      XDATA_APPNAME:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sApplication Name %s', [ID, Chunk^.Data.XDataAppName^]);
-        Strings.Add(Output);
-      end;
-      XDATA_STRING:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sString value of %s', [ID, Chunk^.Data.XDataString^]);
-        Strings.Add(Output);
-      end;
-      MAT_NAME:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMaterial Name %s', [ID, Chunk^.Data.MatName^]);
-        Strings.Add(Output);
-      end;
-      MAT_SHADING:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sShading value of %d', [ID, Chunk^.Data.MatShading^]);
-        Strings.Add(Output);
-      end;
-      MAT_ACUBIC:
-      begin
-        Source.ReadChunkData(Chunk);
-        with Chunk^.Data.MatAcubic^ do
-        begin
-          Output := Format('%sShade level of %d', [ID, ShadeLevel]);
-          Strings.Add(Output);
-          Output := Format('%sAntialias level of %d', [ID, AntiAlias]);
-          Strings.Add(Output);
-          Output := Format('%sFlags: %d', [ID, Flags]);
-          Strings.Add(Output);
-          Output := Format('%sMap Size of %d', [ID, MapSize]);
-          Strings.Add(Output);
-          Output := Format('%sFrame skip of %d', [ID, FrameInterval]);
-          Strings.Add(Output);
-        end;
-      end;
-      MAT_MAPNAME:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMap Name %s', [ID, Chunk^.Data.MatMapname^]);
-        Strings.Add(Output);
-      end;
-      MAT_WIRESIZE:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sWire frame Size of  %f', [ID, Chunk^.Data.MatWireSize^]);
-        Strings.Add(Output);
-      end;
-      MAT_MAP_TILING:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMap Flags: ', [ID]);
-        if (Chunk^.Data.MatMapTiling^ = 0) then
-          Output := Output + ' NONE'
-        else
-        begin
-          if (Chunk^.Data.MatMapTiling^ and TEX_DECAL) <> 0 then
-            Output := Output + ' TEX_DECAL, ';
-          if (Chunk^.Data.MatMapTiling^ and TEX_MIRROR) <> 0 then
-            Output := Output + ' TEX_MIRROR, ';
-          if (Chunk^.Data.MatMapTiling^ and TEX_UNUSED1) <> 0 then
-            Output := Output + ' TEX_UNUSED1, ';
-          if (Chunk^.Data.MatMapTiling^ and TEX_INVERT) <> 0 then
-            Output := Output + ' TEX_INVERT, ';
-          if (Chunk^.Data.MatMapTiling^ and TEX_NOWRAP) <> 0 then
-            Output := Output + ' TEX_NOWRAP, ';
-          if (Chunk^.Data.MatMapTiling^ and TEX_SAT) <> 0 then
-            Output := Output + ' TEX_SAT, ';
-          if (Chunk^.Data.MatMapTiling^ and TEX_ALPHA_SOURCE) <> 0 then
-            Output := Output + ' TEX_ALPHA_SOURCE, ';
-          if (Chunk^.Data.MatMapTiling^ and TEX_TINT) <> 0 then
-            Output := Output + ' TEX_TINT, ';
-          if (Chunk^.Data.MatMapTiling^ and TEX_DONT_USE_ALPHA) <> 0 then
-            Output := Output + ' TEX_DONT_USE_ALPHA, ';
-          if (Chunk^.Data.MatMapTiling^ and TEX_RGB_TINT) <> 0 then
-            Output := Output + ' TEX_RGB_TINT, ';
-          Delete(Output, Length(Output) - 1, 2); // take the last comma out
-        end;
-        Strings.Add(Output);
-      end;
-      MAT_MAP_COL1:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.MatMapCol1^.Red]);
-        Output := Output + Format(' G: %d, ', [Chunk^.Data.MatMapCol1^.Green]);
-        Output := Output + Format(' B: %d', [Chunk^.Data.MatMapCol1^.Blue]);
-        Strings.Add(Output);
-      end;
-      MAT_MAP_COL2:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.MatMapCol2^.Red]);
-        Output := Output + Format(' G: %d, ', [Chunk^.Data.MatMapCol2^.Green]);
-        Output := Output + Format(' B: %d', [Chunk^.Data.MatMapCol2^.Blue]);
-        Strings.Add(Output);
-      end;
-      MAT_MAP_RCOL:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.MatMapRCol^.Red]);
-        Output := Output + Format(' G: %d, ', [Chunk^.Data.MatMapRCol^.Green]);
-        Output := Output + Format(' B: %d', [Chunk^.Data.MatMapRCol^.Blue]);
-        Strings.Add(Output);
-      end;
-      MAT_MAP_GCOL:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.MatMapGCol^.Red]);
-        Output := Output + Format(' G: %d, ', [Chunk^.Data.MatMapGCol^.Green]);
-        Output := Output + Format(' B: %d', [Chunk^.Data.MatMapGCol^.Blue]);
-        Strings.Add(Output);
-      end;
-      MAT_MAP_BCOL:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sColor R: %d, ', [ID, Chunk^.Data.MatMapBCol^.Red]);
-        Output := Output + Format(' G: %d, ', [Chunk^.Data.MatMapBCol^.Green]);
-        Output := Output + Format(' B: %d', [Chunk^.Data.MatMapBCol^.Blue]);
-        Strings.Add(Output);
-      end;
-      MAT_MAP_TEXBLUR:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMap bluring of  %f', [ID, Chunk^.Data.MatMapTexblur^]);
-        Strings.Add(Output);
-      end;
-      MAT_MAP_USCALE:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMap U scale of  %f', [ID, Chunk^.Data.MatMapUScale^]);
-        Strings.Add(Output);
-      end;
-      MAT_MAP_VSCALE:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMap V scale of  %f', [ID, Chunk^.Data.MatMapVScale^]);
-        Strings.Add(Output);
-      end;
-      MAT_MAP_UOFFSET:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMap U offset of  %f', [ID, Chunk^.Data.MatMapUOffset^]);
-        Strings.Add(Output);
-      end;
-      MAT_MAP_VOFFSET:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMap V offset of  %f', [ID, Chunk^.Data.MatMapVOffset^]);
-        Strings.Add(Output);
-      end;
-      MAT_MAP_ANG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMap rotation angle of  %f', [ID, Chunk^.Data.MatMapAng^]);
-        Strings.Add(Output);
-      end;
-      MAT_BUMP_PERCENT:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sPercentage of %d%%', [ID, Chunk^.Data.MatBumpPercent^]);
-        Strings.Add(Output);
-      end;
-      KFHDR:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sRevision level of $%x', [ID, Chunk^.Data.KFHdr^.Revision]);
-        Strings.Add(Output);
-        Output := Format('%sFilename %s', [ID, Chunk^.Data.KFHdr^.FileName]);
-        Strings.Add(Output);
-        Output := Format('%sAnimation length of %d',
-          [ID, Chunk^.Data.KFHdr^.AnimLength]);
-        Strings.Add(Output);
-      end;
-      KFSEG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sSegment starts at %d and ends at %d',
-          [ID, Chunk^.Data.KFSeg^.First, Chunk^.Data.KFSeg^.Last]);
-        Strings.Add(Output);
-      end;
-      KFCURTIME:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sCurrent frame is %d', [ID, Chunk^.Data.KFCurtime^]);
-        Strings.Add(Output);
-      end;
-      NODE_ID:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sNode ID: %d', [ID, Chunk^.Data.KFID^]);
-        Strings.Add(Output);
-      end;
-      NODE_HDR:
-      begin
-        Source.ReadChunkData(Chunk);
-        Strings.Add(Format('%sObject Name: %s',
-          [ID, Chunk^.Data.NodeHdr^.ObjNameStr]));
-        //--- Flags 1
-        Strings.Add(Format('%sFlags 1: $%x', [ID, Chunk^.Data.NodeHdr^.Flags1]));
-        if DumpLevel = dlMaximumDump then
-          with Chunk^.Data.NodeHdr^ do
-          begin
-            if (Flags1 and NODE_RENDOB_HIDE) <> 0 then
-              Strings.Add(Format('%sNODE_RENDOB_HIDE', [ID]));
-            if (Flags1 and NODE_OFF) <> 0 then
-              Strings.Add(Format('%sNODE_OFF', [ID]));
-            if (Flags1 and ATKEY1) <> 0 then
-              Strings.Add(Format('%sATKEY1', [ID]));
-            if (Flags1 and ATKEY2) <> 0 then
-              Strings.Add(Format('%sATKEY2', [ID]));
-            if (Flags1 and ATKEY3) <> 0 then
-              Strings.Add(Format('%sATKEY3', [ID]));
-            if (Flags1 and ATKEY4) <> 0 then
-              Strings.Add(Format('%sATKEY4', [ID]));
-            if (Flags1 and ATKEY5) <> 0 then
-              Strings.Add(Format('%sATKEY5', [ID]));
-            if (Flags1 and ATKEYFLAGS) <> 0 then
-              Strings.Add(Format('%sATKEYFLAGS', [ID]));
-            if (Flags1 and MARK_NODE) <> 0 then
-              Strings.Add(Format('%sMARK_NODE', [ID]));
-            if (Flags1 and DISABLE_NODE) <> 0 then
-              Strings.Add(Format('%sDISABLE_NODE', [ID]));
-            if (Flags1 and HIDE_NODE) <> 0 then
-              Strings.Add(Format('%sHIDE_NODE', [ID]));
-            if (Flags1 and FAST_NODE) <> 0 then
-              Strings.Add(Format('%sFAST_NODE', [ID]));
-            if (Flags1 and PRIMARY_NODE) <> 0 then
-              Strings.Add(Format('%sPRIMARY_NODE', [ID]));
-            if (Flags1 and NODE_CALC_PATH) <> 0 then
-              Strings.Add(Format('%sNODE_CALC_PATH', [ID]));
-          end;
-
-        //--- Flags 2
-        Strings.Add(Format('%sFlags 2: $%x', [ID, Chunk^.Data.NodeHdr^.Flags2]));
-        if DumpLevel = dlMaximumDump then
-          with Chunk^.Data.NodeHdr^ do
-          begin
-            if (Flags2 and NODE_HAS_PATH) <> 0 then
-              Strings.Add(Format('%sNODE_HAS_PATH', [ID]));
-            if (Flags2 and NODE_AUTO_SMOOTH) <> 0 then
-              Strings.Add(Format('%sNODE_AUTO_SMOOTH', [ID]));
-            if (Flags2 and NODE_FROZEN) <> 0 then
-              Strings.Add(Format('%sNODE_FROZEN', [ID]));
-            if (Flags2 and NODE_ANI_HIDDEN) <> 0 then
-              Strings.Add(Format('%sNODE_ANI_HIDDEN', [ID]));
-            if (Flags2 and NODE_MOTION_BLUR) <> 0 then
-              Strings.Add(Format('%sNODE_MOTION_BLUR', [ID]));
-            if (Flags2 and NODE_BLUR_BRANCH) <> 0 then
-              Strings.Add(Format('%sNODE_BLUR_BRANCH', [ID]));
-            if (Flags2 and NODE_MORPH_MTL) <> 0 then
-              Strings.Add(Format('%sNODE_MORPH_MTL', [ID]));
-            if (Flags2 and NODE_MORPH_OB) <> 0 then
-              Strings.Add(Format('%sNODE_MORPH_OB', [ID]));
-          end;
-
-        if Chunk^.Data.NodeHdr^.ParentIndex = -1 then
-          Strings.Add(Format('%sNo Parent', [ID]))
-        else
-          Strings.Add(Format('%sParent %d', [ID, Chunk^.Data.NodeHdr^.ParentIndex]));
-      end;
-      INSTANCE_NAME:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sInstance Name: %s', [ID, Chunk^.Data.InstanceName^]);
-        Strings.Add(Output);
-      end;
-      PARENT_NAME:
-      begin
-        Source.ReadChunkData(Chunk);
-        if Chunk^.Data.InstanceName = nil then
-          Strings.Add(Format('%sNo Parent', [ID]))
-        else
-          Strings.Add(Format('%sParent Name: %s', [ID, Chunk^.Data.InstanceName^]));
-      end;
-      PIVOT:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sPivot at  %f,  %f,  %f',
-          [ID, Chunk^.Data.Pivot^.X, Chunk^.Data.Pivot^.Y,
-          Chunk^.Data.Pivot^.Z]);
-        Strings.Add(Output);
-      end;
-      BOUNDBOX:
-        if Assigned(Chunk^.Data.Dummy) then
-        begin
-          Output := Format('%sMinimum at  %f,  %f,  %f',
-            [ID, Chunk^.Data.BoundBox^.Min.X, Chunk^.Data.BoundBox^.Min.Y,
-            Chunk^.Data.BoundBox^.Min.Z]);
-          Strings.Add(Output);
-          Output := Format('%sMaximum at  %f,  %f,  %f',
-            [ID, Chunk^.Data.BoundBox^.Max.X, Chunk^.Data.BoundBox^.Max.Y,
-            Chunk^.Data.BoundBox^.Max.Z]);
-          Strings.Add(Output);
-        end;
-      MORPH_SMOOTH:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%sMorph Smoothing Angle of  %f',
-          [ID, Chunk^.Data.MorphSmooth^]);
-        Strings.Add(Output);
-      end;
-      POS_TRACK_TAG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Keys, Flags: $%x',
-          [ID, Chunk^.Data.PosTrackTag^.TrackHdr.KeyCount,
-          Chunk^.Data.PosTrackTag^.TrackHdr.Flags]);
-        Strings.Add(Output);
-        for I := 0 to Chunk^.Data.PosTrackTag^.TrackHdr.KeyCount - 1 do
-        begin
-          DumpKeyHeader(Strings, Chunk^.Data.PosTrackTag^.KeyHdrList^[I],
-            IndentLevel + 1);
-          Output := Format('%sObject at  %f,  %f,  %f',
-            [ID, Chunk^.Data.PosTrackTag^.PositionList^[I].X,
-            Chunk^.Data.PosTrackTag^.PositionList^[I].Y,
-            Chunk^.Data.PosTrackTag^.PositionList^[I].Z]);
-          Strings.Add(Output);
-        end;
-      end;
-      ROT_TRACK_TAG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Keys, Flags: $%x',
-          [ID, Chunk^.Data.RotTrackTag^.TrackHdr.KeyCount,
-          Chunk^.Data.RotTrackTag^.TrackHdr.Flags]);
-        Strings.Add(Output);
-        for I := 0 to Chunk^.Data.RotTrackTag^.TrackHdr.KeyCount - 1 do
-        begin
-          DumpKeyHeader(Strings, Chunk^.Data.RotTrackTag^.KeyHdrList^[I],
-            IndentLevel + 1);
-          Output := Format('%sRotation of  %f',
-            [ID, Chunk^.Data.RotTrackTag^.RotationList^[I].Angle]);
-          Strings.Add(Output);
-          Output := Format('%sAxis of  %f,  %f,  %f',
-            [ID, Chunk^.Data.RotTrackTag^.RotationList^[I].X,
-            Chunk^.Data.RotTrackTag^.RotationList^[I].Y,
-            Chunk^.Data.RotTrackTag^.RotationList^[I].Z]);
-          Strings.Add(Output);
-        end;
-      end;
-      SCL_TRACK_TAG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Keys, Flags: $%x',
-          [ID, Chunk^.Data.ScaleTrackTag^.TrackHdr.KeyCount,
-          Chunk^.Data.ScaleTrackTag^.TrackHdr.Flags]);
-        Strings.Add(Output);
-        for I := 0 to Chunk^.Data.ScaleTrackTag^.TrackHdr.KeyCount - 1 do
-        begin
-          DumpKeyHeader(Strings, Chunk^.Data.ScaleTrackTag^.KeyHdrList^[I],
-            IndentLevel + 1);
-          Output := Format('%sScale of  %f,  %f,  %f',
-            [ID, Chunk^.Data.ScaleTrackTag^.ScaleList^[I].X,
-            Chunk^.Data.ScaleTrackTag^.ScaleList^[I].Y,
-            Chunk^.Data.ScaleTrackTag^.ScaleList^[I].Z]);
-          Strings.Add(Output);
-        end;
-      end;
-      FOV_TRACK_TAG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Keys, Flags: $%x',
-          [ID, Chunk^.Data.FovTrackTag^.TrackHdr.KeyCount,
-          Chunk^.Data.FovTrackTag^.TrackHdr.Flags]);
-        Strings.Add(Output);
-        for I := 0 to Chunk^.Data.FovTrackTag^.TrackHdr.KeyCount - 1 do
-        begin
-          DumpKeyHeader(Strings, Chunk^.Data.FovTrackTag^.KeyHdrList^[I],
-            IndentLevel + 1);
-          Output := Format('%sCamera FOV of  %f',
-            [ID, Chunk^.Data.FovTrackTag^.FOVAngleList^[I]]);
-          Strings.Add(Output);
-        end;
-      end;
-      ROLL_TRACK_TAG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Keys, Flags: $%x',
-          [ID, Chunk^.Data.RollTrackTag^.TrackHdr.KeyCount,
-          Chunk^.Data.RollTrackTag^.TrackHdr.Flags]);
-        Strings.Add(Output);
-        for I := 0 to Chunk^.Data.RollTrackTag^.TrackHdr.KeyCount - 1 do
-        begin
-          DumpKeyHeader(Strings, Chunk^.Data.RollTrackTag^.KeyHdrList^[I],
-            IndentLevel + 1);
-          Output := Format('%sCamera Roll of  %f',
-            [ID, Chunk^.Data.RollTrackTag^.RollAngleList^[I]]);
-          Strings.Add(Output);
-        end;
-      end;
-      COL_TRACK_TAG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Keys, Flags: $%x',
-          [ID, Chunk^.Data.ColTrackTag^.TrackHdr.KeyCount,
-          Chunk^.Data.ColTrackTag^.TrackHdr.Flags]);
-        Strings.Add(Output);
-        for I := 0 to Chunk^.Data.ColTrackTag^.TrackHdr.KeyCount - 1 do
-        begin
-          DumpKeyHeader(Strings, Chunk^.Data.ColTrackTag^.KeyHdrList^[I],
-            IndentLevel + 1);
-          Output := Format('%sColor R:  %f, ',
-            [ID, Chunk^.Data.ColTrackTag^.ColorList^[I].B]);
-          Output := Output + Format(' G:  %f, ',
-            [Chunk^.Data.ColTrackTag^.ColorList^[I].G]);
-          Output := Output + Format(' B:  %f',
-            [Chunk^.Data.ColTrackTag^.ColorList^[I].B]);
-          Strings.Add(Output);
-        end;
-      end;
-      MORPH_TRACK_TAG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Keys, Flags: $%x',
-          [ID, Chunk^.Data.MorphTrackTag^.TrackHdr.KeyCount,
-          Chunk^.Data.MorphTrackTag^.TrackHdr.Flags]);
-        Strings.Add(Output);
-        for I := 0 to Chunk^.Data.MorphTrackTag^.TrackHdr.KeyCount - 1 do
-        begin
-          DumpKeyHeader(Strings, Chunk^.Data.MorphTrackTag^.KeyHdrList^[I],
-            IndentLevel + 1);
-          Output := Format('%sMorph to %s',
-            [ID, Chunk^.Data.MorphTrackTag^.MorphList^[I]]);
-          Strings.Add(Output);
-        end;
-      end;
-      HOT_TRACK_TAG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Keys, Flags: $%x',
-          [ID, Chunk^.Data.HotTrackTag^.TrackHdr.KeyCount,
-          Chunk^.Data.HotTrackTag^.TrackHdr.Flags]);
-        Strings.Add(Output);
-        for I := 0 to Chunk^.Data.HotTrackTag^.TrackHdr.KeyCount - 1 do
-        begin
-          DumpKeyHeader(Strings, Chunk^.Data.HotTrackTag^.KeyHdrList^[I],
-            IndentLevel + 1);
-          Output := Format('%sHotspot angle of  %f',
-            [ID, Chunk^.Data.HotTrackTag^.HotspotAngleList^[I]]);
-          Strings.Add(Output);
-        end;
-      end;
-      FALL_TRACK_TAG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Keys, Flags: $%x',
-          [ID, Chunk^.Data.FallTrackTag^.TrackHdr.KeyCount,
-          Chunk^.Data.FallTrackTag^.TrackHdr.Flags]);
-        Strings.Add(Output);
-        for I := 0 to Chunk^.Data.FallTrackTag^.TrackHdr.KeyCount - 1 do
-        begin
-          DumpKeyHeader(Strings, Chunk^.Data.FallTrackTag^.KeyHdrList^[I],
-            IndentLevel + 1);
-          Output := Format('%sFalloff Angle of  %f',
-            [ID, Chunk^.Data.FallTrackTag^.FalloffAngleList^[I]]);
-          Strings.Add(Output);
-        end;
-      end;
-      HIDE_TRACK_TAG:
-      begin
-        Source.ReadChunkData(Chunk);
-        Output := Format('%s%d Keys, Flags: $%x',
-          [ID, Chunk^.Data.HideTrackTag^.TrackHdr.KeyCount,
-          Chunk^.Data.HideTrackTag^.TrackHdr.Flags]);
-        Strings.Add(Output);
-        for I := 0 to Chunk^.Data.HideTrackTag^.TrackHdr.KeyCount - 1 do
-          DumpKeyHeader(Strings, Chunk^.Data.HideTrackTag^.KeyHdrList^[I],
-            IndentLevel + 1);
-      end;
-    end; // end case
-  end;
-
-  Child := Chunk^.Children;
-
-  while Assigned(Child) do
-  begin
-    DumpChunk(Source, Strings, Child, IndentLevel + 1, DumpLevel);
-    Child := Child^.Sibling;
-  end;
-end;
-
-//----------------- common support function ---------------------------------------------------------------------------
-
-procedure AddChild(Parent, Child: PChunk3DS);
-
-// AddChild puts the chunk at the end of the Sibling list
-
-var
-  Current: PChunk3DS;
-
-begin
-  if Parent^.Children = nil then
-    Parent^.Children := Child
-  else
-  begin
-    Current := Parent^.Children;
-    while Assigned(Current^.Sibling) do
-      Current := Current^.Sibling;
-    Current^.Sibling := Child;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure AddChildOrdered(Parent, Child: PChunk3DS);
-
-// AddChildOrdered will insert the child among its siblings depending
-// on the order of occurance set by the 3DS file.
-
-var
-  Current, Prev: PChunk3DS;
-  ChildValue: integer;
-
-begin
-  ChildValue := GetChunkValue(Child^.Tag);
-
-  if Parent^.Children = nil then
-    Parent^.Children := Child
-  else
-  begin
-    Current := Parent^.Children;
-    Prev := nil;
-    while Assigned(Current^.Sibling) do
-    begin
-      if ChildValue > GetChunkValue(Current^.Tag) then
-        break;
-      Prev := Current;
-      Current := Current^.Sibling;
-    end;
-
-    if ChildValue > GetChunkValue(Current^.Tag) then
-    begin
-      Child^.Sibling := Current;
-      if Assigned(Prev) then
-        Prev^.Sibling := Child
-      else
-        Parent^.Children := Child;
-    end
-    else
-    begin
-      Child^.Sibling := Current^.Sibling;
-      Current^.Sibling := Child;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function FindChunk(Top: PChunk3DS; Tag: word): PChunk3DS;
-
-  // searchs the given top Chunk and its children for a match
-
-var
-  Child, Match: PChunk3DS;
-
-begin
-  Result := nil;
-  if Assigned(Top) then
-    if Top^.Tag = Tag then
-      Result := Top
-    else
-    begin
-      Child := Top^.Children;
-      while Assigned(Child) do
-      begin
-        Match := FindChunk(Child, Tag);
-        if Assigned(Match) then
-        begin
-          Result := Match;
-          Break;
-        end;
-        Child := Child^.Sibling;
-      end;
-    end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function FindNextChunk(Local: PChunk3DS; Tag: word): PChunk3DS;
-
-var
-  Current: PChunk3DS;
-
-begin
-  Result := nil;
-  Current := Local;
-  while Assigned(Current) and (Result = nil) do
-  begin
-    if Current^.Tag = Tag then
-      Result := Current;
-    Current := Current^.Sibling;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure FreeChunkData(var Chunk: PChunk3DS);
-
-begin
-  if Assigned(Chunk^.Data.Dummy) then
-  begin
-    // do only care about Chunk^.Data fields that contain other pointers
-    // that need to be free
-    case Chunk^.Tag of
-      MAT_SXP_TEXT_DATA,
-      MAT_SXP_TEXT2_DATA,
-      MAT_SXP_OPAC_DATA,
-      MAT_SXP_BUMP_DATA,
-      MAT_SXP_SPEC_DATA,
-      MAT_SXP_SHIN_DATA,
-      MAT_SXP_SELFI_DATA,
-      MAT_SXP_TEXT_MASKDATA,
-      MAT_SXP_TEXT2_MASKDATA,
-      MAT_SXP_OPAC_MASKDATA,
-      MAT_SXP_BUMP_MASKDATA,
-      MAT_SXP_SPEC_MASKDATA,
-      MAT_SXP_SHIN_MASKDATA,
-      MAT_SXP_SELFI_MASKDATA,
-      MAT_SXP_REFL_MASKDATA,
-      PROC_DATA:
-        FreeMem(Chunk^.Data.IpasData^.Data);
-      POINT_ARRAY:
-        FreeMem(Chunk^.Data.PointArray^.PointList);
-      POINT_FLAG_ARRAY:
-        FreeMem(Chunk^.Data.PointFlagArray^.FlagList);
-      FACE_ARRAY:
-        Freemem(Chunk^.Data.FaceArray^.FaceList);
-      MSH_MAT_GROUP:
-      begin
-        Dispose(Chunk^.Data.MshMatGroup);
-        Chunk^.Data.MshMatGroup := nil;
-      end;
-      SMOOTH_GROUP:
-        FreeMem(Chunk^.Data.SmoothGroup^.GroupList);
-      TEX_VERTS:
-        FreeMem(Chunk^.Data.TexVerts^.TextVertList);
-      XDATA_ENTRY:
-        FreeMem(Chunk^.Data.XDataEntry^.Data);
-      POS_TRACK_TAG:
-      begin
-        FreeMem(Chunk^.Data.PosTrackTag^.KeyHdrList);
-        Freemem(Chunk^.Data.PosTrackTag^.PositionList);
-      end;
-      COL_TRACK_TAG:
-      begin
-        FreeMem(Chunk^.Data.ColTrackTag^.KeyHdrList);
-        FreeMem(Chunk^.Data.ColTrackTag^.ColorList);
-      end;
-      ROT_TRACK_TAG:
-      begin
-        FreeMem(Chunk^.Data.RotTrackTag^.KeyHdrList);
-        FreeMem(Chunk^.Data.RotTrackTag^.RotationList);
-      end;
-      SCL_TRACK_TAG:
-      begin
-        FreeMem(Chunk^.Data.ScaleTrackTag^.KeyHdrList);
-        FreeMem(Chunk^.Data.ScaleTrackTag^.ScaleList);
-      end;
-      MORPH_TRACK_TAG:
-      begin
-        FreeMem(Chunk^.Data.MorphTrackTag^.KeyHdrList);
-        FreeMem(Chunk^.Data.MorphTrackTag^.MorphList);
-      end;
-      FOV_TRACK_TAG:
-      begin
-        FreeMem(Chunk^.Data.FovTrackTag^.KeyHdrList);
-        FreeMem(Chunk^.Data.FovTrackTag^.FOVAngleList);
-      end;
-      ROLL_TRACK_TAG:
-      begin
-        FreeMem(Chunk^.Data.RollTrackTag^.KeyHdrList);
-        FreeMem(Chunk^.Data.RollTrackTag^.RollAngleList);
-      end;
-      HOT_TRACK_TAG:
-      begin
-        FreeMem(Chunk^.Data.HotTrackTag^.KeyHdrList);
-        FreeMem(Chunk^.Data.HotTrackTag^.HotspotAngleList);
-      end;
-      FALL_TRACK_TAG:
-      begin
-        FreeMem(Chunk^.Data.FallTrackTag^.KeyHdrList);
-        FreeMem(Chunk^.Data.FallTrackTag^.FalloffAngleList);
-      end;
-      KFHDR:
-      begin
-        Dispose(Chunk^.Data.KFHdr);
-        Chunk^.Data.KFHdr := nil;
-      end;
-      NODE_HDR:
-      begin
-        Dispose(Chunk^.Data.NodeHdr);
-        Chunk^.Data.NodeHdr := nil;
-      end;
-      HIDE_TRACK_TAG:
-        FreeMem(Chunk^.Data.HideTrackTag^.KeyHdrList);
-    end; // case end
-    // finally free the data chunk
-    FreeMem(Chunk^.Data.Dummy);
-    Chunk^.Data.Dummy := nil;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure InitChunk(var Chunk: PChunk3DS);
-
-// initializes and allocates memory for a chunk
-
-begin
-  New(Chunk);
-  if Chunk = nil then
-    ShowError(strError3DS_NO_MEM);
-
-  // set default values
-  with Chunk^ do
-  begin
-    Tag := NULL_CHUNK;
-    Size := 0;
-    Position := 0;
-    Data.Dummy := nil;
-    Sibling := nil;
-    Children := nil;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure InitChunkList(var List: PChunklist3DS; Count: integer);
-
-begin
-  if List = nil then
-  begin
-    List := AllocMem(SizeOf(TChunklist3DS));
-    if List = nil then
-      ShowError(strError3DS_NO_MEM);
-  end;
-
-  List^.Count := Count;
-
-  if Count > 0 then
-  begin
-    List^.List := AllocMem(Count * SizeOf(TChunkListEntry3DS));
-    if List^.List = nil then
-      ShowError(strError3DS_NO_MEM);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function PutGenericNode(TagID: word; ParentChunk: PChunk3DS): PChunk3DS;
-
-  // put a tag into database as a child of ParentChunk
-
-begin
-  InitChunk(Result);
-  Result^.Tag := TagID;
-  AddChildOrdered(ParentChunk, Result);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ReleaseChunk(var Chunk: PChunk3DS);
-
-var
-  Sibling: PChunk3DS;
-
-begin
-  // free memory associated with chunk and substructure
-  while Assigned(Chunk) do
-  begin
-    Sibling := Chunk^.Sibling;
-    ReleaseChunk(Chunk^.Children);
-    FreeChunkData(Chunk);
-    FreeMem(Chunk);
-    Chunk := Sibling;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ReleaseChunkList(var List: PChunkList3DS);
-
-var
-  I: integer;
-
-begin
-  if Assigned(List) then
-  begin
-    // tell the string management that we don't need these strings any longer
-    for I := 0 to List^.Count - 1 do
-      List^.List^[I].NameStr := '';
-    if Assigned(List^.List) then
-      FreeMem(List^.List);
-    FreeMem(List);
-    List := nil;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function CopyChunk(Chunk: PChunk3DS): PChunk3DS;
-
-  // copies the structure of Chunk to Result, assigned data of Chunk will not be copied, but
-  // moved to Result (actually references will be moved)
-
-var
-  ChildIn: PChunk3DS;
-  ChildOut: ^PChunk3DS;
-
-begin
-  if Chunk = nil then
-    ShowError(strERROR3DS_INVALID_ARG);
-
-  InitChunk(Result);
-  with Result^ do
-  begin
-    Tag := Chunk^.Tag;
-    Size := Chunk^.Size;
-    Position := Chunk^.Position;
-
-    if Assigned(Chunk^.Data.Dummy) then
-    begin
-      Data.Dummy := Chunk^.Data.Dummy;
-      Chunk^.Data.Dummy := nil;
-    end;
-
-    ChildIn := Chunk^.Children;
-    ChildOut := @Children;
-    while Assigned(ChildIn) do
-    begin
-      ChildOut^ := CopyChunk(ChildIn);
-      ChildIn := ChildIn^.Sibling;
-      ChildOut := @ChildOut^.Sibling;
-    end;
-  end;
-end;
-
-//----------------- list update routines ------------------------------------------------------------------------------
-
-procedure UpdateMatEntryList(const Source: TFile3DS; var DB: TDatabase3DS);
-
-var
-  Parent, MatName, MatEntry: PChunk3DS;
-  I, MatCount: integer;
-
-begin
-  if DB.MatlistDirty then
-  begin
-    ReleaseChunkList(DB.MatList);
-
-    Parent := FindChunk(DB.TopChunk, MDATA);
-    if Parent = nil then
-      Parent := FindChunk(DB.TopChunk, MLIBMAGIC);
-
-    MatCount := 0;
-    if Assigned(Parent) then
-    begin
-      MatEntry := FindChunk(Parent, MAT_ENTRY);
-      while Assigned(MatEntry) do
-      begin
-        MatEntry := FindNextChunk(MatEntry^.Sibling, MAT_ENTRY);
-        Inc(MatCount);
-      end;
-    end;
-
-    InitChunkList(DB.MatList, MatCount);
-    if Parent = nil then
-      Exit;
-
-    I := 0;
-    MatEntry := FindChunk(Parent, MAT_ENTRY);
-    while Assigned(MatEntry) do
-    begin
-      MatName := FindChunk(MatEntry, MAT_NAME);
-      Source.ReadChunkData(MatName);
-      DB.MatList^.List^[I].Chunk := MatEntry;
-      DB.MatList^.List^[I].NameStr := string(MatName^.Data.MatName);
-      MatEntry := FindNextChunk(MatEntry^.Sibling, MAT_ENTRY);
-      Inc(I);
-    end;
-    DB.MatlistDirty := False;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure UpdateNamedObjectList(Source: TFile3DS; var DB: TDatabase3DS);
-
-var
-  MDataChunk, Current: PChunk3DS;
-  I: integer;
-
-begin
-  if DB.ObjListDirty then
-  begin
-    ReleaseChunkList(DB.ObjList);
-
-    MDataChunk := FindChunk(DB.TopChunk, MDATA);
-
-    I := 0;
-    if Assigned(MDataChunk) then
-    begin
-      Current := FindChunk(MDataChunk, NAMED_OBJECT);
-      while Assigned(Current) do
-      begin
-        Inc(I);
-        Current := FindNextChunk(Current^.Sibling, NAMED_OBJECT);
-      end;
-    end;
-
-    InitChunkList(DB.ObjList, I);
-    if MDataChunk = nil then
-      Exit;
-
-    I := 0;
-    Current := FindChunk(MDataChunk, NAMED_OBJECT);
-    while Assigned(Current) do
-    begin
-      Source.ReadChunkData(Current);
-      DB.ObjList^.List^[I].Chunk := Current;
-      DB.ObjList^.List^[I].NameStr := string(Current^.Data.NamedObject);
-      Current := FindNextChunk(Current^.Sibling, NAMED_OBJECT);
-      Inc(I);
-    end;
-    DB.ObjListDirty := False;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure UpdateNodeTagList(Source: TFile3DS; var DB: TDatabase3DS);
-
-var
-  KFDataChunk, Chunk, Current: PChunk3DS;
-  I: integer;
-
-begin
-  if DB.NodeListDirty then
-  begin
-    ReleaseChunkList(DB.NodeList);
-    KFDataChunk := FindChunk(DB.TopChunk, KFDATA);
-
-    I := 0;
-    // if there is a keyframe section then count the number of node tags
-    if Assigned(KFDataChunk) then
-    begin
-      Current := KFDataChunk^.Children;
-      while Assigned(Current) do
-      begin
-        case Current^.Tag of
-          AMBIENT_NODE_TAG,
-          OBJECT_NODE_TAG,
-          CAMERA_NODE_TAG,
-          TARGET_NODE_TAG,
-          LIGHT_NODE_TAG,
-          L_TARGET_NODE_TAG,
-          SPOTLIGHT_NODE_TAG:
-            Inc(I);
-        end;
-        Current := Current^.Sibling;
-      end;
-    end;
-
-    InitChunkList(DB.NodeList, I);
-    if I = 0 then
-      Exit;
-
-    I := 0;
-    Current := KFDataChunk^.Children;
-    while Assigned(Current) do
-    begin
-      case Current^.Tag of
-        AMBIENT_NODE_TAG,
-        OBJECT_NODE_TAG,
-        CAMERA_NODE_TAG,
-        TARGET_NODE_TAG,
-        LIGHT_NODE_TAG,
-        L_TARGET_NODE_TAG,
-        SPOTLIGHT_NODE_TAG:
-        begin
-          Chunk := FindNextChunk(Current^.Children, NODE_HDR);
-          if Assigned(Chunk) then
-          begin
-            Source.ReadChunkData(Chunk);
-            DB.NodeList^.List^[I].Chunk := Current;
-            DB.NodeList^.List^[I].NameStr := Chunk^.Data.NodeHdr^.ObjNameStr;
-            FreeChunkData(Chunk);
-          end;
-
-          // Object tags may have an instance name as well, which gets appended to
-          // the object name with a "." seperator
-          if Current^.Tag = OBJECT_NODE_TAG then
-          begin
-            Chunk := FindNextChunk(Current^.Children, INSTANCE_NAME);
-            if Assigned(Chunk) then
-            begin
-              Source.ReadChunkData(Chunk);
-              DB.NodeList^.List^[I].NameStr :=
-                DB.NodeList^.List^[I].NameStr + '.' + string(Chunk^.Data.InstanceName);
-              FreeChunkData(Chunk);
-            end;
-          end;
-          Inc(I); // Increment index counter
-        end;
-      end;
-      Current := Current^.Sibling;
-    end;
-
-    DB.NodeListDirty := False;
-  end;
-end;
-
-//----------------- other support function ----------------------------------------------------------------------------
-
-function GetGenericNodeCount(const Source: TFile3DS; var DB: TDatabase3DS;
-  Tag: word): integer;
-
-var
-  I: integer;
-
-begin
-  UpdateNodeTagList(Source, DB);
-
-  Result := 0;
-  for I := 0 to DB.NodeList^.Count - 1 do
-    if DB.NodeList^.List^[I].Chunk^.Tag = Tag then
-      Inc(Result);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure GetGenericNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
-  TagID: word; List: TStringList);
-
-var
-  I: cardinal;
-
-begin
-  UpdateNodeTagList(Source, DB);
-  List.Clear;
-  for I := 0 to DB.NodeList^.Count - 1 do
-    if DB.NodeList^.List^[I].Chunk^.Tag = TagID then
-      List.Add(DB.NodeList^.List^[I].NameStr);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function FindNamedAndTaggedChunk(const Source: TFile3DS; var DB: TDatabase3DS;
-  Name: string; TagID: word): PChunk3DS;
-
-  // Look through the keyframer stuff and find named chunk of the tag type TagID.
-  // Has to be a chunk that has a node header: CAMERA_NODE, LIGHT_NODE, , .
-
-var
-  KfChunk, NodeHdrChunk: PChunk3DS;
-
-begin
-  // find Keyframe Chunk
-  KfChunk := FindChunk(DB.TopChunk, KFDATA);
-
-  // look for the target tag
-  Result := FindChunk(KfChunk, TagID);
-  while Assigned(Result) do
-  begin
-    NodeHdrChunk := FindNextChunk(Result^.Children, NODE_HDR);
-    if Assigned(NodeHdrChunk) then
-    begin
-      Source.ReadChunkData(NodeHdrChunk);
-      // match name, set pointer (case sensitive comparation!)
-      if CompareStr(Name, NodeHdrChunk^.Data.NodeHdr^.ObjNameStr) = 0 then
-      begin
-        FreeChunkData(NodeHdrChunk);
-        Break;
-      end;
-      FreeChunkData(NodeHdrChunk);
-    end;
-    Result := FindNextChunk(Result^.Sibling, TagID);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function FindNodeTagByIndexAndType(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: cardinal; AType: word): PChunk3DS;
-
-var
-  I, Count: cardinal;
-
-begin
-  Result := nil;
-  Count := 0;
-  UpdateNodeTagList(Source, DB);
-  for I := 0 to DB.NodeList^.Count - 1 do
-    if DB.NodeList^.List^[I].Chunk^.Tag = AType then
-    begin
-      if Count = Index then
-      begin
-        Result := DB.NodeList^.List^[I].Chunk;
-        Break;
-      end;
-      Inc(Count);
-    end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function FindNodeTagByNameAndType(const Source: TFile3DS; DB: TDatabase3DS;
-  Name: string; AType: word): PChunk3DS;
-
-var
-  I: integer;
-
-begin
-  Result := nil;
-  UpdateNodeTagList(Source, DB);
-  for I := 0 to DB.NodeList^.Count - 1 do
-    if (DB.NodeList^.List^[I].Chunk^.Tag = AType) and
-      (CompareStr(Name, DB.NodeList^.List^[I].NameStr) = 0) then
-    begin
-      Result := DB.NodeList^.List^[I].Chunk;
-      Exit;
-    end;
-end;
-
-//----------------- material handling ---------------------------------------------------------------------------------
-
-function GetMaterialCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-
-begin
-  UpdateMatEntryList(Source, DB);
-  if DB.MatList = nil then
-    Result := 0
-  else
-    Result := DB.MatList^.Count;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function FindMatEntryByIndex(Source: TFile3DS; DB: TDatabase3DS;
-  Index: integer): PChunk3DS;
-
-begin
-  if DB.TopChunk = nil then
-    ShowError(strError3DS_INVALID_DATABASE);
-  if (DB.TopChunk^.Tag <> MLIBMAGIC) and (DB.TopChunk^.Tag <> M3DMAGIC) and
-    (DB.TopChunk^.Tag <> CMAGIC) then
-    ShowError(strError3DS_WRONG_DATABASE);
-
-  UpdateMatEntryList(Source, DB);
-  if Index < DB.MatList^.Count then
-    Result := DB.MatList^.List^[Index].Chunk
-  else
-    Result := nil;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure InitBitmap(var Map: TBitmap3DS);
-
-begin
-  FillChar(Map, SizeOf(Map), 0);
-  with Map do
-  begin
-    UScale := 1;
-    VScale := 1;
-    Tint2.R := 1;
-    Tint2.G := 1;
-    Tint2.B := 1;
-    RedTint.R := 1;
-    GreenTint.G := 1;
-    BlueTint.B := 1;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure InitMaterial(var Mat: TMaterial3DS);
-
-begin
-  FillChar(Mat, SizeOf(Mat), 0);
-  with Mat do
-  begin
-    WireSize := 1;
-    Shading := stPhong;
-    Reflect.AutoMap.Size := 100;
-    Reflect.AutoMap.nthFrame := 1;
-    InitBitmap(Texture.Map);
-    InitBitmap(Texture.Mask);
-    InitBitmap(Texture2.Map);
-    InitBitmap(Texture2.Mask);
-    InitBitmap(Opacity.Map);
-    InitBitmap(Opacity.Mask);
-    InitBitmap(Reflect.Map);
-    InitBitmap(Reflect.Mask);
-    InitBitmap(Bump.Map);
-    InitBitmap(Bump.Mask);
-    InitBitmap(SpecMap.Map);
-    InitBitmap(SpecMap.Mask);
-    InitBitmap(ShinMap.Map);
-    InitBitmap(ShinMap.Mask);
-    InitBitmap(IllumMap.Map);
-    InitBitmap(IllumMap.Mask);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ReleaseMaterial(Mat: PMaterial3DS);
-
-begin
-  if Assigned(Mat) then
-  begin
-    FreeMem(Mat^.Texture.Map.Data);
-    FreeMem(Mat^.Texture.Mask.Data);
-    FreeMem(Mat^.Texture2.Map.Data);
-    FreeMem(Mat^.Texture2.Mask.Data);
-    FreeMem(Mat^.Opacity.Map.Data);
-    FreeMem(Mat^.Opacity.Mask.Data);
-    FreeMem(Mat^.Reflect.Mask.Data);
-    FreeMem(Mat^.Bump.Map.Data);
-    FreeMem(Mat^.Bump.Mask.Data);
-    FreeMem(Mat^.Specmap.Map.Data);
-    FreeMem(Mat^.SpecMap.Mask.Data);
-    FreeMem(Mat^.ShinMap.Map.Data);
-    FreeMem(Mat^.ShinMap.Mask.Data);
-    FreeMem(Mat^.IllumMap.Map.Data);
-    FreeMem(Mat^.IllumMap.Mask.Data);
-    Dispose(Mat);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function FindNamedObjectByIndex(Source: TFile3DS; DB: TDatabase3DS;
-  AType: word; Index: integer): PChunk3DS;
-
-  // searches the database for a named object by index position and object type
-  // returns the NAMED_OBJECT chunk if found, nil otherwise
-
-var
-  Chunk: PChunk3DS;
-  I, Count: integer;
-
-begin
-  UpdateNamedObjectList(Source, DB);
-
-  Count := 0;
-  Result := nil;
-  for I := 0 to DB.ObjList^.Count - 1 do
-  begin
-    if AType = DL_SPOTLIGHT then
-    begin
-      Chunk := FindChunk(DB.ObjList^.List^[I].Chunk, N_DIRECT_LIGHT);
-      if Assigned(Chunk) then
-        Chunk := FindChunk(Chunk, AType);
-    end
-    else
-      Chunk := FindChunk(DB.ObjList^.List^[I].Chunk, AType);
-
-    if Assigned(Chunk) then
-    begin
-      if Count = Index then
-      begin
-        Result := DB.ObjList^.List^[I].Chunk;
-        Break;
-      end
-      else
-        Inc(Count);
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure DeleteChunk(var Chunk: PChunk3DS);
-
-// returns a chunk to its untagged state state, but leaves it
-// connected to any siblings it might have
-
-begin
-  if Assigned(Chunk) then
-  begin
-    // release any children
-    if Assigned(Chunk^.Children) then
-      ReleaseChunk(Chunk^.Children);
-    // release any data
-    if Assigned(Chunk^.Data.Dummy) then
-      FreeChunkData(Chunk);
-    // return to a semi-uninitialized state
-    Chunk^.Tag := NULL_CHUNK;
-    Chunk^.Size := 0;
-    Chunk^.Position := 0;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function ReadPercentageChunk(Source: TFile3DS; Chunk: PChunk3DS): single;
-
-var
-  DataChunk: PChunk3DS;
-
-begin
-  DataChunk := FindChunk(Chunk, INT_PERCENTAGE);
-  if Assigned(DataChunk) then
-  begin
-    Source.ReadChunkData(DataChunk);
-    Result := DataChunk^.Data.IntPercentage^ / 100;
-    FreeChunkData(DataChunk);
-  end
-  else
-  begin
-    DataChunk := FindChunk(Chunk, FLOAT_PERCENTAGE);
-    if Assigned(DataChunk) then
-    begin
-      Source.ReadChunkData(DataChunk);
-      Result := DataChunk^.Data.FloatPercentage^;
-      FreeChunkData(DataChunk);
-    end
-    else
-      Result := 0;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure GetBitmapChunk(const DataSource: TFile3DS; Chunk: PChunk3DS;
-  var Bitmap: TBitmap3DS);
-
-var
-  Current: PChunk3DS;
-
-begin
-  Current := Chunk^.Children;
-  while Assigned(Current) do
-  begin
-    with Bitmap do
-    begin
-      case Current^.Tag of
-        INT_PERCENTAGE:
-        begin
-          DataSource.ReadChunkData(Current);
-          Percent := Current^.Data.IntPercentage^ / 100;
-          FreeChunkData(Current);
-        end;
-        FLOAT_PERCENTAGE:
-        begin
-          DataSource.ReadChunkData(Current);
-          Percent := Current^.Data.FloatPercentage^;
-          FreeChunkData(Current);
-        end;
-        MAT_MAPNAME:
-        begin
-          DataSource.ReadChunkData(Current);
-          NameStr := StrPas(Current^.Data.MatMapname);
-          FreeChunkData(Current);
-        end;
-        MAT_MAP_TILING:
-        begin
-          DataSource.ReadChunkData(Current);
-          if (Current^.Data.MatMapTiling^ and TEX_DECAL) <> 0 then
-            if (Current^.Data.MatMapTiling^ and TEX_NOWRAP) <> 0 then
-              Tiling := ttDecal
-            else
-              Tiling := ttBoth
-          else
-            tiling := ttTile;
-          IgnoreAlpha := (Current^.Data.MatMapTiling^ and TEX_DONT_USE_ALPHA) <> 0;
-          if (Current^.Data.MatMapTiling^ and TEX_SAT) <> 0 then
-            Filter := ftSummedArea
-          else
-            Filter := ftPyramidal;
-          Mirror := (Current^.Data.MatMapTiling^ and TEX_MIRROR) <> 0;
-          Negative := (Current^.Data.MatMapTiling^ and TEX_INVERT) <> 0;
-          if (Current^.Data.MatMapTiling^ and TEX_TINT) <> 0 then
-            if (Current^.Data.MatMapTiling^ and TEX_ALPHA_SOURCE) <> 0 then
-              Source := ttAlphaTint
-            else
-              Source := ttRGBLumaTint
-          else if (Current^.Data.MatMapTiling^ and TEX_RGB_TINT) <> 0 then
-            Source := ttRGBTint
-          else if (Current^.Data.MatMapTiling^ and TEX_ALPHA_SOURCE) <> 0 then
-            Source := ttAlpha
-          else
-            Source := ttRGB;
-          FreeChunkData(Current);
-        end;
-        MAT_MAP_USCALE:
-        begin
-          DataSource.ReadChunkData(Current);
-          UScale := Current^.Data.MatMapUScale^;
-          FreeChunkData(Current);
-        end;
-        MAT_MAP_VSCALE:
-        begin
-          DataSource.ReadChunkData(Current);
-          VScale := Current^.Data.MatMapVScale^;
-          FreeChunkData(Current);
-        end;
-        MAT_MAP_UOFFSET:
-        begin
-          DataSource.ReadChunkData(Current);
-          UOffset := Current^.Data.MatMapUOffset^;
-          FreeChunkData(Current);
-        end;
-        MAT_MAP_VOFFSET:
-        begin
-          DataSource.ReadChunkData(Current);
-          VOffset := Current^.Data.MatMapVOffset^;
-          FreeChunkData(Current);
-        end;
-        MAT_MAP_ANG:
-        begin
-          DataSource.ReadChunkData(Current);
-          Rotation := Current^.Data.MatMapAng^;
-          FreeChunkData(Current);
-        end;
-        MAT_BUMP_PERCENT:
-          ; // value is really stored in TMaterial3DS structure
-        MAT_MAP_COL1:
-        begin
-          DataSource.ReadChunkData(Current);
-          Tint1.R := Current^.Data.MatMapCol1^.Red / 255;
-          Tint1.G := Current^.Data.MatMapCol1^.Green / 255;
-          Tint1.B := Current^.Data.MatMapCol1^.Blue / 255;
-          FreeChunkData(Current);
-        end;
-        MAT_MAP_COL2:
-        begin
-          DataSource.ReadChunkData(Current);
-          Tint2.R := Current^.Data.MatMapCol2^.Red / 255;
-          Tint2.G := Current^.Data.MatMapCol2^.Green / 255;
-          Tint2.B := Current^.Data.MatMapCol2^.Blue / 255;
-          FreeChunkData(Current);
-        end;
-        MAT_MAP_RCOL:
-        begin
-          DataSource.ReadChunkData(Current);
-          RedTint.R := Current^.Data.MatMapRCol^.Red / 255;
-          RedTint.G := Current^.Data.MatMapRCol^.Green / 255;
-          RedTint.B := Current^.Data.MatMapRCol^.Blue / 255;
-          FreeChunkData(Current);
-        end;
-        MAT_MAP_GCOL:
-        begin
-          DataSource.ReadChunkData(Current);
-          GreenTint.R := Current^.Data.MatMapGCol^.Red / 255;
-          GreenTint.G := Current^.Data.MatMapGCol^.Green / 255;
-          GreenTint.B := Current^.Data.MatMapGCol^.Blue / 255;
-          FreeChunkData(Current);
-        end;
-        MAT_MAP_BCOL:
-        begin
-          DataSource.ReadChunkData(Current);
-          BlueTint.R := Current^.Data.MatMapBCol^.Red / 255;
-          BlueTint.G := Current^.Data.MatMapBCol^.Green / 255;
-          BlueTint.B := Current^.Data.MatMapBCol^.Blue / 255;
-          FreeChunkData(Current);
-        end;
-        MAT_MAP_TEXBLUR:
-        begin
-          DataSource.ReadChunkData(Current);
-          Blur := Current^.Data.MatMapTexBlur^; // float percents
-          FreeChunkData(Current);
-        end;
-      end; // case Current^.Tag of
-      Current := Current^.Sibling;
-    end; // with Bitmap do
-  end; // while Assigned(Current) do
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function ReadMatEntryChunk(Source: TFile3DS; MatEntry: PChunk3DS): TMaterial3DS;
-
-var
-  Current, DataChunk, Color: PChunk3DS;
-  MatColor: PFColor3DS;
-
-begin
-  if MatEntry^.Tag <> MAT_ENTRY then
-    ShowError(strError3DS_INVALID_CHUNK);
-  InitMaterial(Result);
-
-  with Result do
-  begin
-    Current := MatEntry^.Children;
-    while Assigned(Current) do
-    begin
-      if (Current^.Tag and $FF00) <> $8000 then // ignore xdata
-        case Current^.Tag of
-          MAT_NAME:
-          begin
-            Source.ReadChunkData(Current);
-            NameStr := StrPas(Current^.Data.MatName);
-            FreeChunkData(Current);
-          end;
-          MAT_AMBIENT,
-          MAT_DIFFUSE,
-          MAT_SPECULAR:
-          begin
-            case Current^.Tag of
-              MAT_DIFFUSE:
-                MatColor := @Diffuse;
-              MAT_SPECULAR:
-                MatColor := @Specular;
-              else
-                MatColor := @Ambient; // MAT_AMBIENT
-            end;
-            Color := FindChunk(Current, COLOR_24);
-            if Assigned(color) then
-            begin
-              Source.ReadChunkData(Color);
-              MatColor^.R := Color^.Data.Color24^.Red / 255;
-              MatColor^.G := Color^.Data.Color24^.Green / 255;
-              MatColor^.B := Color^.Data.Color24^.Blue / 255;
-              FreeChunkData(Color);
-            end;
-            Color := FindChunk(Current, COLOR_F);
-            if Assigned(Color) then
-            begin
-              Source.ReadChunkData(Color);
-              MatColor^.R := Color^.Data.ColorF^.Red;
-              MatColor^.G := Color^.Data.ColorF^.Green;
-              MatColor^.B := Color^.Data.ColorF^.Blue;
-              FreeChunkData(Color);
-            end;
-            Color := FindChunk(Current, LIN_COLOR_24);
-            if Assigned(Color) then
-            begin
-              Source.ReadChunkData(Color);
-              MatColor^.R := Color^.Data.LinColor24^.Red / 255;
-              MatColor^.G := Color^.Data.LinColor24^.Green / 255;
-              MatColor^.B := Color^.Data.LinColor24^.Blue / 255;
-              FreeChunkData(Color);
-            end;
-          end;
-          MAT_SHININESS:
-            Shininess := ReadPercentageChunk(Source, Current);
-          MAT_SHIN2PCT:
-            ShinStrength := ReadPercentageChunk(Source, Current);
-          MAT_SHIN3PCT:
-            ; // just skip for now
-          MAT_REFBLUR:
-            Blur := ReadPercentageChunk(Source, Current);
-          MAT_TRANSPARENCY:
-            Transparency := ReadPercentageChunk(Source, Current);
-          MAT_XPFALL:
-            TransFalloff := ReadPercentageChunk(Source, Current);
-          MAT_SELF_ILPCT:
-            SelfIllumPct := ReadPercentageChunk(Source, Current);
-          MAT_WIRE:
-            Shading := stWire;
-          MAT_WIREABS:
-            UseWireAbs := True;
-          MAT_XPFALLIN:
-            Transparency := -Transparency;
-          MAT_WIRESIZE:
-          begin
-            Source.ReadChunkData(Current);
-            WireSize := Current^.Data.MatWireSize^;
-            FreeChunkData(Current);
-          end;
-          MAT_USE_XPFALL:
-            UseFall := True;
-          MAT_USE_REFBLUR:
-            Useblur := True;
-          MAT_SELF_ILLUM:
-            SelfIllum := True;
-          MAT_TWO_SIDE:
-            TwoSided := True;
-          MAT_ADDITIVE:
-            Additive := True;
-          MAT_SHADING:
-          begin
-            Source.ReadChunkData(Current);
-            Shading := TShadeType3DS(Current^.Data.MatShading^);
-            FreeChunkData(Current);
-          end;
-          MAT_FACEMAP:
-            FaceMap := True;
-          MAT_PHONGSOFT:
-            Soften := True;
-          MAT_TEXMAP:
-            GetBitmapChunk(Source, Current, Texture.Map);
-          MAT_TEXMASK:
-            GetBitmapChunk(Source, Current, Texture.Mask);
-          MAT_TEX2MAP:
-            GetBitmapChunk(Source, Current, Texture2.Map);
-          MAT_TEX2MASK:
-            GetBitmapChunk(Source, Current, Texture2.Mask);
-          MAT_OPACMAP:
-            GetBitmapChunk(Source, Current, Opacity.Map);
-          MAT_OPACMASK:
-            GetBitmapChunk(Source, Current, Opacity.Mask);
-          MAT_REFLMAP:
-            GetBitmapChunk(Source, Current, Reflect.Map);
-          MAT_ACUBIC:
-          begin
-            Source.ReadChunkData(Current);
-            Reflect.UseAuto := True;
-            Reflect.AutoMap.FirstFrame :=
-              (Current^.Data.MatAcubic^.Flags and ACubicFirst3DS) <> 0;
-            Reflect.AutoMap.Flat :=
-              (Current^.Data.MatAcubic^.Flags and ACubicFlat3DS) <> 0;
-            Reflect.AutoMap.Size := Current^.Data.MatAcubic^.MapSize;
-            Reflect.AutoMap.nthFrame := Current^.Data.MatAcubic^.FrameInterval;
-            FreeChunkData(Current);
-          end;
-          MAT_REFLMASK:
-            GetBitmapChunk(Source, Current, Reflect.Mask);
-          MAT_BUMPMAP:
-          begin
-            GetBitmapChunk(Source, Current, Bump.Map);
-            DataChunk := FindChunk(Current, MAT_BUMP_PERCENT);
-            if Assigned(DataChunk) then
-            begin
-              Source.ReadChunkData(DataChunk);
-              Bump.Map.Percent := DataChunk^.Data.MatBumpPercent^ / 100;
-              FreeChunkData(DataChunk);
-            end;
-          end;
-          MAT_BUMPMASK:
-            GetBitmapChunk(Source, Current, Bump.Mask);
-          MAT_SPECMAP:
-            GetBitmapChunk(Source, Current, SpecMap.Map);
-          MAT_SPECMASK:
-            GetBitmapChunk(Source, Current, SpecMap.Mask);
-          MAT_SHINMAP:
-            GetBitmapChunk(Source, Current, ShinMap.Map);
-          MAT_SHINMASK:
-            GetBitmapChunk(Source, Current, Shinmap.Mask);
-          MAT_SELFIMAP:
-            GetBitmapChunk(Source, Current, IllumMap.Map);
-          MAT_SELFIMASK:
-            GetBitmapChunk(Source, Current, IllumMap.Mask);
-          MAT_SXP_TEXT_DATA:
-          begin
-            Source.ReadChunkData(Current);
-            Texture.Map.DataSize := Current^.Data.IpasData^.Size;
-            Texture.Map.Data := Current^.Data.IpasData^.Data;
-            // avoid releasing the data memory
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_TEXT_MASKDATA:
-          begin
-            Source.ReadChunkData(Current);
-            Texture.Mask.DataSize := Current^.Data.IpasData^.Size;
-            Texture.Mask.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_TEXT2_DATA:
-          begin
-            Source.ReadChunkData(Current);
-            Texture2.Map.DataSize := Current^.Data.IpasData^.Size;
-            Texture2.Map.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_TEXT2_MASKDATA:
-          begin
-            Source.ReadChunkData(Current);
-            Texture2.Mask.DataSize := Current^.Data.IpasData^.Size;
-            Texture2.Mask.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_OPAC_DATA:
-          begin
-            Source.ReadChunkData(Current);
-            Opacity.Map.DataSize := Current^.Data.IpasData^.Size;
-            Opacity.Map.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_OPAC_MASKDATA:
-          begin
-            Source.ReadChunkData(Current);
-            Opacity.Mask.DataSize := Current^.Data.IpasData^.Size;
-            Opacity.Mask.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_REFL_MASKDATA:
-          begin
-            Source.ReadChunkData(Current);
-            Reflect.Mask.DataSize := Current^.Data.IpasData^.Size;
-            Reflect.Mask.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_BUMP_DATA:
-          begin
-            Source.ReadChunkData(Current);
-            Bump.Map.DataSize := Current^.Data.IpasData^.Size;
-            Bump.Map.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_BUMP_MASKDATA:
-          begin
-            Source.ReadChunkData(Current);
-            Bump.Mask.DataSize := Current^.Data.IpasData^.Size;
-            Bump.Mask.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_SPEC_DATA:
-          begin
-            Source.ReadChunkData(Current);
-            SpecMap.Map.DataSize := Current^.Data.IpasData^.Size;
-            SpecMap.Map.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_SPEC_MASKDATA:
-          begin
-            Source.ReadChunkData(Current);
-            Specmap.Mask.DataSize := Current^.Data.IpasData^.Size;
-            Specmap.Mask.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_SHIN_DATA:
-          begin
-            Source.ReadChunkData(Current);
-            ShinMap.Map.DataSize := Current^.Data.IpasData^.Size;
-            ShinMap.Map.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_SHIN_MASKDATA:
-          begin
-            Source.ReadChunkData(Current);
-            ShinMap.Mask.DataSize := Current^.Data.IpasData^.Size;
-            ShinMap.Mask.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_SELFI_DATA:
-          begin
-            Source.ReadChunkData(Current);
-            IllumMap.Map.DataSize := Current^.Data.IpasData^.Size;
-            IllumMap.Map.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_SXP_SELFI_MASKDATA:
-          begin
-            Source.ReadChunkData(Current);
-            IllumMap.Mask.DataSize := Current^.Data.IpasData^.Size;
-            IllumMap.Mask.Data := Current^.Data.IpasData^.Data;
-            Current^.Data.IpasData^.Data := nil;
-            FreeChunkData(Current);
-          end;
-          MAT_DECAL:
-            ; // don't know what do to with it
-          else
-            ShowError(strError3DS_INVALID_CHUNK)
-        end;
-      Current := Current^.Sibling;
-    end; // while Assigned(Current) do
-  end; // with Result do
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetChunkValue(Tag: word): integer;
-
-  // Computes a chunk weighting used to determine proper chunk order,
-  // higher values appear earlier in the parent than lower values
-
-begin
-  // only chunks where an explicit order matters are handled
-  Result := 0;
-
-  case Tag of
-    NULL_CHUNK:
-      Inc(Result); // These should just be ignored
-    SMAGIC:
-      Inc(Result, 2);
-    LMAGIC:
-      Inc(Result, 3);
-    M3DMAGIC:
-      Inc(Result, 4);
-    M3D_VERSION:
-      Inc(Result, 5);
-    MDATA:
-      Inc(Result, 6);
-    KFDATA:
-      Inc(Result, 7);
-    COLOR_24:
-      Inc(Result, 8);
-    LIN_COLOR_24:
-      Inc(Result, 9);
-    MESH_VERSION:
-      Inc(Result, 10);
-    MAT_ENTRY:
-      Inc(Result, 11);
-    KFHDR:
-      Inc(Result, 12);
-    MASTER_SCALE:
-      Inc(Result, 13);
-    VIEWPORT_LAYOUT:
-      Inc(Result, 14);
-    LO_SHADOW_BIAS:
-      Inc(Result, 15);
-    SHADOW_MAP_SIZE:
-      Inc(Result, 16);
-    SHADOW_FILTER:
-      Inc(Result, 17);
-    RAY_BIAS:
-      Inc(Result, 18);
-    O_CONSTS:
-      Inc(Result, 19);
-    AMBIENT_LIGHT:
-      Inc(Result, 20);
-    SOLID_BGND:
-      Inc(Result, 21);
-    BIT_MAP:
-      Inc(Result, 22);
-    V_GRADIENT:
-      Inc(Result, 23);
-    USE_BIT_MAP:
-      Inc(Result, 24);
-    USE_SOLID_BGND:
-      Inc(Result, 25);
-    USE_V_GRADIENT:
-      Inc(Result, 26);
-    FOG:
-      Inc(Result, 27);
-    LAYER_FOG:
-      Inc(Result, 28);
-    DISTANCE_CUE:
-      Inc(Result, 29);
-    DEFAULT_VIEW:
-      Inc(Result, 30);
-    NAMED_OBJECT:
-      Inc(Result, 31);
-    KFSEG:
-      Inc(Result, 32);
-    KFCURTIME:
-      Inc(Result, 33);
-    TARGET_NODE_TAG,
-    L_TARGET_NODE_TAG,
-    OBJECT_NODE_TAG,
-    CAMERA_NODE_TAG,
-    SPOTLIGHT_NODE_TAG:
-      Inc(Result, 34);
-    AMBIENT_NODE_TAG:
-      Inc(Result, 35);
-    N_TRI_OBJECT,
-    N_CAMERA,
-    N_DIRECT_LIGHT:
-      Inc(Result);
-    OBJ_HIDDEN:
-      Inc(Result);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetMaterialByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: integer): TMaterial3DS;
-
-var
-  Chunk: PChunk3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  Chunk := FindMatEntryByIndex(Source, DB, Index);
-  if Assigned(Chunk) then
-    Result := ReadMatEntryChunk(Source, Chunk)
-  else
-    ShowErrorFormatted(strError3DS_INVALID_INDEX, [Index]);
-end;
-
-//----------------- mesh object handling ------------------------------------------------------------------------------
-
-function GetMeshCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-
-  // returns the number of mesh objects referenced in the chunk list
-
-var
-  I: integer;
-  Chunk: PChunk3DS;
-
-begin
-  // update the index to named objects if the list has changed recently
-  UpdateNamedObjectList(Source, DB);
-
-  Result := 0;
-  if DB.ObjList = nil then
-    Exit;
-
-  // scan through the list of named objects
-  for I := 0 to DB.ObjList^.Count - 1 do
-  begin
-    Chunk := FindChunk(DB.ObjList^.List^[I].Chunk, N_TRI_OBJECT);
-    if Assigned(Chunk) then
-      Inc(Result);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetMeshMatCount(Current: PChunk3DS): integer;
-
-  // aids the GetMeshEntryChunk3DS in determining
-  // how many materials are defined within the mesh object
-
-var
-  Chunk: PChunk3DS;
-
-begin
-  Result := 0;
-  Chunk := FindChunk(Current, MSH_MAT_GROUP);
-  while Assigned(Chunk) do
-  begin
-    Chunk := FindNextChunk(Chunk^.Sibling, MSH_MAT_GROUP);
-    Inc(Result);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure RelMeshObjField(var Mesh: TMesh3DS; Field: integer);
-
-var
-  I: integer;
-
-begin
-  if ((Field and RelVertexArray3DS) <> 0) and Assigned(Mesh.VertexArray) then
-  begin
-    FreeMem(Mesh.VertexArray);
-    Mesh.VertexArray := nil;
-  end;
-
-  if ((Field and RelTextArray3DS) <> 0) and Assigned(Mesh.TextArray) then
-  begin
-    FreeMem(Mesh.TextArray);
-    Mesh.TextArray := nil;
-  end;
-
-  if ((Field and RelFaceArray3DS) <> 0) and Assigned(Mesh.FaceArray) then
-  begin
-    FreeMem(Mesh.FaceArray);
-    Mesh.FaceArray := nil;
-  end;
-
-  if ((Field and RelMatArray3DS) <> 0) and Assigned(Mesh.MatArray) then
-  begin
-    for I := 0 to Mesh.NMats - 1 do
-    begin
-      // name is always assigned
-      Mesh.MatArray^[I].NameStr := '';
-      if Assigned(Mesh.MatArray^[I].FaceIndex) then
-      begin
-        FreeMem(Mesh.MatArray^[I].FaceIndex);
-        Mesh.MatArray^[I].FaceIndex := nil;
-      end;
-    end;
-    FreeMem(Mesh.MatArray);
-    Mesh.MatArray := nil;
-  end;
-
-  if ((Field and RelSmoothArray3DS) <> 0) and Assigned(Mesh.SmoothArray) then
-  begin
-    FreeMem(Mesh.SmoothArray);
-    Mesh.SmoothArray := nil;
-  end;
-
-  if ((Field and RelProcData3DS) <> 0) and Assigned(Mesh.ProcData) then
-  begin
-    FreeMem(Mesh.ProcData);
-    Mesh.ProcData := nil;
-  end;
-
-  if ((Field and RelVFlagArray3DS) <> 0) and Assigned(Mesh.VFlagArray) then
-  begin
-    FreeMem(Mesh.VFlagArray);
-    Mesh.VFlagArray := nil;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure InitMeshObjField(var aMesh: TMesh3DS; Field: integer);
-
-var
-  I: integer;
-
-begin
-  with aMesh do
-  begin
-    // test to see if Vertices are being allocated
-    if (Field and InitVertexArray3DS) <> 0 then
-    begin
-      // if the vertex count is 0 then free the array
-      if NVertices = 0 then
-        RelMeshObjField(aMesh, RelVertexArray3DS)
-      else
-      begin
-        // if this is the very first allocation
-        if VertexArray = nil then
-        begin
-          // allocate the new block of memory
-          VertexArray := AllocMem(NVertices * SizeOf(TPoint3DS));
-          if VertexArray = nil then
-            ShowError(strError3DS_NO_MEM);
-
-          // this is done by AllocMem already
-          // initialize the new block
-          //for I := 0 to NVertices - 1 do VertexArray[I] := DefPoint3DS;
-        end
-        else // else this is an existing block
-        begin
-          // just resize it
-          ReallocMem(VertexArray, SizeOf(TPoint3DS) * NVertices);
-          if VertexArray = nil then
-            ShowError(strError3DS_NO_MEM);
-        end;
-      end;
-    end;
-
-    if (Field and InitTextArray3DS) <> 0 then
-    begin
-      if NTextVerts = 0 then
-        RelMeshObjField(aMesh, RelTextArray3DS)
-      else
-      begin
-        if TextArray = nil then
-        begin
-          TextArray := Allocmem(NTextVerts * SizeOf(TTexVert3DS));
-          if TextArray = nil then
-            ShowError(strError3DS_NO_MEM);
-
-          for I := 0 to NTextVerts - 1 do
-            TextArray^[I] := DefTextVert3DS;
-        end
-        else
-        begin
-          Reallocmem(TextArray, SizeOf(TTexVert3DS) * NTextVerts);
-          if TextArray = nil then
-            ShowError(strError3DS_NO_MEM);
-        end;
-      end;
-    end;
-
-    if (Field and InitFaceArray3DS) <> 0 then
-    begin
-      if NFaces = 0 then
-        RelMeshObjField(aMesh, RelFaceArray3DS)
-      else
-      begin
-        if FaceArray = nil then
-        begin
-          FaceArray := AllocMem(NFaces * SizeOf(TFace3DS));
-          if FaceArray = nil then
-            ShowError(strError3DS_NO_MEM);
-
-          for I := 0 to NFaces - 1 do
-            FaceArray^[I] := DefFace3DS;
-        end
-        else
-        begin
-          ReallocMem(FaceArray, SizeOf(TFace3DS) * NFaces);
-          if FaceArray = nil then
-            ShowError(strError3DS_NO_MEM);
-        end;
-      end;
-    end;
-
-    if (Field and InitMatArray3DS) <> 0 then
-    begin
-      if NMats = 0 then
-        RelMeshObjField(aMesh, RelMatArray3DS)
-      else
-      begin
-        if Matarray = nil then
-        begin
-          MatArray := AllocMem(NMats * SizeOf(TObjmat3DS));
-          if MatArray = nil then
-            ShowError(strError3DS_NO_MEM);
-
-          for I := 0 to NMats - 1 do
-            MatArray^[I] := DefObjMat3DS;
-        end
-        else
-        begin
-          ReallocMem(MatArray, SizeOf(TObjmat3DS) * NMats);
-          if MatArray = nil then
-            ShowError(strError3DS_NO_MEM);
-        end;
-      end;
-    end;
-
-    if (Field and InitSmoothArray3DS) <> 0 then
-    begin
-      if NFaces = 0 then
-        RelMeshObjField(aMesh, RelSmoothArray3DS)
-      else
-      begin
-        if SmoothArray = nil then
-        begin
-          SmoothArray := AllocMem(NFaces * SizeOf(integer));
-          if SmoothArray = nil then
-            ShowError(strError3DS_NO_MEM);
-
-          // done by AllocMem
-          // for I := 0 to NFaces - 1 do SmoothArray[I] := 0;
-        end
-        else
-        begin
-          ReallocMem(SmoothArray, SizeOf(integer) * NFaces);
-          if SmoothArray = nil then
-            ShowError(strError3DS_NO_MEM);
-        end;
-      end;
-    end;
-
-    if (Field and InitProcData3DS) <> 0 then
-    begin
-      if ProcSize = 0 then
-        RelMeshObjField(aMesh, RelProcData3DS)
-      else
-      begin
-        if ProcData = nil then
-        begin
-          ProcData := AllocMem(ProcSize * SizeOf(byte));
-          if ProcData = nil then
-            ShowError(strError3DS_NO_MEM);
-        end
-        else
-        begin
-          ReallocMem(ProcData, SizeOf(byte) * ProcSize);
-          if ProcData = nil then
-            ShowError(strError3DS_NO_MEM);
-        end;
-      end;
-    end;
-
-    if (Field and InitVFlagArray3DS) <> 0 then
-    begin
-      if NVertices = 0 then
-        RelMeshObjField(aMesh, RelVFlagArray3DS)
-      else
-      begin
-        if VFlagArray = nil then
-        begin
-          VFlagArray := AllocMem(NVertices * SizeOf(word));
-          if VFlagArray = nil then
-            ShowError(strError3DS_NO_MEM);
-        end
-        else
-        begin
-          ReallocMem(VFlagArray, SizeOf(word) * NVertices);
-          if VFlagArray = nil then
-            ShowError(strError3DS_NO_MEM);
-        end;
-      end;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function InitMeshObj(VertexCount, FaceCount, InitFlags: word): TMesh3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-  with Result do
-  begin
-    NVertices := VertexCount;
-    Map.TileX := 1;
-    Map.TileY := 1;
-    Map.Scale := 1;
-    Map.Matrix[0] := 1;
-    Map.Matrix[4] := 1;
-    Map.PW := 1;
-    Map.PH := 1;
-    Map.CH := 1;
-
-    NFaces := FaceCount;
-
-    InitMeshObjField(Result, InitVertexArray3DS or InitFaceArray3DS);
-
-    if (InitFlags and InitTextArray3DS) <> 0 then
-    begin
-      NTextVerts := VertexCount;
-      InitMeshObjField(Result, InitTextArray3DS);
-    end;
-
-    if (InitFlags and InitVFlagArray3DS) <> 0 then
-    begin
-      NVFlags := VertexCount;
-      InitMeshObjField(Result, InitVFlagArray3DS);
-    end;
-
-    if (InitFlags and InitSmoothArray3DS) <> 0 then
-      InitMeshObjField(Result, InitSmoothArray3DS);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ReleaseMeshObj(Mesh: PMesh3DS);
-
-begin
-  if Assigned(Mesh) then
-  begin
-    RelMeshObjField(Mesh^, RelAll3DS);
-    Dispose(Mesh);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetMeshEntryChunk(const Source: TFile3DS; Chunk: PChunk3DS): TMesh3DS;
-
-var
-  NTriChunk, FaceArrayChunk, DataChunk, Current: PChunk3DS;
-  I: integer;
-
-begin
-  NTriChunk := FindNextChunk(Chunk^.Children, N_TRI_OBJECT);
-  if NTriChunk = nil then
-    ShowError(strError3DS_WRONG_OBJECT);
-
-  Result := InitMeshObj(0, 0, 0);
-
-  with Result do
-  begin
-    // get the mesh name
-    Source.ReadChunkData(Chunk);
-    NameStr := StrPas(Chunk^.Data.NamedObject);
-
-    Current := NTriChunk^.Children;
-    while Assigned(Current) do
-    begin
-      case Current^.Tag of
-        POINT_ARRAY:
-        begin
-          Source.ReadChunkData(Current);
-          NVertices := Current^.Data.PointArray^.Vertices;
-          VertexArray := Current^.Data.PointArray^.PointList;
-          // avoid freeing the just allocated memory
-          Current^.Data.PointArray^.PointList := nil;
-          FreeChunkData(Current);
-        end;
-        POINT_FLAG_ARRAY:
-        begin
-          Source.ReadChunkData(Current);
-          NVFlags := Current^.Data.PointFlagArray^.Flags;
-          VFlagArray := Current^.Data.PointFlagArray^.FlagList;
-          Current^.Data.PointFlagArray^.FlagList := nil;
-          FreeChunkData(Current);
-        end;
-        FACE_ARRAY:
-        begin
-          Source.ReadChunkData(Current);
-          NFaces := Current^.Data.FaceArray^.Faces;
-          FaceArray := Current^.Data.FaceArray^.FaceList;
-          Current^.Data.FaceArray^.FaceList := nil;
-
-          if Assigned(Current^.Children) then
-          begin
-            // begin search for MESH_MAT_GROUP and SMOOTH_GROUP
-            FaceArrayChunk := Current;
-
-            // create a list of all mesh mat groups
-            DataChunk := FindChunk(FaceArrayChunk, MSH_MAT_GROUP);
-            if Assigned(DataChunk) then
-            begin
-              NMats := GetMeshMatCount(DataChunk);
-              MatArray := AllocMem(NMats * SizeOf(TObjMat3DS));
-
-              for I := 0 to NMats - 1 do
-              begin
-                Source.ReadChunkData(DataChunk);
-                MatArray^[I].NameStr := DataChunk^.Data.MshMatGroup^.MatNameStr;
-                MatArray^[I].NFaces := DataChunk^.Data.MshMatGroup^.Faces;
-                MatArray^[I].FaceIndex := DataChunk^.Data.MshMatGroup^.FaceList;
-                DataChunk^.Data.MshMatGroup^.FaceList := nil;
-                FreeChunkData(DataChunk);
-                DataChunk := FindNextChunk(DataChunk^.Sibling, MSH_MAT_GROUP);
-              end;
-            end;
-
-            DataChunk := FindNextChunk(FaceArrayChunk^.Children, SMOOTH_GROUP);
-            if Assigned(DataChunk) then
-            begin
-              Source.ReadChunkData(DataChunk);
-              SmoothArray := DataChunk^.Data.SmoothGroup^.GroupList;
-              DataChunk^.Data.SmoothGroup^.GroupList := nil;
-              FreeChunkData(DataChunk);
-            end;
-
-            DataChunk := FindNextChunk(FaceArrayChunk^.Children, MSH_BOXMAP);
-            if Assigned(DataChunk) then
-            begin
-              Source.ReadChunkData(DataChunk);
-              for I := 0 to 5 do
-                BoxMapStr[I] := string(DataChunk^.Data.MshBoxmap^[I]);
-              UseBoxmap := True;
-              FreeChunkData(DataChunk);
-            end;
-          end;
-          FreeChunkData(Current);
-        end;
-        TEX_VERTS:
-        begin
-          Source.ReadChunkData(Current);
-          ntextverts := Current^.Data.TexVerts^.NumCoords;
-          TextArray := Current^.Data.TexVerts^.TextVertList;
-          Current^.Data.TexVerts^.TextVertList := nil;
-          FreeChunkData(Current);
-        end;
-        MESH_MATRIX:
-        begin
-          Source.ReadChunkData(Current);
-          LocMatrix := Current^.Data.MeshMatrix^;
-          FreeChunkData(Current);
-        end;
-        MESH_TEXTURE_INFO:
-        begin
-          UseMapInfo := True;
-          Source.ReadChunkData(Current);
-          Map.MapType := Current^.Data.MeshTextureInfo^.MapType;
-          Map.TileX := Current^.Data.MeshTextureInfo^.XTiling;
-          Map.TileY := Current^.Data.MeshTextureInfo^.YTiling;
-          Map.CenX := Current^.Data.MeshTextureInfo^.IconPos.X;
-          Map.CenY := Current^.Data.MeshTextureInfo^.IconPos.Y;
-          Map.CenZ := Current^.Data.MeshTextureInfo^.IconPos.Z;
-          Map.Scale := Current^.Data.MeshTextureInfo^.IconScaling;
-          Map.Matrix := Current^.Data.MeshTextureInfo^.XMatrix;
-          Map.PW := Current^.Data.MeshTextureInfo^.IconWidth;
-          Map.PH := Current^.Data.MeshTextureInfo^.IconHeight;
-          Map.CH := Current^.Data.MeshTextureInfo^.CylIconHeight;
-          FreeChunkData(Current);
-        end;
-        PROC_NAME:
-        begin
-          Source.ReadChunkData(Current);
-          ProcNameStr := string(StrPas(Current^.Data.ProcName));
-          FreeChunkData(Current);
-        end;
-        PROC_DATA:
-        begin
-          Source.ReadChunkData(Current);
-          ProcSize := Current^.Data.IpasData^.Size;
-          ProcData := Current^.Data.IpasData^.Data;
-          Current^.Data.IpasData^.Data := nil;
-          FreeChunkData(Current);
-        end;
-        MESH_COLOR:
-        begin
-          Source.ReadChunkData(Current);
-          MeshColor := Current^.Data.MeshColor^;
-          FreeChunkData(Current);
-        end;
-      end;
-      Current := Current^.Sibling;
-    end;
-
-    IsHidden := Assigned(FindNextChunk(Chunk^.Children, OBJ_HIDDEN));
-    IsVisLofter := Assigned(FindNextChunk(Chunk^.Children, OBJ_VIS_LOFTER));
-    IsNoCast := Assigned(FindNextChunk(Chunk^.Children, OBJ_DOESNT_CAST));
-    IsMatte := Assigned(FindNextChunk(Chunk^.Children, OBJ_MATTE));
-    IsFast := Assigned(FindNextChunk(Chunk^.Children, OBJ_FAST));
-    IsFrozen := Assigned(FindNextChunk(Chunk^.Children, OBJ_FROZEN));
-    IsNoRcvShad := Assigned(FindNextChunk(Chunk^.Children, OBJ_DONT_RCVSHADOW));
-    UseProc := Assigned(FindNextChunk(Chunk^.Children, OBJ_PROCEDURAL));
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetMeshByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: integer): TMesh3DS;
-
-  // fills a mesh structure from the (index)th mesh reference found in DB
-
-var
-  Current: PChunk3DS;
-  I, Count: integer;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  if DB.TopChunk = nil then
-    ShowError(strError3DS_INVALID_DATABASE);
-  if (DB.TopChunk^.Tag <> M3DMAGIC) and (DB.TopChunk^.Tag <> CMAGIC) then
-    ShowError(strError3DS_WRONG_DATABASE);
-
-  // update the index to named objects if the list has changed recently
-  UpdateNamedObjectList(Source, DB);
-
-  // scan through the list of named objects
-  Count := 0;
-  for I := 0 to DB.ObjList^.Count - 1 do
-  begin
-    // search each named object for a mesh chunk
-    Current := FindChunk(DB.ObjList^.List^[I].Chunk, N_TRI_OBJECT);
-
-    // if a mesh chunk is found
-    if Assigned(Current) then
-    begin
-      // increment the running total
-      Inc(Count);
-      // if this is the (index)th mesh, fill out the structure
-      if (Count - 1) = Index then
-      begin
-        Result := GetMeshEntryChunk(Source, DB.ObjList^.List^[I].Chunk);
-        Break;
-      end;
-    end;
-  end;
-end;
-
-//----------------- spot and omni light handling ----------------------------------------------------------------------
-
-function GetOmnilightCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-
-var
-  DLite, SpotL: PChunk3DS;
-  I: integer;
-
-begin
-  // update the index to named objects if the list has changed recently
-  UpdateNamedObjectList(Source, DB);
-
-  Result := 0;
-  if DB.ObjList = nil then
-    Exit;
-
-  // scan through the list of named objects looking for lights
-  for I := 0 to DB.ObjList^.Count - 1 do
-  begin
-    // search each object for a Light chunk
-    DLite := FindChunk(DB.ObjList^.List^[I].chunk, N_DIRECT_LIGHT);
-
-    // if one was found, check to see if its a spotlight
-    if Assigned(DLite) then
-    begin
-      SpotL := FindChunk(DLite, DL_SPOTLIGHT);
-      // if it isn't a spotlight then increment the count
-      if SpotL = nil then
-        Inc(Result);
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetSpotlightCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-
-var
-  DLite, SpotL: PChunk3DS;
-  I: integer;
-
-begin
-  // update the index to named objects if the list has changed recently
-  UpdateNamedObjectList(Source, DB);
-
-  Result := 0;
-  if DB.ObjList = nil then
-    Exit;
-
-  // scan through the list of named objects looking for lights
-  for I := 0 to DB.ObjList^.Count - 1 do
-  begin
-    // search each object for a Light chunk
-    DLite := FindChunk(DB.ObjList^.List^[I].Chunk, N_DIRECT_LIGHT);
-
-    // if one was found, check to see if its a spotlight
-    if Assigned(DLite) then
-    begin
-      SpotL := FindChunk(DLite, DL_SPOTLIGHT);
-      // if it is a spotlight then increment the count
-      if Assigned(SpotL) then
-        Inc(Result);
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure InitLight(var Light: TLight3DS);
-
-// Initializes the Light structure
-
-begin
-  FillChar(Light, SizeOf(Light), 0);
-  with Light do
-  begin
-    NameStr := '';
-    Color.R := 0.708852;
-    Color.G := 0.708852;
-    Color.B := 0.708852;
-    Multiplier := 1;
-    Attenuation.Inner := 10;
-    Attenuation.Outer := 100;
-    Exclude := TStringList.Create;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ReleaseLight(Light: PLight3DS);
-
-begin
-  Light^.Exclude.Free;
-  Light^.Exclude := nil;
-  if Assigned(Light^.Spot) then
-  begin
-    Light^.Spot^.Projector.BitmapStr := '';
-    FreeMem(Light^.Spot);
-  end;
-  Dispose(Light);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure InitSpotLight(var SpotLight: TLight3DS);
-
-begin
-  // do the common Light initialization
-  InitLight(SpotLight);
-  SpotLight.Spot := AllocMem(SizeOf(TSpotLight3DS));
-
-  with SpotLight.Spot^ do
-  begin
-    Target.X := 1;
-    Target.Y := 1;
-    Target.Z := 1;
-    Hotspot := 44;
-    Falloff := 45;
-    Aspect := 1;
-
-    Shadows.AType := ssUseShadowMap;
-    Shadows.Bias := 1;
-    Shadows.Filter := 3;
-    Shadows.Mapsize := 512;
-    Shadows.RayBias := 1;
-
-    Cone.AType := csCircular;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetLightEntryChunk(const Source: TFile3DS; Chunk: PChunk3DS): TLight3DS;
-
-  // fills out the given Light structure with the Light pointed to by Chunk
-
-var
-  DLite, SpotChunk, Current: PChunk3DS;
-
-begin
-  DLite := FindNextChunk(Chunk^.Children, N_DIRECT_LIGHT);
-  if DLite = nil then
-    ShowError(strError3DS_WRONG_OBJECT);
-
-  DLite := FindChunk(Chunk^.Children, N_DIRECT_LIGHT);
-  SpotChunk := FindChunk(Chunk, DL_SPOTLIGHT);
-
-  if Assigned(DLite) then
-    with Result do
-    begin
-      // initilize Light
-      if SpotChunk = nil then
-        InitLight(Result)
-      else
-        InitSpotLight(Result);
-
-      // read object name
-      Source.ReadChunkData(Chunk);
-      NameStr := StrPas(Chunk^.Data.NamedObject);
-      FreeChunkData(Chunk);
-
-      // read Light postion
-      Source.ReadChunkData(DLite);
-      Pos := DLite^.Data.NDirectLight^;
-
-      // scan all the chunks the Light contains
-      Current := DLite^.Children;
-      while Assigned(Current) do
-      begin
-        case Current^.Tag of
-          COLOR_F:
-          begin
-            Source.ReadChunkData(Current);
-            Color.R := Current^.Data.ColorF^.Red;
-            Color.G := Current^.Data.ColorF^.Green;
-            Color.B := Current^.Data.ColorF^.Blue;
-            FreeChunkData(Current);
-          end;
-          COLOR_24:
-          begin
-            Source.ReadChunkData(Current);
-            Color.R := Current^.Data.Color24^.Red / 255;
-            Color.G := Current^.Data.Color24^.Green / 255;
-            Color.B := Current^.Data.Color24^.Blue / 255;
-            FreeChunkData(Current);
-          end;
-          DL_MULTIPLIER:
-          begin
-            Source.ReadChunkData(Current);
-            Multiplier := Current^.Data.DlMultiplier^;
-            FreeChunkData(Current);
-          end;
-          DL_INNER_RANGE:
-          begin
-            Source.ReadChunkData(Current);
-            // assuming since there is a value it is on
-            Attenuation.Inner := Current^.Data.DlInnerRange^;
-            FreeChunkData(Current);
-          end;
-          DL_OUTER_RANGE:
-          begin
-            Source.ReadChunkData(Current);
-            // assuming since there is a value it is on
-            Attenuation.Outer := Current^.Data.DlOuterRange^;
-            FreeChunkData(Current);
-          end;
-          DL_EXCLUDE:
-          begin
-            Source.ReadChunkData(Current);
-            Exclude.Add(string(Current^.Data.DlExclude^));
-            FreeChunkData(Current);
-          end;
-          DL_OFF:
-            DLOff := True;
-          DL_ATTENUATE:
-            Attenuation.IsOn := True;
-        end;
-        Current := Current^.Sibling;
-      end;
-
-      // DL_SPOTLIGHT chunk
-      if Assigned(SpotChunk) then
-      begin
-        // read spotlight data
-        Source.ReadChunkData(SpotChunk);
-        Spot^.Target := SpotChunk^.Data.DlSpotlight^.SpotLightTarg;
-        Spot^.Hotspot := SpotChunk^.Data.DlSpotlight^.HotspotAngle;
-        Spot^.Falloff := SpotChunk^.Data.DlSpotlight^.FalloffAngle;
-
-        // scan all the chunks the spotlight contains
-        Current := SpotChunk^.Children;
-        while Assigned(Current) do
-        begin
-          case Current^.Tag of
-            DL_SPOT_ROLL:
-            begin
-              Source.ReadChunkData(Current);
-              Spot^.Roll := Current^.Data.DlSpotRoll^;
-              FreeChunkData(Current);
-            end;
-            DL_LOCAL_SHADOW:
-              Spot^.Shadows.Cast := True;
-            DL_LOCAL_SHADOW2:
-            begin
-              Source.ReadChunkData(Current);
-              Spot^.Shadows.Bias := Current^.Data.DlLocalShadow2^.LocalShadowBias;
-              Spot^.Shadows.Filter := Current^.Data.DlLocalShadow2^.LocalShadowFilter;
-              Spot^.Shadows.Mapsize :=
-                Current^.Data.DlLocalShadow2^.LocalShadowMapSize;
-              Spot^.Shadows.Local := True;
-              FreeChunkData(Current);
-            end;
-            DL_SHADOWED:
-              Spot^.Shadows.Cast := True;
-            DL_SPOT_RECTANGULAR:
-              Spot^.Cone.AType := csRectangular;
-            DL_SEE_CONE:
-              Spot^.Cone.Show := True;
-            DL_SPOT_OVERSHOOT:
-              Spot^.Cone.Overshoot := True;
-            DL_SPOT_ASPECT:
-            begin
-              Source.ReadChunkData(Current);
-              Spot^.Aspect := Current^.Data.DlSpotAspect^;
-              FreeChunkData(Current);
-            end;
-            DL_RAY_BIAS:
-            begin
-              Source.ReadChunkData(Current);
-              Spot^.Shadows.RayBias := Current^.Data.DlRayBias^;
-              FreeChunkData(Current);
-            end;
-            DL_RAYSHAD:
-              Spot^.Shadows.AType := ssUseRayTraceShadow;
-            DL_SPOT_PROJECTOR:
-            begin
-              Source.ReadChunkData(Current);
-              Spot^.Projector.BitmapStr :=
-                string(StrPas(Current^.Data.DlSpotProjector));
-              Spot^.Projector.Use := True;
-              FreeChunkData(Current);
-            end;
-          end;
-          Current := Current^.Sibling;
-        end;
-      end;
-    end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetOmnilightByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: integer): TLight3DS;
-
-  // fills out the omnilight structure from the (index)th mesh reference found in DB
-
-var
-  LightChunk, SpotChunk: PChunk3DS;
-  I, Count: integer;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  if (DB.TopChunk = nil) then
-    ShowError(strError3DS_INVALID_DATABASE);
-  if not (DB.TopChunk^.Tag = M3DMAGIC) and not (DB.TopChunk^.Tag = CMAGIC) then
-    ShowError(strError3DS_WRONG_DATABASE);
-
-  // update the list if it's changed recently
-  UpdateNamedObjectList(Source, DB);
-
-  // Scan through the List
-  Count := 0;
-  for I := 0 to DB.ObjList^.Count - 1 do
-  begin
-    // search for a Light chunk
-    LightChunk := FindChunk(DB.ObjList^.List^[I].Chunk, N_DIRECT_LIGHT);
-
-    // if one was found check to see if its a spot
-    if Assigned(LightChunk) then
-    begin
-      SpotChunk := FindChunk(LightChunk, DL_SPOTLIGHT);
-      // if its not a spot then increment the count
-      if SpotChunk = nil then
-      begin
-        Inc(Count);
-        // if this is the (index)th Light file out the structure
-        if (Count - 1) = Index then
-        begin
-          Result := GetLightEntryChunk(Source, DB.ObjList^.List^[I].Chunk);
-          Break;
-        end;
-      end;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetSpotlightByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: integer): TLight3DS;
-
-  // fills out the Spot structure from the (index)th spot reference found in DB
-
-var
-  LightChunk, SpotChunk: PChunk3DS;
-  I, Count: integer;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  if (DB.TopChunk = nil) then
-    ShowError(strError3DS_INVALID_DATABASE);
-  if not (DB.TopChunk^.Tag = M3DMAGIC) and not (DB.TopChunk^.Tag = CMAGIC) then
-    ShowError(strError3DS_WRONG_DATABASE);
-
-  // update the list if it's changed recently
-  UpdateNamedObjectList(Source, DB);
-
-  // Scan through the List
-  Count := 0;
-  for I := 0 to DB.ObjList^.Count - 1 do
-  begin
-    // search for a Light chunk
-    LightChunk := FindChunk(DB.ObjList^.List^[I].Chunk, N_DIRECT_LIGHT);
-
-    // if one was found check to see if its a spot
-    if Assigned(LightChunk) then
-    begin
-      SpotChunk := FindChunk(LightChunk, DL_SPOTLIGHT);
-      // if its not a spot then increment the count
-      if Assigned(SpotChunk) then
-      begin
-        Inc(Count);
-        // if this is the (index)th Light file out the structure
-        if (Count - 1) = Index then
-        begin
-          Result := GetLightEntryChunk(Source, DB.ObjList^.List^[I].Chunk);
-          Break;
-        end;
-      end;
-    end;
-  end;
-end;
-
-//----------------- camera handling -----------------------------------------------------------------------------------
-
-procedure InitCamera(var Camera: TCamera3DS);
-
-begin
-  FillChar(Camera, SizeOf(Camera), 0);
-  with Camera do
-  begin
-    Target.X := 1;
-    Target.Y := 1;
-    Target.Z := 1;
-    FOV := 45;
-    Ranges.CamNear := 10;
-    Ranges.CamFar := 1000;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ReleaseCamera(Camera: PCamera3DS);
-
-begin
-  if Assigned(Camera) then
-  begin
-    Dispose(Camera);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetCameraCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-
-var
-  Chunk: PChunk3DS;
-  I: integer;
-
-begin
-  UpdateNamedObjectList(Source, DB);
-  Result := 0;
-  if Assigned(DB.ObjList) then
-    for I := 0 to DB.ObjList^.Count - 1 do
-    begin
-      Chunk := FindChunk(DB.ObjList^.List^[I].Chunk, N_CAMERA);
-      if Assigned(Chunk) then
-        Inc(Result);
-    end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetCameraEntry(const Source: TFile3DS; Chunk: PChunk3DS): TCamera3DS;
-
-var
-  Current, Camera: PChunk3DS;
-
-begin
-  if Chunk^.Tag <> NAMED_OBJECT then
-    ShowError(strError3DS_WRONG_OBJECT);
-
-  Camera := FindNextChunk(Chunk^.Children, N_CAMERA);
-  if Camera = nil then
-    ShowError(strError3DS_WRONG_OBJECT);
-
-  with Result do
-  begin
-    InitCamera(Result);
-    Camera := FindNextChunk(Chunk^.Children, N_CAMERA);
-
-    Source.ReadChunkData(Chunk);
-    NameStr := StrPas(Chunk^.Data.NamedObject);
-    FreeChunkData(Chunk);
-
-    Source.ReadChunkData(Camera);
-    Position.X := Camera^.Data.NCamera^.CameraPos.X;
-    Position.Y := Camera^.Data.NCamera^.CameraPos.Y;
-    Position.Z := Camera^.Data.NCamera^.CameraPos.Z;
-    Target.X := Camera^.Data.NCamera^.TargetPos.X;
-    Target.Y := Camera^.Data.NCamera^.TargetPos.Y;
-    Target.Z := Camera^.Data.NCamera^.TargetPos.Z;
-    Roll := Camera^.Data.NCamera^.CameraBank;
-    FOV := 2400 / Camera^.Data.NCamera^.CameraFocalLength;
-    FreeChunkData(Camera);
-
-    Current := Camera^.Children;
-    while Assigned(Current) do
-    begin
-      case Current^.Tag of
-        CAM_SEE_CONE:
-          ShowCone := True;
-        CAM_RANGES:
-        begin
-          Source.ReadChunkData(Current);
-          Ranges.CamNear := Current^.Data.CamRanges^.NearPlane;
-          Ranges.CamFar := Current^.Data.CamRanges^.FarPlane;
-          FreeChunkData(Current);
-        end;
-      end;
-      Current := Current^.Sibling;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetCameraByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: integer): TCamera3DS;
-
-var
-  Camera: PChunk3DS;
-  I, Count: integer;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  UpdateNamedObjectList(Source, DB);
-
-  Count := 0;
-  for I := 0 to DB.ObjList^.Count - 1 do
-  begin
-    Camera := FindChunk(DB.ObjList^.List^[I].Chunk, N_CAMERA);
-    if Assigned(Camera) then
-    begin
-      Inc(Count);
-      if (Count - 1) = Index then
-        Result := GetCameraEntry(Source, DB.ObjList^.List^[I].Chunk);
-    end;
-  end;
-end;
-
-//----------------- common animation settings -------------------------------------------------------------------------
-
-procedure InitKfSets(var Key: TKFSets3DS);
-
-begin
-  Key.Anim.Length := 30;
-  Key.Anim.CurFrame := 0;
-  Key.Seg.Use := False;
-  Key.Seg.SegBegin := 0;
-  Key.Seg.SegEnd := 30;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetKFSeg(TopChunk: PChunk3DS): PChunk3DS;
-
-  // all the keyframe information has to go in the appropriate segment KFDATA
-
-begin
-  // look for KFDATA
-  Result := FindNextChunk(TopChunk^.Children, KFDATA);
-  if Result = nil then
-    Result := PutGenericNode(KFDATA, TopChunk);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetKeyInfo(const Source: TFile3DS; var DB: TDatabase3DS): TKFKeyInfo3DS;
-
-var
-  KFData, KFHdrChunk, KFCTChunk: PChunk3DS;
-
-begin
-  KFData := GetKfSeg(DB.TopChunk);
-  KFHdrChunk := FindNextChunk(KFData^.Children, KFHDR);
-
-  if Assigned(KFHdrChunk) then
-  begin
-    Source.ReadChunkData(KFHdrChunk);
-    Result.Length := KFHdrChunk^.Data.KFHdr^.AnimLength;
-    FreeChunkData(KFHdrChunk);
-  end;
-
-  KFCTChunk := FindNextChunk(KFData^.Children, KFCURTIME);
-
-  if Assigned(KFCTChunk) then
-  begin
-    Source.ReadChunkData(KFCTChunk);
-    Result.CurFrame := KFCTChunk^.Data.KFCurTime^;
-    FreeChunkData(KFCTChunk);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetKFSegment(const Source: TFile3DS; var DB: TDatabase3DS): TKFSegment3DS;
-var
-  DataChunk, SegChunk: PChunk3DS;
-begin
-  Result.SegBegin := 0;
-  Result.SegEnd := 0;
-  Result.Use := False;
-
-  DataChunk := GetKFSeg(DB.TopChunk);
-  SegChunk := FindNextChunk(DataChunk^.Children, KFSEG);
-
-  if Assigned(SegChunk) then
-  begin
-    Source.ReadChunkData(SegChunk);
-    Result.Use := True;
-    Result.SegBegin := SegChunk^.Data.KFSeg^.First;
-    Result.SegEnd := SegChunk^.Data.KFSeg^.Last;
-    FreeChunkData(SegChunk);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetKFSettings(const Source: TFile3DS; var DB: TDatabase3DS): TKFSets3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  if DB.TopChunk = nil then
-    ShowError(strError3DS_INVALID_DATABASE);
-  if (DB.TopChunk^.Tag <> M3DMAGIC) and (DB.TopChunk^.Tag <> CMAGIC) then
-    ShowError(strError3DS_WRONG_DATABASE);
-
-  InitKFSets(Result);
-  Result.Anim := GetKeyInfo(Source, DB);
-  Result.Seg := GetKFSegment(Source, DB);
-end;
-
-//----------------- Camera animation ----------------------------------------------------------------------------------
-
-procedure InitCameraMotion(var Camera: TKFCamera3DS;
-  NewNPKeys, NewNFKeys, NewNRKeys, NewNTKeys: cardinal);
-
-var
-  I: integer;
-
-begin
-  with Camera do
-  begin
-    // free any previously allocated memory first
-    if Assigned(PKeys) then
-      FreeMem(PKeys);
-    if Assigned(Pos) then
-      FreeMem(Pos);
-    if Assigned(FKeys) then
-      FreeMem(FKeys);
-    if Assigned(FOV) then
-      FreeMem(FOV);
-    if Assigned(RKeys) then
-      FreeMem(RKeys);
-    if Assigned(Roll) then
-      FreeMem(Roll);
-    if Assigned(TKeys) then
-      FreeMem(TKeys);
-    if Assigned(TPos) then
-      FreeMem(TPos);
-
-    FillChar(Camera, SizeOf(TKFCamera3DS), 0);
-    NPKeys := NewNPKeys;
-    NFKeys := NewNFKeys;
-    NRKeys := NewNRKeys;
-    NTKeys := NewNTKeys;
-
-    if NPKeys <> 0 then
-    begin
-      NPFlag := TrackSingle3DS;
-
-      PKeys := AllocMem(NPKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NPKeys - 1 do
-        PKeys^[I] := DefKeyHeader3DS;
-
-      Pos := AllocMem(NPKeys * SizeOf(TPoint3DS));
-      for I := 0 to NPKeys - 1 do
-        Pos^[I] := DefPoint3DS;
-    end;
-
-    if NFKeys <> 0 then
-    begin
-      NFFlag := TrackSingle3DS;
-
-      FKeys := AllocMem(NFKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NFKeys - 1 do
-        FKeys^[I] := DefKeyHeader3DS;
-
-      FOV := AllocMem(NFKeys * SizeOf(single));
-      for I := 0 to NFKeys - 1 do
-        FOV^[I] := 60;
-    end;
-
-    if NRKeys <> 0 then
-    begin
-      NRFlag := TrackSingle3DS;
-
-      RKeys := AllocMem(NRKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NRKeys - 1 do
-        RKeys^[I] := DefKeyHeader3DS;
-
-      Roll := AllocMem(NRKeys * SizeOf(single));
-    end;
-
-    if NTKeys <> 0 then
-    begin
-      NTFlag := TrackSingle3DS;
-      TFlags1 := 0;
-      TFlags2 := 0;
-
-      TKeys := AllocMem(NTKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NTKeys - 1 do
-        TKeys^[I] := DefKeyHeader3DS;
-
-      TPos := AllocMem(NTKeys * SizeOf(TPoint3DS));
-      for I := 0 to NTKeys - 1 do
-        TPos^[I] := DefPoint3DS;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ReleaseCameraMotion(Camera: PKFCamera3DS);
-
-begin
-  if Assigned(Camera) then
-  begin
-    with Camera^ do
-    begin
-      if Assigned(PKeys) then
-        FreeMem(PKeys);
-      if Assigned(Pos) then
-        FreeMem(Pos);
-      if Assigned(FKeys) then
-        FreeMem(FKeys);
-      if Assigned(FOV) then
-        FreeMem(FOV);
-      if Assigned(RKeys) then
-        FreeMem(RKeys);
-      if Assigned(Roll) then
-        FreeMem(Roll);
-      if Assigned(TKeys) then
-        FreeMem(TKeys);
-      if Assigned(TPos) then
-        FreeMem(TPos);
-    end;
-    Dispose(Camera);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure GetCameraNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
-  List: TStringList);
-
-begin
-  GetGenericNodeNameList(Source, DB, CAMERA_NODE_TAG, List);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetCameraNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-
-begin
-  Result := GetGenericNodeCount(Source, DB, CAMERA_NODE_TAG);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetParentName(const Source: TFile3DS; Chunk: PChunk3DS): string;
-
-  // get parent name if there is one
-
-var
-  NameChunk: PChunk3DS;
-
-begin
-  Result := '';
-  NameChunk := FindChunk(Chunk, PARENT_NAME);
-  if Assigned(NameChunk) then
-  begin
-    Source.ReadChunkData(NameChunk);
-    Result := string(NameChunk^.Data.NamedObject);
-    FreeChunkData(NameChunk);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetCameraMotion(const Source: TFile3DS;
-  CamChunk, TargetChunk: PChunk3DS): TKFCamera3DS;
-
-  // gets camera keyframe information from chunk
-  // CamChunk    : CAMERA_NODE_TAG chunk to extract data from
-  // TargetChunk : TARGET_NODE_TAG chunk to extract target data from
-  // KFCamera    : Structure to fill in with chunk data
-
-var
-  NodeHdrChunk, PosChunk, FovChunk, RollChunk, TargetPosChunk,
-  TargetHdrChunk: PChunk3DS;
-  PosKeys, FovKeys, RollKeys, TargetKeys: integer;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  TargetPosChunk := nil;
-  TargetHdrChunk := nil;
-  PosKeys := 0;
-  FovKeys := 0;
-  RollKeys := 0;
-  TargetKeys := 0;
-
-  // get information from chunks
-  // search children of camera Chunk
-  NodeHdrChunk := FindChunk(CamChunk, NODE_HDR);
-  PosChunk := FindChunk(CamChunk, POS_TRACK_TAG);
-  FovChunk := FindChunk(CamChunk, FOV_TRACK_TAG);
-  RollChunk := FindChunk(CamChunk, ROLL_TRACK_TAG);
-
-  Source.ReadChunkData(NodeHdrChunk);
-
-  if Assigned(PosChunk) then
-  begin
-    Source.ReadChunkData(PosChunk);
-    PosKeys := PosChunk^.Data.PosTrackTag^.TrackHdr.KeyCount;
-  end;
-
-  if Assigned(FOVChunk) then
-  begin
-    Source.ReadChunkData(FOVChunk);
-    FovKeys := FOVChunk^.Data.FOVTrackTag^.TrackHdr.KeyCount;
-  end;
-
-  if Assigned(RollChunk) then
-  begin
-    Source.ReadChunkData(RollChunk);
-    RollKeys := RollChunk^.Data.RollTrackTag^.TrackHdr.KeyCount;
-  end;
-
-  if Assigned(TargetChunk) then
-  begin
-    TargetHdrChunk := FindChunk(TargetChunk, NODE_HDR);
-    if Assigned(TargetHdrChunk) then
-      Source.ReadChunkData(TargetHdrChunk);
-
-    TargetPosChunk := FindChunk(TargetChunk, POS_TRACK_TAG);
-    if Assigned(TargetPosChunk) then
-    begin
-      Source.ReadChunkData(TargetPosChunk);
-      TargetKeys := TargetPosChunk^.Data.PosTrackTag^.TrackHdr.KeyCount;
-    end;
-  end;
-
-  // set-up and fill-in the kfcamera structure
-  InitCameraMotion(Result, PosKeys, FOVKeys, RollKeys, TargetKeys);
-  with Result do
-  begin
-    // header Information
-    if Assigned(NodeHdrChunk) then
-    begin
-      NameStr := ansistring(NodeHdrChunk^.Data.NodeHdr^.ObjNameStr);
-      Flags1 := NodeHdrChunk^.Data.NodeHdr^.Flags1;
-      Flags2 := NodeHdrChunk^.Data.NodeHdr^.Flags2;
-    end;
-    // parents
-    ParentStr := ansistring(GetParentName(Source, NodeHdrChunk));
-    TParentStr := GetParentName(Source, TargetHdrChunk);
-
-    // target information
-    if TargetKeys <> 0 then
-    begin
-      NTFlag := TargetPosChunk^.Data.PosTrackTag^.TrackHdr.Flags;
-      Move(TargetPosChunk^.Data.PosTrackTag^.KeyHdrList^, TKeys^,
-        TargetKeys * SizeOf(TKeyHeader3DS));
-      Move(TargetPosChunk^.Data.PosTrackTag^.PositionList^, TPos^,
-        TargetKeys * SizeOf(TPoint3DS));
-    end;
-    if Assigned(TargetHdrChunk) then
-    begin
-      TFlags1 := TargetHdrChunk^.Data.NodeHdr^.Flags1;
-      TFlags2 := TargetHdrChunk^.Data.NodeHdr^.Flags2;
-    end;
-
-    // position information
-    if PosKeys <> 0 then
-    begin
-      NPFlag := PosChunk^.Data.PosTrackTag^.TrackHdr.Flags;
-      Move(PosChunk^.Data.PosTrackTag^.KeyHdrList^, PKeys^, PosKeys *
-        SizeOf(TKeyHeader3DS));
-      Move(PosChunk^.Data.PosTrackTag^.PositionList^, Pos^, PosKeys * SizeOf(TPoint3DS));
-    end;
-
-    // field of view information
-    if FOVKeys <> 0 then
-    begin
-      NFFlag := FOVChunk^.Data.FOVTrackTag^.TrackHdr.Flags;
-      Move(FOVChunk^.Data.FOVTrackTag^.KeyHdrList^, FKeys^, FOVKeys *
-        SizeOf(TKeyHeader3DS));
-      Move(FOVChunk^.Data.FOVTrackTag^.FOVAngleList^, FOV^, FOVKeys * SizeOf(single));
-    end;
-
-    // roll track information
-    if RollKeys <> 0 then
-    begin
-      NRFlag := RollChunk^.Data.RollTrackTag^.TrackHdr.Flags;
-      Move(RollChunk^.Data.RollTrackTag^.KeyHdrList^, RKeys^, RollKeys *
-        SizeOf(TKeyHeader3DS));
-      Move(RollChunk^.Data.RollTrackTag^.RollangleList^, Roll^,
-        RollKeys * SizeOf(single));
-    end;
-
-    // free chunk data
-    if Assigned(PosChunk) then
-      FreeChunkData(PosChunk);
-    if Assigned(FovChunk) then
-      FreeChunkData(FovChunk);
-    if Assigned(RollChunk) then
-      FreeChunkData(RollChunk);
-    if Assigned(NodeHdrChunk) then
-      FreeChunkData(NodeHdrChunk);
-    if Assigned(TargetPosChunk) then
-      FreeChunkData(TargetPosChunk);
-    if Assigned(TargetHdrChunk) then
-      FreeChunkData(TargetHdrChunk);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetCameraMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: integer): TKFCamera3DS;
-
-var
-  CameraChunk, TargetChunk: PChunk3DS;
-  List: TStringList;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  List := TStringList.Create;
-  try
-    GetCameraNodeNameList(Source, DB, List);
-    if Index < List.Count then
-    begin
-      CameraChunk := FindNamedAndTaggedChunk(Source, DB, List[Index], CAMERA_NODE_TAG);
-      if Assigned(CameraChunk) then
-      begin
-        TargetChunk := FindNamedAndTaggedChunk(Source, DB, List[Index], TARGET_NODE_TAG);
-        Result := GetCameraMotion(Source, CameraChunk, TargetChunk);
-      end;
-    end;
-  finally
-    List.Free;
-  end;
-end;
-
-//----------------- Ambient Light animation ---------------------------------------------------------------------------
-
-procedure InitAmbientLightMotion(var Light: TKFAmbient3DS; NewNCKeys: cardinal);
-
-var
-  I: integer;
-
-begin
-  with Light do
-  begin
-    if Assigned(Color) then
-      FreeMem(Color);
-    if Assigned(CKeys) then
-      FreeMem(CKeys);
-    FillChar(Light, SizeOf(Light), 0);
-    NCKeys := NewNCKeys;
-
-    if NCKeys <> 0 then
-    begin
-      NCFlag := TrackSingle3DS;
-      CKeys := AllocMem(NCKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NCKeys - 1 do
-        CKeys^[I] := DefKeyHeader3DS;
-
-      Color := AllocMem(NCKeys * SizeOf(TFColor3DS));
-      for I := 0 to NCKeys - 1 do
-      begin
-        Color^[I].R := 1;
-        Color^[I].G := 1;
-        Color^[I].B := 1;
-      end;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ReleaseAmbientLightMotion(Light: PKFAmbient3DS);
-
-begin
-  if Assigned(Light) then
-  begin
-    with Light^ do
-    begin
-      if Assigned(CKeys) then
-        FreeMem(CKeys);
-      if Assigned(Color) then
-        FreeMem(Color);
-    end;
-    Dispose(Light);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetAmbientLightMotionChunk(const Source: TFile3DS;
-  AmbientChunk: PChunk3DS): TKFAmbient3DS;
-
-  // AmbientChunk : SPOTAMBIENT_NODE_TAG chunk to extract data from
-  // TargetChunk  : L_TARGET_NODE_TAG chunk to extract target data from
-  // KFSpot       : Structure to fill in with chunk data
-
-  // Gets AmbientLight keyframe information from chunk
-  //  L_TARGET
-  //   ...
-  //  NODE_HDR
-  //  APP_DATA
-  //  COL_TRACK
-
-var
-  NodeHdrChunk, ColChunk: PChunk3DS;
-  ColKeys: integer;
-
-begin
-  if AmbientChunk = nil then
-    ShowError(strERROR3DS_INVALID_ARG);
-  FillChar(Result, SizeOf(Result), 0);
-
-  // get information from chunks
-  // search children of AmbientLight chunk
-  NodeHdrChunk := FindChunk(AmbientChunk, NODE_HDR);
-  ColChunk := FindChunk(AmbientChunk, COL_TRACK_TAG);
-
-  if Assigned(NodeHdrChunk) then
-    Source.ReadChunkData(NodeHdrChunk);
-  if Assigned(ColChunk) then
-  begin
-    Source.ReadChunkData(ColChunk);
-    ColKeys := ColChunk^.Data.ColTrackTag^.TrackHdr.KeyCount;
-  end
-  else
-    ColKeys := 0;
-
-  // eat-up and fill-in the PKFAmbient3DS structure
-  InitAmbientLightMotion(Result, ColKeys);
-
-  // header information
-  if Assigned(NodeHdrChunk) then
-  begin
-    Result.Flags1 := NodeHdrChunk^.Data.NodeHdr^.Flags1;
-    Result.Flags2 := NodeHdrChunk^.Data.NodeHdr^.Flags2;
-  end;
-
-  // color information
-  if Assigned(ColChunk) then
-  begin
-    if ColKeys <> 0 then
-    begin
-      Result.NCFlag := ColChunk^.Data.ColTrackTag^.TrackHdr.Flags;
-      Move(ColChunk^.Data.ColTrackTag^.KeyHdrList^, Result.CKeys^,
-        ColKeys * SizeOf(TKeyHeader3DS));
-      Move(ColChunk^.Data.ColTrackTag^.ColorList^, Result.Color^,
-        ColKeys * SizeOf(TFColor3DS));
-    end;
-  end;
-
-  // free chunk data
-  if Assigned(NodeHdrChunk) then
-    FreeChunkData(NodeHdrChunk);
-  if Assigned(ColChunk) then
-    FreeChunkData(ColChunk);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetAmbientLightMotion(const Source: TFile3DS;
-  var DB: TDatabase3DS): TKFAmbient3DS;
-
-  // Ambient Light a special case: only one ambient node per keyframe data Chunk^.
-
-var
-  KFChunk, Chunk: PChunk3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-  // find keyframe chunk
-  KFChunk := FindChunk(DB.TopChunk, KFDATA);
-  if Assigned(KFChunk) then
-  begin
-    Chunk := FindChunk(KFChunk, AMBIENT_NODE_TAG);
-    if Assigned(Chunk) then
-      Result := GetAmbientLightMotionChunk(Source, Chunk);
-  end;
-end;
-
-//----------------- Mesh object animation -----------------------------------------------------------------------------
-
-procedure InitObjectMotion(var Obj: TKFMesh3DS; NewNPKeys, // Number of position keys
-  NewNRKeys, // Number of rot keys
-  NewNSKeys, // Number of scale keys
-  NewNMKeys, // Number of morph keys
-  NewNHKeys: cardinal); // Number of hide keys
-var
-  I: integer;
-
-begin
-  with Obj do
-  begin
-    if Assigned(PKeys) then
-      FreeMem(PKeys);
-    if Assigned(Pos) then
-      FreeMem(Pos);
-    if Assigned(RKeys) then
-      FreeMem(RKeys);
-    if Assigned(Rot) then
-      FreeMem(Rot);
-    if Assigned(SKeys) then
-      FreeMem(SKeys);
-    if Assigned(Scale) then
-      FreeMem(Scale);
-    if Assigned(MKeys) then
-      FreeMem(MKeys);
-    if Assigned(Morph) then
-      FreeMem(Morph);
-    if Assigned(HKeys) then
-      FreeMem(HKeys);
-
-    FillChar(Obj, SizeOf(Obj), 0);
-    Pivot := DefPoint3DS;
-    BoundMin := DefPoint3DS;
-    BoundMax := DefPoint3DS;
-
-    NPKeys := NewNPKeys;
-    NRKeys := NewNRKeys;
-    NSKeys := NewNSKeys;
-    NMKeys := NewNMKeys;
-    NHKeys := NewNHKeys;
-
-    MSAngle := 24;
-
-    if NPKeys <> 0 then
-    begin
-      NPFlag := TrackSingle3DS;
-
-      PKeys := AllocMem(NPKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NPKeys - 1 do
-        PKeys^[I] := DefKeyHeader3DS;
-
-      Pos := AllocMem(NPKeys * SizeOf(TPoint3DS));
-      for I := 0 to NPKeys - 1 do
-        Pos^[I] := DefPoint3DS;
-    end;
-
-    if NRKeys <> 0 then
-    begin
-      NRFlag := TrackSingle3DS;
-
-      RKeys := AllocMem(NRKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NRKeys - 1 do
-        RKeys^[I] := DefKeyHeader3DS;
-
-      Rot := AllocMem(NRKeys * SizeOf(TKFRotKey3DS));
-      for I := 0 to NRKeys - 1 do
-        Rot^[I] := DefKfRotKey3DS;
-    end;
-
-    if NSKeys <> 0 then
-    begin
-      NSFlag := TrackSingle3DS;
-
-      SKeys := AllocMem(NSKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NSKeys - 1 do
-        SKeys^[I] := DefKeyHeader3DS;
-
-      Scale := AllocMem(NSKeys * SizeOf(TPoint3DS));
-      for I := 0 to NSKeys - 1 do
-      begin
-        Scale^[I].X := 1;
-        Scale^[I].Y := 1;
-        Scale^[I].Z := 1;
-      end;
-    end;
-
-    if NMKeys <> 0 then
-    begin
-      NMFlag := TrackSingle3DS;
-
-      MKeys := AllocMem(NMKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NMKeys - 1 do
-        MKeys^[I] := DefKeyHeader3DS;
-
-      Morph := AllocMem(NMKeys * SizeOf(TKFMorphKey3DS));
-      for I := 0 to NMKeys - 1 do
-        Morph^[I] := ' ';
-    end;
-
-    if NHKeys <> 0 then
-    begin
-      NHFlag := TrackSingle3DS;
-
-      HKeys := AllocMem(NHKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NMKeys - 1 do
-        MKeys^[I] := DefKeyHeader3DS;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ReleaseObjectMotion(Obj: PKFMesh3DS);
-
-begin
-  if Assigned(Obj) then
-  begin
-    with Obj^ do
-    begin
-      if Assigned(PKeys) then
-        FreeMem(PKeys);
-      if Assigned(Pos) then
-        FreeMem(Pos);
-      if Assigned(RKeys) then
-        FreeMem(RKeys);
-      if Assigned(Rot) then
-        FreeMem(Rot);
-      if Assigned(SKeys) then
-        FreeMem(SKeys);
-      if Assigned(Scale) then
-        FreeMem(Scale);
-      if Assigned(MKeys) then
-        FreeMem(MKeys);
-      if Assigned(Morph) then
-        FreeMem(Morph);
-      if Assigned(HKeys) then
-        FreeMem(HKeys);
-    end;
-    Dispose(Obj);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetObjectNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): integer;
-
-begin
-  Result := GetGenericNodeCount(Source, DB, OBJECT_NODE_TAG);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure GetObjectNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
-  List: TStringList);
-
-begin
-  GetGenericNodeNameList(Source, DB, OBJECT_NODE_TAG, List);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetObjectMotion(const Source: TFile3DS; MeshChunk: PChunk3DS): TKFMesh3DS;
-
-  // Gets mesh keyframe information from chunk
-
-  //  NODE_ID
-  //  NODE_HDR
-  //  APP_DATA
-  //  INSTANCE_NAME
-  //  PRESCALE a no-op in 3DS code
-  //  POS_TRACK
-  //  ROT_TRACK
-  //  SCL_TRACK
-  //  MORPH_TRACK
-  //  MORPH_SMOOTH
-  //  HIDE_TRACK
-
-  // This function is really confusing, because instead of loading the MeshChunk and its children, reading the
-  // data out and freeing it, the chunk structure is copied, its data is moved to the copy (so MeshChunk is then without
-  // any data), the copy is parsed and then it is freed. I don't know why this is so, but I don't want to change
-  // the way it works in case this has (or will later have) side effects I don't see yet. ml
-
-var
-  NodeHdrChunk, InstChunk, PivotChunk, BboxChunk, MsChunk,
-  PosChunk, RotChunk, ScaleChunk, MorphChunk, HideChunk,
-  ObjTag: PChunk3DS;
-
-  PosKeys, RotKeys, ScaleKeys, MorphKeys, HideKeys: integer;
-
-  PivotData: PPivot;
-  InstData: PInstanceName;
-  BBoxData: PBoundBox;
-  MsData: PMorphSmooth;
-  PosData: PPosTrackTag;
-  RotData: PRotTrackTag;
-  ScaleData: PScaleTrackTag;
-  MorphData: PMorphTrackTag;
-  HideData: PHideTrackTag;
-
-begin
-  PosKeys := 0;
-  RotKeys := 0;
-  ScaleKeys := 0;
-  MorphKeys := 0;
-  HideKeys := 0;
-  PivotData := nil;
-  InstData := nil;
-  BboxData := nil;
-  MsData := nil;
-  PosData := nil;
-  RotData := nil;
-  ScaleData := nil;
-  MorphData := nil;
-  HideData := nil;
-
-  if MeshChunk^.Tag <> OBJECT_NODE_TAG then
-    ShowError(strERROR3DS_WRONG_OBJECT);
-
-  ObjTag := CopyChunk(MeshChunk);
-
-  // get information from chunks
-  // search children of MeshLight chunk
-  NodeHdrChunk := FindChunk(ObjTag, NODE_HDR);
-  InstChunk := FindChunk(ObjTag, INSTANCE_NAME);
-  PivotChunk := FindChunk(ObjTag, PIVOT);
-  BboxChunk := FindChunk(ObjTag, BOUNDBOX);
-  MsChunk := FindChunk(ObjTag, MORPH_SMOOTH);
-  PosChunk := FindChunk(ObjTag, POS_TRACK_TAG);
-  RotChunk := FindChunk(ObjTag, ROT_TRACK_TAG);
-  ScaleChunk := FindChunk(ObjTag, SCL_TRACK_TAG);
-  MorphChunk := FindChunk(ObjTag, MORPH_TRACK_TAG);
-  HideChunk := FindChunk(ObjTag, HIDE_TRACK_TAG);
-
-  Source.ReadChunkData(NodeHdrChunk);
-
-  if Assigned(InstChunk) then
-  begin
-    Source.ReadChunkData(InstChunk);
-    InstData := InstChunk^.Data.Dummy;
-    InstChunk^.Data.Dummy := nil;
-  end;
-
-  if Assigned(PivotChunk) then
-  begin
-    Source.ReadChunkData(PivotChunk);
-    PivotData := PivotChunk^.Data.Dummy;
-    PivotChunk^.Data.Dummy := nil;
-  end;
-
-  if Assigned(BboxChunk) then
-  begin
-    Source.ReadChunkData(BboxChunk);
-    BboxData := BboxChunk^.Data.Dummy;
-    BboxChunk^.Data.Dummy := nil;
-  end;
-
-  if Assigned(MsChunk) then
-  begin
-    Source.ReadChunkData(MsChunk);
-    MsData := MsChunk^.Data.Dummy;
-    MsChunk^.Data.Dummy := nil;
-  end;
-
-  if Assigned(PosChunk) then
-  begin
-    Source.ReadChunkData(PosChunk);
-    PosData := PosChunk^.Data.Dummy;
-    PosKeys := PosData^.TrackHdr.KeyCount;
-    PosChunk^.Data.Dummy := nil;
-  end;
-
-  if Assigned(RotChunk) then
-  begin
-    Source.ReadChunkData(RotChunk);
-    RotData := RotChunk^.Data.Dummy;
-    RotKeys := RotData^.TrackHdr.KeyCount;
-    RotChunk^.Data.Dummy := nil;
-  end;
-
-  if Assigned(ScaleChunk) then
-  begin
-    Source.ReadChunkData(ScaleChunk);
-    ScaleData := ScaleChunk^.Data.Dummy;
-    ScaleKeys := ScaleData^.TrackHdr.KeyCount;
-    ScaleChunk^.Data.Dummy := nil;
-  end;
-
-  if Assigned(MorphChunk) then
-  begin
-    Source.ReadChunkData(MorphChunk);
-    MorphData := MorphChunk^.Data.Dummy;
-    MorphKeys := MorphData^.TrackHdr.KeyCount;
-    MorphChunk^.Data.Dummy := nil;
-  end;
-
-  if Assigned(HideChunk) then
-  begin
-    Source.ReadChunkData(HideChunk);
-    HideData := HideChunk^.Data.Dummy;
-    HideKeys := HideData^.TrackHdr.KeyCount;
-    HideChunk^.Data.Dummy := nil;
-  end;
-
-  // set-up and fill-in the TKFMesh3DS structure
-  with Result do
-  begin
-    //--- header Information
-    NameStr := ansistring(NodeHdrChunk^.Data.NodeHdr^.ObjNameStr);
-    Flags1 := NodeHdrChunk^.Data.NodeHdr^.Flags1;
-    Flags2 := NodeHdrChunk^.Data.NodeHdr^.Flags2;
-
-    //--- get parent name if there is one
-    ParentStr := ansistring(GetParentName(Source, NodeHdrChunk));
-
-    //--- Instance
-    if Assigned(InstData) then
-    begin
-      InstanceStr := StrPas(InstData);
-      NameStr := NameStr + '.' + InstanceStr;
-      FreeMem(InstData);
-    end
-    else
-      InstanceStr := '';
-
-    //--- Pivot
-    if Assigned(PivotData) then
-    begin
-      Pivot := PivotData^;
-      FreeMem(PivotData);
-    end
-    else
-      Pivot := DefPoint3DS;
-
-    //--- Bound
-    if Assigned(BboxData) then
-    begin
-      BoundMin := BboxData^.Min;
-      BoundMax := BboxData^.Max;
-      FreeMem(BboxData);
-    end
-    else
-    begin
-      BoundMin := DefPoint3DS;
-      BoundMax := DefPoint3DS;
-    end;
-
-    //--- MorphSmooth Angle
-    if Assigned(MsData) then
-    begin
-      MSAngle := MsData^;
-      FreeMem(MsData);
-    end
-    else
-      MSAngle := 0;
-
-    //--- Position
-    NPKeys := PosKeys;
-    if PosKeys <> 0 then
-    begin
-      PKeys := PosData^.KeyHdrList;
-      Pos := PosData^.PositionList;
-      NPFlag := PosData^.TrackHdr.Flags;
-      FreeMem(PosData);
-    end
-    else
-    begin
-      PKeys := nil;
-      Pos := nil;
-      NPFlag := 0;
-    end;
-
-    //--- Rotation
-    NRKeys := RotKeys;
-    if RotKeys <> 0 then
-    begin
-      RKeys := RotData^.KeyHdrList;
-      Rot := RotData^.RotationList;
-      NRFlag := RotData^.TrackHdr.Flags;
-      FreeMem(RotData);
-    end
-    else
-    begin
-      RKeys := nil;
-      Rot := nil;
-      NRFlag := 0;
-    end;
-
-    //--- Scale
-    NSKeys := ScaleKeys;
-    if ScaleKeys <> 0 then
-    begin
-      SKeys := ScaleData^.KeyHdrList;
-      Scale := ScaleData^.ScaleList;
-      NSFlag := ScaleData^.TrackHdr.Flags;
-      FreeMem(ScaleData);
-    end
-    else
-    begin
-      SKeys := nil;
-      Scale := nil;
-      NSFlag := 0;
-    end;
-
-    //--- Morph
-    NMKeys := MorphKeys;
-    if MorphKeys <> 0 then
-    begin
-      MKeys := MorphData^.KeyHdrList;
-      Morph := MorphData^.MorphList;
-      NMFlag := MorphData^.TrackHdr.Flags;
-      FreeMem(MorphData);
-    end
-    else
-    begin
-      MKeys := nil;
-      Morph := nil;
-      NMFlag := 0;
-    end;
-
-    NHKeys := HideKeys;
-    if HideKeys <> 0 then
-    begin
-      HKeys := HideData^.KeyHdrList;
-      NHFlag := HideData^.TrackHdr.Flags;
-      FreeMem(HideData);
-    end
-    else
-    begin
-      HKeys := nil;
-      NHFlag := 0;
-    end;
-  end;
-
-  //-- ADDITIONAL Morph INFO HERE
-
-  //--- free chunk data: only free those that arent being copied
-  ReleaseChunk(ObjTag);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetObjectMotionByName(const Source: TFile3DS; var DB: TDatabase3DS;
-  Name: string): TKFMesh3DS;
-
-var
-  ObjectChunk: PChunk3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  ObjectChunk := FindNodeTagByNameAndType(Source, DB, Name, OBJECT_NODE_TAG);
-  if Assigned(ObjectChunk) then
-    Result := GetObjectMotion(Source, ObjectChunk);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetObjectMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: cardinal): TKFMesh3DS;
-
-var
-  Chunk: PChunk3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  Chunk := FindNodeTagByIndexAndType(Source, DB, Index, OBJECT_NODE_TAG);
-  if Assigned(Chunk) then
-    Result := GetObjectMotion(Source, Chunk);
-end;
-
-//----------------- Omni Light animation ------------------------------------------------------------------------------
-
-procedure InitOmnilightMotion(var Light: TKFOmni3DS; NewNPKeys, NewNCKeys: cardinal);
-
-var
-  I: integer;
-
-begin
-  with Light do
-  begin
-    if Assigned(PKeys) then
-      FreeMem(PKeys);
-    if Assigned(Pos) then
-      FreeMem(Pos);
-    if Assigned(CKeys) then
-      FreeMem(CKeys);
-    if Assigned(Color) then
-      FreeMem(Color);
-
-    FillChar(Light, SizeOf(Light), 0);
-    NPKeys := NewNPKeys;
-    NCKeys := NewNCKeys;
-
-    if NPKeys <> 0 then
-    begin
-      NPFlag := TrackSingle3DS;
-
-      PKeys := AllocMem(NPKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NPKeys - 1 do
-        PKeys^[I] := DefKeyHeader3DS;
-
-      Pos := AllocMem(NPKeys * SizeOf(TPoint3DS));
-      for I := 0 to NPKeys - 1 do
-        Pos^[I] := DefPoint3DS;
-    end;
-
-    if NCKeys <> 0 then
-    begin
-      NCFlag := TrackSingle3DS;
-
-      CKeys := AllocMem(NCKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NCKeys - 1 do
-        CKeys^[I] := DefKeyHeader3DS;
-
-      Color := AllocMem(NCKeys * SizeOf(TFColor3DS));
-      for I := 0 to NCKeys - 1 do
-      begin
-        Color^[I].R := 1;
-        Color^[I].G := 1;
-        Color^[I].B := 1;
-      end;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ReleaseOmnilightMotion(Light: PKFOmni3DS);
-
-begin
-  if Assigned(Light) then
-  begin
-    with Light^ do
-    begin
-      if Assigned(PKeys) then
-        FreeMem(PKeys);
-      if Assigned(Pos) then
-        FreeMem(Pos);
-      if Assigned(CKeys) then
-        FreeMem(CKeys);
-      if Assigned(Color) then
-        FreeMem(Color);
-    end;
-    Dispose(Light);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetOmnilightNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): cardinal;
-
-begin
-  Result := GetGenericNodeCount(Source, DB, LIGHT_NODE_TAG);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure GetOmnilightNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
-  List: TStringList);
-
-begin
-  GetGenericNodeNameList(Source, DB, LIGHT_NODE_TAG, List);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetOmnilightMotion(const Source: TFile3DS; OmniChunk: PChunk3DS): TKFOmni3DS;
-
-  // Gets Omnilight keyframe information from chunk
-
-  //  L_TARGET
-  //  NODE_ID
-  //  NODE_HDR
-  //  APP_DATA
-  //  POS_TRACK
-  //  COL_TRACK
-  //  HOT_TRACK
-  //  FALL_TRACK
-  //  ROLL_TRACK
-
-var
-  NodeHdrChunk, PosChunk, ColChunk: PChunk3DS;
-  PosKeys, ColKeys: cardinal;
-
-begin
-  PosKeys := 0;
-  ColKeys := 0;
-
-  // get information from chunks
-  // search children of OmniLight chunk
-  NodeHdrChunk := FindChunk(OmniChunk, NODE_HDR);
-  PosChunk := FindChunk(OmniChunk, POS_TRACK_TAG);
-  ColChunk := FindChunk(OmniChunk, COL_TRACK_TAG);
-
-  Source.ReadChunkData(NodeHdrChunk);
-
-  if Assigned(PosChunk) then
-  begin
-    Source.ReadChunkData(PosChunk);
-    PosKeys := PosChunk^.Data.PosTrackTag^.TrackHdr.KeyCount;
-  end;
-
-  if Assigned(ColChunk) then
-  begin
-    Source.ReadChunkData(ColChunk);
-    ColKeys := ColChunk^.Data.ColTrackTag^.TrackHdr.KeyCount;
-  end;
-
-  // set-up and fill-in the TKFOmni3DS structure
-  FillChar(Result, SizeOf(Result), $00);
-  InitOmnilightMotion(Result, PosKeys, ColKeys);
-  with Result do
-  begin
-    //--- Header Information
-    Name := ansistring(NodeHdrChunk^.Data.NodeHdr^.ObjNameStr);
-    Flags1 := NodeHdrChunk^.Data.NodeHdr^.Flags1;
-    Flags2 := NodeHdrChunk^.Data.NodeHdr^.Flags2;
-    Parent := ansistring(GetParentName(Source, NodeHdrChunk));
-
-    //--- Position Information
-    if PosKeys <> 0 then
-    begin
-      NPFlag := PosChunk^.Data.PosTrackTag^.TrackHdr.Flags;
-      Move(PosChunk^.Data.PosTrackTag^.KeyHdrList^, PKeys^, PosKeys *
-        SizeOf(TKeyHeader3DS));
-      Move(PosChunk^.Data.PosTrackTag^.PositionList^, Pos^, PosKeys * SizeOf(TPoint3DS));
-    end;
-
-    //--- Color Information
-    if ColKeys <> 0 then
-    begin
-      NCFlag := PosChunk^.Data.ColTrackTag^.TrackHdr.Flags;
-      Move(ColChunk^.Data.ColTrackTag^.KeyHdrList^, CKeys^, ColKeys *
-        SizeOf(TKeyHeader3DS));
-      Move(ColChunk^.Data.ColTrackTag^.ColorList^, Color^, ColKeys * SizeOf(TFColor3DS));
-    end;
-
-    //--- Free Chunk Data
-    if Assigned(NodeHdrChunk) then
-      FreeChunkData(NodeHdrChunk);
-    if Assigned(PosChunk) then
-      FreeChunkData(PosChunk);
-    if Assigned(ColChunk) then
-      FreeChunkData(ColChunk);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetOmnilightMotionByName(const Source: TFile3DS; var DB: TDatabase3DS;
-  Name: string): TKFOmni3DS;
-
-var
-  Chunk: PChunk3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  Chunk := FindNamedAndTaggedChunk(Source, DB, Name, LIGHT_NODE_TAG);
-  if Assigned(Chunk) then
-    Result := GetOmnilightMotion(Source, Chunk);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetOmnilightMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: cardinal): TKFOmni3DS;
-
-var
-  Chunk: PChunk3DS;
-  List: TStringList;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  List := TStringList.Create;
-  try
-    GetOmnilightNodeNameList(Source, DB, List);
-
-    if Index < cardinal(List.Count) then
-    begin
-      Chunk := FindNamedAndTaggedChunk(Source, DB, List[Index], LIGHT_NODE_TAG);
-      if Assigned(Chunk) then
-        Result := GetOmnilightMotion(Source, Chunk);
-    end;
-  finally
-    List.Free;
-  end;
-end;
-
-//----------------- Spot Light animation ------------------------------------------------------------------------------
-
-procedure InitSpotlightMotion(var Spot: TKFSpot3DS;
-  NewNPKeys, //  Number of position keys
-  NewNCKeys, //  Number of Color keys
-  NewNHKeys, //  Number of hot spot angle keys
-  NewNFKeys, //  Number of falloff angle keys
-  NewNRKeys, //  Number of roll keys
-  NewNTKeys: cardinal); //  Number of target position keys
-
-var
-  I: cardinal;
-
-begin
-  with Spot do
-  begin
-    if Assigned(PKeys) then
-      FreeMem(PKeys);
-    if Assigned(Pos) then
-      FreeMem(Pos);
-    if Assigned(CKeys) then
-      FreeMem(CKeys);
-    if Assigned(Color) then
-      FreeMem(Color);
-    if Assigned(HKeys) then
-      FreeMem(HKeys);
-    if Assigned(Hot) then
-      FreeMem(Hot);
-    if Assigned(FKeys) then
-      FreeMem(FKeys);
-    if Assigned(Fall) then
-      FreeMem(Fall);
-    if Assigned(RKeys) then
-      FreeMem(RKeys);
-    if Assigned(Roll) then
-      FreeMem(Roll);
-    if Assigned(TKeys) then
-      FreeMem(TKeys);
-    if Assigned(TPos) then
-      FreeMem(TPos);
-
-    FillChar(Spot, SizeOf(Spot), 0);
-    NPKeys := NewNPKeys;
-    NCKeys := NewNCKeys;
-    NFKeys := NewNFKeys;
-    NTKeys := NewNTKeys;
-    NHKeys := NewNHKeys;
-    NRKeys := NewNRKeys;
-
-    //--- POSITION KEYS -----------------------------------------------------
-    if NPKeys <> 0 then
-    begin
-      NPFlag := TrackSingle3DS;
-
-      PKeys := AllocMem(NPKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NPKeys - 1 do
-        PKeys^[I] := DefKeyHeader3DS;
-
-      Pos := AllocMem(NPKeys * SizeOf(TPoint3DS));
-      for I := 0 to NPKeys - 1 do
-        Pos^[I] := DefPoint3DS;
-    end;
-
-    //--- Color KEYS ----------------------------------------------------------
-    if NCKeys <> 0 then
-    begin
-      NCFlag := TrackSingle3DS;
-      CKeys := AllocMem(NCKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NCKeys - 1 do
-        CKeys^[I] := DefKeyHeader3DS;
-
-      Color := AllocMem(NCKeys * SizeOf(TFColor3DS));
-      // Initialization is unclear, even the original developers didn't know what's up.
-      // They put this part in an '#ifdef LATER #endif' block. ml
-      // for I := 0 to NCKeys - 1 do Color[I] := localDColor.bDefFColor3DS;
-    end;
-
-    //---Hot-Spot ANGLE KEYS---------------------------------------------------
-    if NHKeys <> 0 then
-    begin
-      NHFlag := TrackSingle3DS;
-
-      HKeys := AllocMem(NHKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NHKeys - 1 do
-        HKeys^[I] := DefKeyHeader3DS;
-
-      Hot := AllocMem(NHKeys * SizeOf(single));
-      // default Hot Spot ange 90.0 for now, get real value later (1..174.5)
-      for I := 0 to NHKeys - 1 do
-        Hot^[I] := 90;
-    end;
-
-    //---FALLOFF ANGLE KEYS----------------------------------------------------
-    if NFKeys <> 0 then
-    begin
-      NFFlag := TrackSingle3DS;
-
-      FKeys := AllocMem(NFKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NFKeys - 1 do
-        FKeys^[I] := DefKeyHeader3DS;
-
-      Fall := AllocMem(NFKeys * SizeOf(single));
-
-      // default falloff ange 90.0 for now, get real value later (1..175)
-      for I := 0 to NFKeys - 1 do
-        Fall^[I] := 90;
-    end;
-
-    //--- Roll KEYS ----------------------------------------------------------
-    if NRKeys <> 0 then
-    begin
-      NRFlag := TrackSingle3DS;
-
-      RKeys := AllocMem(NRKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NRKeys - 1 do
-        RKeys^[I] := DefKeyHeader3DS;
-
-      Roll := AllocMem(NRKeys * SizeOf(single));
-      for I := 0 to NRKeys - 1 do
-        Roll^[I] := 0;
-    end;
-
-    //---L_TARGET Pos KEYS ------------------------------------------------
-    if NTKeys <> 0 then
-    begin
-      NTFlag := TrackSingle3DS;
-
-      TKeys := AllocMem(NTKeys * SizeOf(TKeyHeader3DS));
-      for I := 0 to NTKeys - 1 do
-        TKeys^[I] := DefKeyHeader3DS;
-
-      TPos := AllocMem(NTKeys * SizeOf(TPoint3DS));
-      // default target position, 0, 0, 0  sjw fix later if necessary
-      for I := 0 to NTKeys - 1 do
-        TPos^[I] := DefPoint3DS;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure ReleaseSpotlightMotion(Spot: PKFSpot3DS);
-
-begin
-  if Assigned(Spot) then
-  begin
-    with Spot^ do
-    begin
-      if Assigned(PKeys) then
-        FreeMem(PKeys);
-      if Assigned(Pos) then
-        FreeMem(Pos);
-      if Assigned(CKeys) then
-        FreeMem(CKeys);
-      if Assigned(Color) then
-        FreeMem(Color);
-      if Assigned(HKeys) then
-        FreeMem(HKeys);
-      if Assigned(Hot) then
-        FreeMem(Hot);
-      if Assigned(FKeys) then
-        FreeMem(FKeys);
-      if Assigned(Fall) then
-        FreeMem(Fall);
-      if Assigned(RKeys) then
-        FreeMem(RKeys);
-      if Assigned(Roll) then
-        FreeMem(Roll);
-      if Assigned(TKeys) then
-        FreeMem(TKeys);
-      if Assigned(TPos) then
-        FreeMem(TPos);
-    end;
-    Dispose(Spot);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetSpotlightNodeCount(const Source: TFile3DS; var DB: TDatabase3DS): cardinal;
-
-begin
-  Result := GetGenericNodeCount(Source, DB, SPOTLIGHT_NODE_TAG);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-procedure GetSpotlightNodeNameList(const Source: TFile3DS; var DB: TDatabase3DS;
-  List: TStringList);
-
-begin
-  GetGenericNodeNameList(Source, DB, SPOTLIGHT_NODE_TAG, List);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetSpotlightMotion(const Source: TFile3DS;
-  SpotChunk, TargetChunk: PChunk3DS): TKFSpot3DS;
-
-  // gets Spotlight keyframe information from chunk
-
-  // L_TARGET
-  //  ...
-  // NODE_HDR
-  // APP_DATA
-  // POS_TRACK
-  // COL_TRACK
-  // HOT_TRACK
-  // FALL_TRACK
-  // ROLL_TRACK
-
-var
-  NodeHdrChunk, PosChunk, ColChunk, TargetPosChunk, HotChunk,
-  FallChunk, RollChunk, TargetHdrChunk: PChunk3DS;
-  PosKeys, ColKeys, HotKeys, FallKeys, RollKeys, TargetKeys: cardinal;
-
-begin
-  TargetPosChunk := nil;
-  TargetHdrChunk := nil;
-  PosKeys := 0;
-  ColKeys := 0;
-  HotKeys := 0;
-  FallKeys := 0;
-  RollKeys := 0;
-  TargetKeys := 0;
-
-  // get information from chunks
-  // search children of Spotlight chunk
-  NodeHdrChunk := FindChunk(SpotChunk, NODE_HDR);
-  PosChunk := FindChunk(SpotChunk, POS_TRACK_TAG);
-  ColChunk := FindChunk(SpotChunk, COL_TRACK_TAG);
-  HotChunk := FindChunk(SpotChunk, HOT_TRACK_TAG);
-  FallChunk := FindChunk(SpotChunk, FALL_TRACK_TAG);
-  RollChunk := FindChunk(SpotChunk, ROLL_TRACK_TAG);
-
-  Source.ReadChunkData(NodeHdrChunk);
-
-  if Assigned(PosChunk) then
-  begin
-    Source.ReadChunkData(PosChunk);
-    PosKeys := PosChunk^.Data.PosTrackTag^.TrackHdr.KeyCount;
-  end;
-
-  if Assigned(ColChunk) then
-  begin
-    Source.ReadChunkData(ColChunk);
-    ColKeys := ColChunk^.Data.ColTrackTag^.TrackHdr.KeyCount;
-  end;
-
-  if Assigned(HotChunk) then
-  begin
-    Source.ReadChunkData(HotChunk);
-    HotKeys := HotChunk^.Data.HotTrackTag^.TrackHdr.KeyCount;
-  end;
-
-  if Assigned(FallChunk) then
-  begin
-    Source.ReadChunkData(FallChunk);
-    FallKeys := FallChunk^.Data.FallTrackTag^.TrackHdr.KeyCount;
-  end;
-
-  if Assigned(RollChunk) then
-  begin
-    Source.ReadChunkData(RollChunk);
-    RollKeys := RollChunk^.Data.RollTrackTag^.TrackHdr.KeyCount;
-  end;
-
-  if Assigned(TargetChunk) then
-  begin
-    TargetHdrChunk := FindChunk(TargetChunk, NODE_HDR);
-    if Assigned(TargetHdrChunk) then
-      Source.ReadChunkData(TargetHdrChunk);
-
-    TargetPosChunk := FindChunk(TargetChunk, POS_TRACK_TAG);
-    if Assigned(TargetPosChunk) then
-    begin
-      Source.ReadChunkData(TargetPosChunk);
-      TargetKeys := TargetPosChunk^.Data.PosTrackTag^.TrackHdr.KeyCount;
-    end;
-  end;
-
-  // set-up and fill-in the TKFSpot3DS structure
-  InitSpotlightMotion(Result, PosKeys, ColKeys, HotKeys, FallKeys, RollKeys, TargetKeys);
-
-  with Result do
-  begin
-    // header Information
-    Name := ansistring(NodeHdrChunk^.Data.NodeHdr^.ObjNameStr);
-    Flags1 := NodeHdrChunk^.Data.NodeHdr^.Flags1;
-    Flags2 := NodeHdrChunk^.Data.NodeHdr^.Flags2;
-
-    // get parent name if there is one
-    Parent := ansistring(GetParentName(Source, NodeHdrChunk));
-    TParent := ansistring(GetParentName(Source, TargetHdrChunk));
-
-    if Assigned(TargetHdrChunk) then
-    begin
-      TFlags1 := TargetHdrChunk^.Data.NodeHdr^.Flags1;
-      TFlags2 := TargetHdrChunk^.Data.NodeHdr^.Flags2;
-    end
-    else
-    begin
-      TFlags1 := 0;
-      TFlags2 := 0;
-    end;
-
-    // target information
-    if TargetKeys <> 0 then
-    begin
-      NTFlag := TargetPosChunk^.Data.PosTrackTag^.TrackHdr.Flags;
-      Move(TargetPosChunk^.Data.PosTrackTag^.KeyHdrList^, TKeys^,
-        TargetKeys * SizeOf(TKeyHeader3DS));
-      Move(TargetPosChunk^.Data.PosTrackTag^.PositionList^, TPos^,
-        TargetKeys * SizeOf(TPoint3DS));
-    end;
-
-    // position information
-    if PosKeys <> 0 then
-    begin
-      NPFlag := PosChunk^.Data.PosTrackTag^.TrackHdr.Flags;
-      Move(PosChunk^.Data.PosTrackTag^.KeyHdrList^, PKeys^, PosKeys *
-        SizeOf(TKeyHeader3DS));
-      Move(PosChunk^.Data.PosTrackTag^.PositionList^, Pos^, PosKeys * SizeOf(TPoint3DS));
-    end;
-
-    // color information
-    if ColKeys <> 0 then
-    begin
-      NCFlag := ColChunk^.Data.ColTrackTag^.TrackHdr.Flags;
-      Move(ColChunk^.Data.ColTrackTag^.KeyHdrList^, CKeys^, ColKeys *
-        SizeOf(TKeyHeader3DS));
-      Move(ColChunk^.Data.ColTrackTag^.ColorList^, Color^, ColKeys * SizeOf(TFColor3DS));
-    end;
-
-    // hot spot information
-    if HotKeys <> 0 then
-    begin
-      NHFlag := HotChunk^.Data.HotTrackTag^.TrackHdr.Flags;
-      Move(HotChunk^.Data.HotTrackTag^.KeyHdrList^, HKeys^, HotKeys *
-        SizeOf(TKeyHeader3DS));
-      Move(HotChunk^.Data.HotTrackTag^.HotSpotAngleList^, Hot^, HotKeys *
-        SizeOf(single));
-    end;
-
-    // falloff information
-    if FallKeys <> 0 then
-    begin
-      NFFlag := FallChunk^.Data.FallTrackTag^.TrackHdr.Flags;
-      Move(FallChunk^.Data.FallTrackTag^.KeyHdrList^, FKeys^, FallKeys *
-        SizeOf(TKeyHeader3DS));
-      Move(FallChunk^.Data.FallTrackTag^.FallOffAngleList^, Fall^,
-        FallKeys * SizeOf(single));
-    end;
-
-    // roll track Information
-    if RollKeys <> 0 then
-    begin
-      NRFlag := RollChunk^.Data.RollTrackTag^.TrackHdr.Flags;
-      Move(RollChunk^.Data.RollTrackTag^.KeyHdrList^, RKeys^, RollKeys *
-        SizeOf(TKeyHeader3DS));
-      Move(RollChunk^.Data.RollTrackTag^.RollAngleList^, Roll^,
-        RollKeys * SizeOf(single));
-    end;
-  end;
-
-  //--- Free Chunk Data
-  if Assigned(NodeHdrChunk) then
-    FreeChunkData(NodeHdrChunk);
-  if Assigned(PosChunk) then
-    FreeChunkData(PosChunk);
-  if Assigned(ColChunk) then
-    FreeChunkData(ColChunk);
-  if Assigned(HotChunk) then
-    FreeChunkData(HotChunk);
-  if Assigned(FallChunk) then
-    FreeChunkData(FallChunk);
-  if Assigned(RollChunk) then
-    FreeChunkData(RollChunk);
-  if Assigned(TargetPosChunk) then
-    FreeChunkData(TargetPosChunk);
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetSpotlightMotionByName(const Source: TFile3DS; var DB: TDatabase3DS;
-  Name: string): TKFSpot3DS;
-
-var
-  SpotlightChunk, TargetChunk: PChunk3DS;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  SpotlightChunk := FindNamedAndTaggedChunk(Source, DB, Name, SPOTLIGHT_NODE_TAG);
-  if Assigned(SpotlightChunk) then
-  begin
-    TargetChunk := FindNamedAndTaggedChunk(Source, DB, Name, L_TARGET_NODE_TAG);
-    Result := GetSpotlightMotion(Source, SpotlightChunk, TargetChunk);
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetSpotlightMotionByIndex(const Source: TFile3DS; var DB: TDatabase3DS;
-  Index: cardinal): TKFSpot3DS;
-
-var
-  SpotChunk, TargetChunk: PChunk3DS;
-  List: TStringList;
-
-begin
-  FillChar(Result, SizeOf(Result), 0);
-
-  List := TStringList.Create;
-  try
-    GetSpotlightNodeNameList(Source, DB, List);
-    if Index < cardinal(List.Count) then
-    begin
-      SpotChunk := FindNamedAndTaggedChunk(Source, DB, List[Index], SPOTLIGHT_NODE_TAG);
-      if Assigned(SpotChunk) then
-      begin
-        TargetChunk := FindNamedAndTaggedChunk(Source, DB, List[Index],
-          L_TARGET_NODE_TAG);
-        if Assigned(TargetChunk) then
-          Result := GetSpotlightMotion(Source, SpotChunk, TargetChunk);
-      end;
-    end;
-  finally
-    List.Free;
-  end;
-end;
-
-//----------------- Versioninformation --------------------------------------------------------------------------------
-
-function GetM3dMagicRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
-
-  // Scans the database for M3D_VERSION chunk and returnes its release
-
-var
-  Chunk: PChunk3DS;
-
-begin
-  Result := rlReleaseNotKnown;
-  // If the database is a 3DS file
-  if DB.TopChunk^.Tag = M3DMAGIC then
-  begin
-    Chunk := FindChunk(DB.TopChunk, M3D_VERSION);
-    if Assigned(Chunk) then
-    begin
-      Source.ReadChunkData(Chunk);
-      case Chunk^.Data.M3dVersion^ of
-        1:
-          Result := rlRelease1;
-        2:
-          Result := rlRelease2;
-        3:
-          Result := rlRelease3;
-        else
-          Result := rlReleaseNotKnown;
-      end;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetMeshRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
-
-  // Scans the database for MESH_VERSION chunk and returnes its release
-
-var
-  Chunk: PChunk3DS;
-
-begin
-  Result := rlReleaseNotKnown;
-  // If the database is a 3DS file
-  if (DB.TopChunk^.Tag = M3DMAGIC) or (DB.TopChunk^.Tag = CMAGIC) then
-  begin
-    Chunk := FindChunk(DB.TopChunk, MESH_VERSION);
-    if Assigned(Chunk) then
-    begin
-      Source.ReadChunkData(Chunk);
-      case Chunk^.Data.MeshVersion^ of
-        1:
-          Result := rlRelease1;
-        2:
-          Result := rlRelease2;
-        3:
-          Result := rlRelease3;
-        else
-          Result := rlReleaseNotKnown;
-      end;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetKfRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
-
-  // Scans the database for KFHDR chunk and returnes its release level
-
-var
-  KFChunk, Chunk: PChunk3DS;
-
-begin
-  Result := rlReleaseNotKnown;
-  // If the database is a 3DS file
-  if (DB.TopChunk^.Tag = M3DMAGIC) or (DB.TopChunk^.Tag = CMAGIC) then
-  begin
-    KFChunk := FindChunk(DB.TopChunk, KFDATA);
-    if Assigned(KFChunk) then
-      Chunk := FindChunk(DB.TopChunk, KFHDR)
-    else
-      Chunk := nil;
-    if Assigned(Chunk) then
-    begin
-      Source.ReadChunkData(Chunk);
-      case Chunk^.Data.KFHdr^.Revision of
-        1:
-          Result := rlRelease1;
-        2:
-          Result := rlRelease2;
-        3:
-          Result := rlRelease3;
-        else
-          Result := rlReleaseNotKnown;
-      end;
-    end;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-function GetDatabaseRelease(const Source: TFile3DS; var DB: TDatabase3DS): TReleaseLevel;
-
-begin
-  case DB.TopChunk^.Tag of
-    M3DMAGIC:
-      Result := GetM3dMagicRelease(Source, DB);
-    CMAGIC:
-      Result := GetMeshRelease(Source, DB);
-    MLIBMAGIC:
-      Result := rlRelease3;
-    else
-      Result := rlReleaseNotKnown;
-  end;
-end;
-
-//---------------------------------------------------------------------------------------------------------------------
-
-end.
-

+ 1 - 1
Source/FMX/GLSLx.AsmShader.pas

@@ -11,7 +11,7 @@ unit GLSLx.AsmShader;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,

+ 2 - 2
Source/FMX/GLSLx.BumpShaders.pas

@@ -27,7 +27,7 @@ unit GLSLx.BumpShaders;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,
@@ -44,7 +44,7 @@ uses
   GLX.Texture,
   GLX.Scene,
   GLX.Cadencer,
-  GLX.Strings,
+  Scene.Strings,
   GLX.Color,
   GLX.RenderContextInfo,
   GLX.Material,

+ 2 - 2
Source/FMX/GLSLx.CustomShader.pas

@@ -12,7 +12,7 @@ unit GLSLx.CustomShader;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,
@@ -25,7 +25,7 @@ uses
   GLX.Texture, 
   GLX.Cadencer, 
   GLX.Scene,
-  GLX.Strings, 
+  Scene.Strings, 
   GLX.Context,
   GLX.RenderContextInfo,
   GLX.Material,

+ 2 - 2
Source/FMX/GLSLx.DiffuseSpecularShader.pas

@@ -21,7 +21,7 @@ unit GLSLx.DiffuseSpecularShader;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,
@@ -30,7 +30,7 @@ uses
   GLX.Texture,
   GLX.Scene,
   GLX.VectorGeometry,
-  GLX.Strings,
+  Scene.Strings,
   GLSLx.CustomShader,
   GLSLx.Shader,
   GLX.Color,

+ 1 - 1
Source/FMX/GLSLx.Parameter.pas

@@ -5,7 +5,7 @@ unit GLSLx.Parameter;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 {$M-}
 
 uses

+ 1 - 1
Source/FMX/GLSLx.PhongShader.pas

@@ -7,7 +7,7 @@ unit GLSLx.PhongShader;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,

+ 2 - 2
Source/FMX/GLSLx.PostEffects.pas

@@ -7,7 +7,7 @@ unit GLSLx.PostEffects;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,
@@ -16,7 +16,7 @@ uses
 
   GLX.PersistentClasses,
   GLX.VectorGeometry,
-  GLX.Strings,
+  Scene.Strings,
   GLX.Scene,
   GLX.Texture,
   GLX.Graphics,

+ 1 - 1
Source/FMX/GLSLx.PostShaders.pas

@@ -7,7 +7,7 @@ unit GLSLx.PostShaders;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 1 - 1
Source/FMX/GLSLx.ProjectedTextures.pas

@@ -20,7 +20,7 @@ unit GLSLx.ProjectedTextures;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 1 - 1
Source/FMX/GLSLx.Shader.pas

@@ -7,7 +7,7 @@ unit GLSLx.Shader;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,

+ 2 - 2
Source/FMX/GLSLx.ShaderCombiner.pas

@@ -14,7 +14,7 @@ unit GLSLx.ShaderCombiner;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,
@@ -22,7 +22,7 @@ uses
   GLX.Material,
   GLX.Scene,
   GLX.VectorGeometry,
-  GLX.Strings,
+  Scene.Strings,
   GLX.RenderContextInfo;
 
 type

+ 1 - 1
Source/FMX/GLSLx.TextureShaders.pas

@@ -31,7 +31,7 @@ uses
   GLX.VectorGeometry,
   GLX.Color,
   GLX.Material,
-  GLX.Strings,
+  Scene.Strings,
   GLX.VectorFileObjects,
   GLX.State,
   GLX.PersistentClasses,

+ 1 - 1
Source/FMX/GLX.AVIRecorder.pas

@@ -7,7 +7,7 @@ unit GLX.AVIRecorder;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.Windows,

+ 2 - 2
Source/FMX/GLX.AnimatedSprite.pas

@@ -7,7 +7,7 @@ unit GLX.AnimatedSprite;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,
@@ -21,7 +21,7 @@ uses
   GLX.VectorTypes,
   GLX.VectorGeometry,
   GLX.PersistentClasses,
-  GLX.Strings,
+  Scene.Strings,
 
   GLX.Scene,
   GLX.Context,

+ 1 - 1
Source/FMX/GLX.AnimationUtils.pas

@@ -7,7 +7,7 @@ unit GLX.AnimationUtils;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.SysUtils,

+ 2 - 2
Source/FMX/GLX.ApplicationFileIO.pas

@@ -8,7 +8,7 @@ unit GLX.ApplicationFileIO;
 *)
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.Windows,
@@ -16,7 +16,7 @@ uses
   System.SysUtils,
 
   GLX.BaseClasses,
-  GLX.Strings;
+  Scene.Strings;
 
 const
   RC_DDS_Type = RT_RCDATA;

+ 2 - 2
Source/FMX/GLX.ArchiveManager.pas

@@ -3,7 +3,7 @@
 //
 unit GLX.ArchiveManager;
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 interface
 
@@ -11,7 +11,7 @@ uses
   System.Classes,
   System.SysUtils,
 
-  GLX.Strings,
+  Scene.Strings,
   GLX.PersistentClasses,
   GLX.ApplicationFileIO;
 

+ 1 - 1
Source/FMX/GLX.AsyncHDS.pas

@@ -18,7 +18,7 @@ unit GLX.AsyncHDS;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 1 - 1
Source/FMX/GLX.AsyncTimer.pas

@@ -10,7 +10,7 @@ unit GLX.AsyncTimer;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 2 - 2
Source/FMX/GLX.Atmosphere.pas

@@ -13,7 +13,7 @@ unit GLX.Atmosphere;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,
@@ -25,7 +25,7 @@ uses
   GLX.Cadencer,
   GLX.VectorGeometry,
   GLX.Context,
-  GLX.Strings,
+  Scene.Strings,
   GLX.Color,
   GLX.RenderContextInfo,
   GLX.State,

+ 1 - 1
Source/FMX/GLX.BSP.pas

@@ -10,7 +10,7 @@ unit GLX.BSP;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.SysUtils,

+ 1 - 1
Source/FMX/GLX.BaseClasses.pas

@@ -11,7 +11,7 @@ uses
   System.Classes,
   System.SysUtils,
 
-  GLX.Strings,
+  Scene.Strings,
   GLX.PersistentClasses;
 
 type

+ 1 - 1
Source/FMX/GLX.BaseMeshSilhouette.pas

@@ -7,7 +7,7 @@ unit GLX.BaseMeshSilhouette;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 1 - 1
Source/FMX/GLX.Behaviours.pas

@@ -10,7 +10,7 @@ unit GLX.Behaviours;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 1 - 1
Source/FMX/GLX.BitmapFont.pas

@@ -7,7 +7,7 @@ unit GLX.BitmapFont;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,

+ 2 - 2
Source/FMX/GLX.Blur.pas

@@ -7,7 +7,7 @@ unit GLX.Blur;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,
@@ -32,7 +32,7 @@ uses
   GLX.Graphics,
   GLX.Context,
   GLX.State,
-  GLX.Strings,
+  Scene.Strings,
   GLX.TextureFormat,
   GLX.BaseClasses,
   GLX.RenderContextInfo;

+ 1 - 1
Source/FMX/GLX.BumpmapHDS.pas

@@ -11,7 +11,7 @@ unit GLX.BumpmapHDS;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 1 - 1
Source/FMX/GLX.Cadencer.pas

@@ -7,7 +7,7 @@ unit GLX.Cadencer;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.Windows,

+ 1 - 1
Source/FMX/GLX.Canvas.pas

@@ -11,7 +11,7 @@ unit GLX.Canvas;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,

+ 1 - 1
Source/FMX/GLX.CelShader.pas

@@ -11,7 +11,7 @@ unit GLX.CelShader;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,

+ 1 - 1
Source/FMX/GLX.Collision.pas

@@ -7,7 +7,7 @@ unit GLX.Collision;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,

+ 1 - 1
Source/FMX/GLX.Color.pas

@@ -7,7 +7,7 @@ unit GLX.Color;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,

+ 2 - 2
Source/FMX/GLX.Console.pas

@@ -35,7 +35,7 @@ unit GLX.Console;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.Windows,
@@ -48,7 +48,7 @@ uses
 
   GLX.VectorTypes,
   GLX.PersistentClasses,
-  GLX.Strings,
+  Scene.Strings,
 
   GLX.Coordinates,
   GLX.Scene,

+ 2 - 2
Source/FMX/GLX.Context.pas

@@ -10,7 +10,7 @@ unit GLX.Context;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,
@@ -30,7 +30,7 @@ uses
  // GXL.OpenGLx,
   GLX.Generics,
   GLX.VectorGeometry,
-  GLX.Strings,
+  Scene.Strings,
   GLX.VectorTypes,
   GLX.State,
   GLX.PipelineTransformation,

+ 2 - 2
Source/FMX/GLX.Coordinates.pas

@@ -7,7 +7,7 @@ unit GLX.Coordinates;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,
@@ -18,7 +18,7 @@ uses
   GLX.VectorGeometry,
   GLX.VectorTypes,
   GLX.BaseClasses,
-  GLX.Strings;
+  Scene.Strings;
 
 type
   (* Identifies the type of data stored within a TgxCustomCoordinates.

+ 2 - 2
Source/FMX/GLX.CurvesAndSurfaces.pas

@@ -7,12 +7,12 @@ unit GLX.CurvesAndSurfaces;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.SysUtils,
   System.Math,
-  GLX.Strings,
+  Scene.Strings,
   GLX.VectorGeometry,
   GLX.VectorLists;
 

+ 2 - 2
Source/FMX/GLX.DCE.pas

@@ -24,7 +24,7 @@ unit GLX.DCE;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   System.Classes,
@@ -36,7 +36,7 @@ uses
   GLX.BaseClasses,
   GLX.Manager,
   GLX.VectorTypes,
-  GLX.Strings,
+  Scene.Strings,
 
   GLX.Scene,
   GLX.VectorFileObjects,

+ 1 - 1
Source/FMX/GLX.DCEMisc.pas

@@ -7,7 +7,7 @@ unit GLX.DCEMisc;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   GLX.Coordinates,

+ 2 - 2
Source/FMX/GLX.DynamicTexture.pas

@@ -10,7 +10,7 @@ unit GLX.DynamicTexture;
 
 interface
 
-{$I GLX.Scene.inc}
+{$I Scene.inc}
 
 uses
   Winapi.OpenGL,
@@ -21,7 +21,7 @@ uses
   System.Types,
 
   GLX.VectorGeometry,
-  GLX.Strings,
+  Scene.Strings,
 
   GLX.Context,
   GLX.Texture,

Някои файлове не бяха показани, защото твърде много файлове са промени