Formatx.MD2.pas 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. //
  2. // The graphics engine GXScene
  3. //
  4. unit Formatx.MD2;
  5. (* Loading methods for MD2 file format *)
  6. interface
  7. {$R-}
  8. {$I Stage.Defines.inc}
  9. uses
  10. System.Classes,
  11. System.SysUtils,
  12. Stage.VectorTypes;
  13. const
  14. MAX_MD2_TRIANGLES = 4096;
  15. MAX_MD2_VERTICES = 2048;
  16. MAX_MD2_FRAMES = 512;
  17. MAX_MD2_SKINS = 32;
  18. MAX_MD2_SKINNAME = 64;
  19. type
  20. PMD2VertexIndex = ^TMD2VertexIndex;
  21. TMD2VertexIndex = record
  22. A, B, C: integer;
  23. A_S, A_T,
  24. B_S, B_T,
  25. C_S, C_T: single;
  26. end;
  27. TMD2Triangle = record
  28. VertexIndex: TVector3s;
  29. TextureCoordIndex: TVector3s;
  30. end;
  31. TMD2TriangleVertex = record
  32. Vert: array[0..2] of byte;
  33. LightnormalIndex: byte;
  34. end;
  35. PMD2AliasFrame = ^TMD2AliasFrame;
  36. TMD2AliasFrame = record
  37. Scale: TVector3f;
  38. Translate: TVector3f;
  39. Name: array[0..15] of AnsiChar;
  40. Vertices: array[0..0] of TMD2TriangleVertex;
  41. end;
  42. TMD2Header = record
  43. Ident: integer;
  44. Version: integer;
  45. SkinWidth: integer;
  46. SkinHeight: integer;
  47. FrameSize: integer;
  48. Num_Skins: integer;
  49. Num_Vertices: integer;
  50. Num_TextureCoords: integer;
  51. Num_VertexIndices: integer;
  52. Num_GLCommdands: integer;
  53. Num_Frames: integer;
  54. Offset_skins: integer;
  55. Offset_st: integer;
  56. Offset_tris: integer;
  57. Offset_frames: integer;
  58. Offset_glcmds: integer;
  59. Offset_end: integer;
  60. end;
  61. TIndexList = array of TMD2VertexIndex;
  62. TGLVertexList = array of array of TVector3f;
  63. type
  64. TFileMD2 = class
  65. private
  66. FiFrames: longint;
  67. FiVertices: longint;
  68. FiTriangles: longint;
  69. procedure FreeLists;
  70. public
  71. fIndexList : TIndexList;
  72. fVertexList : TGLVertexList;
  73. FrameNames : TStrings;
  74. constructor Create; virtual;
  75. destructor Destroy; override;
  76. procedure LoadFromStream(aStream : TStream);
  77. property iFrames: longInt read FiFrames;
  78. property iVertices: longInt read FiVertices;
  79. property iTriangles: longInt read FiTriangles;
  80. property IndexList: TIndexList read fIndexList;
  81. property VertexList: TGLVertexList read fVertexList;
  82. end;
  83. implementation // ------------------------------------------------------------
  84. // ------------------
  85. // ------------------ TFileMD2 ------------------
  86. // ------------------
  87. constructor TFileMD2.Create;
  88. begin
  89. inherited;
  90. FreeLists;
  91. FrameNames := TStringList.Create;
  92. end;
  93. destructor TFileMD2.Destroy;
  94. begin
  95. FreeLists;
  96. FrameNames.Free;
  97. inherited;
  98. end;
  99. procedure TFileMD2.FreeLists;
  100. begin
  101. SetLength(fIndexList,0);
  102. SetLength(fVertexList,0,0);
  103. FiFrames := 0;
  104. FiVertices := 0;
  105. FiTriangles := 0;
  106. end;
  107. procedure TFileMD2.LoadFromStream(aStream : TStream);
  108. var
  109. Skins: array[0..MAX_MD2_SKINS - 1, 0..63] of AnsiChar;
  110. TextureCoords: array[0..MAX_MD2_VERTICES - 1] of TVector2s;
  111. Buffer: array[0..MAX_MD2_VERTICES * 4 + 127] of byte;
  112. Header: TMD2Header;
  113. Triangle: TMD2Triangle;
  114. I: integer;
  115. J: integer;
  116. Frame: PMD2AliasFrame;
  117. FrameName : String;
  118. begin
  119. FreeLists;
  120. // read the modelinfo
  121. aStream.Read(Header, SizeOf(Header));
  122. FiFrames := Header.Num_Frames;
  123. FiVertices := Header.Num_Vertices;
  124. FiTriangles := Header.Num_VertexIndices;
  125. SetLength(fIndexList, FiTriangles);
  126. SetLength(fVertexList, FiFrames, FiVertices);
  127. // get the skins...
  128. aStream.Read(Skins, Header.Num_Skins * MAX_MD2_SKINNAME);
  129. // ...and the texcoords
  130. aStream.Read(TextureCoords, Header.Num_TextureCoords * SizeOf(TVector2s));
  131. for I := 0 to Header.Num_VertexIndices - 1 do begin
  132. aStream.Read(Triangle, SizeOf(TMD2Triangle));
  133. with fIndexList[I] do begin
  134. A := Triangle.VertexIndex.Z;
  135. B := Triangle.VertexIndex.Y;
  136. C := Triangle.VertexIndex.X;
  137. A_S := TextureCoords[Triangle.TextureCoordIndex.Z].X / Header.SkinWidth;
  138. A_T := TextureCoords[Triangle.TextureCoordIndex.Z].Y / Header.SkinHeight;
  139. B_S := TextureCoords[Triangle.TextureCoordIndex.Y].X / Header.SkinWidth;
  140. B_T := TextureCoords[Triangle.TextureCoordIndex.Y].Y / Header.SkinHeight;
  141. C_S := TextureCoords[Triangle.TextureCoordIndex.X].X / Header.SkinWidth;
  142. C_T := TextureCoords[Triangle.TextureCoordIndex.X].Y / Header.SkinHeight;
  143. end;
  144. end;
  145. for I := 0 to Header.Num_Frames - 1 do begin
  146. Frame := PMD2AliasFrame(@Buffer);
  147. // read animation / frame info
  148. aStream.Read(Frame^, Header.FrameSize);
  149. FrameName := Trim(String(Frame^.Name));
  150. if CharInSet(Copy(FrameName, Length(FrameName) - 1, 1)[1], ['0'..'9']) then
  151. FrameName := Copy(FrameName, 1, Length(FrameName) - 2)
  152. else
  153. FrameName := Copy(FrameName, 1, Length(FrameName) - 1);
  154. if FrameNames.IndexOf(FrameName) < 0 then
  155. FrameNames.AddObject(FrameName, TObject(Cardinal(I)));
  156. // fill the vertices list
  157. for J := 0 to FiVertices - 1 do begin
  158. fVertexList[i][J].X := Frame^.Vertices[J].Vert[0] * Frame^.Scale.X + Frame^.Translate.X;
  159. fVertexList[i][J].Y := Frame^.Vertices[J].Vert[1] * Frame^.Scale.Y + Frame^.Translate.Y;
  160. fVertexList[i][J].Z := Frame^.Vertices[J].Vert[2] * Frame^.Scale.Z + Frame^.Translate.Z;
  161. end;
  162. end;
  163. end;
  164. //---------------------------------------------------------------------------
  165. end.