Formats.MD2.pas 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. //
  2. // The graphics platform GLScene https://github.com/glscene
  3. //
  4. unit Formats.MD2;
  5. (* Loading methods for MD2 file format *)
  6. interface
  7. {$R-}
  8. {$I Scena.inc}
  9. uses
  10. System.Classes,
  11. System.SysUtils,
  12. Scena.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. // ------------------------------------------------------------------
  84. implementation
  85. // ------------------------------------------------------------------
  86. // ------------------
  87. // ------------------ TFileMD2 ------------------
  88. // ------------------
  89. constructor TFileMD2.Create;
  90. begin
  91. inherited;
  92. FreeLists;
  93. FrameNames := TStringList.Create;
  94. end;
  95. destructor TFileMD2.Destroy;
  96. begin
  97. FreeLists;
  98. FrameNames.Free;
  99. inherited;
  100. end;
  101. procedure TFileMD2.FreeLists;
  102. begin
  103. SetLength(fIndexList,0);
  104. SetLength(fVertexList,0,0);
  105. FiFrames := 0;
  106. FiVertices := 0;
  107. FiTriangles := 0;
  108. end;
  109. procedure TFileMD2.LoadFromStream(aStream : TStream);
  110. var
  111. Skins: array[0..MAX_MD2_SKINS - 1, 0..63] of AnsiChar;
  112. TextureCoords: array[0..MAX_MD2_VERTICES - 1] of TVector2s;
  113. Buffer: array[0..MAX_MD2_VERTICES * 4 + 127] of byte;
  114. Header: TMD2Header;
  115. Triangle: TMD2Triangle;
  116. I: integer;
  117. J: integer;
  118. Frame: PMD2AliasFrame;
  119. FrameName : String;
  120. begin
  121. FreeLists;
  122. // read the modelinfo
  123. aStream.Read(Header, SizeOf(Header));
  124. FiFrames := Header.Num_Frames;
  125. FiVertices := Header.Num_Vertices;
  126. FiTriangles := Header.Num_VertexIndices;
  127. SetLength(fIndexList, FiTriangles);
  128. SetLength(fVertexList, FiFrames, FiVertices);
  129. // get the skins...
  130. aStream.Read(Skins, Header.Num_Skins * MAX_MD2_SKINNAME);
  131. // ...and the texcoords
  132. aStream.Read(TextureCoords, Header.Num_TextureCoords * SizeOf(TVector2s));
  133. for I := 0 to Header.Num_VertexIndices - 1 do begin
  134. aStream.Read(Triangle, SizeOf(TMD2Triangle));
  135. with fIndexList[I] do begin
  136. A := Triangle.VertexIndex.Z;
  137. B := Triangle.VertexIndex.Y;
  138. C := Triangle.VertexIndex.X;
  139. A_S := TextureCoords[Triangle.TextureCoordIndex.Z].X / Header.SkinWidth;
  140. A_T := TextureCoords[Triangle.TextureCoordIndex.Z].Y / Header.SkinHeight;
  141. B_S := TextureCoords[Triangle.TextureCoordIndex.Y].X / Header.SkinWidth;
  142. B_T := TextureCoords[Triangle.TextureCoordIndex.Y].Y / Header.SkinHeight;
  143. C_S := TextureCoords[Triangle.TextureCoordIndex.X].X / Header.SkinWidth;
  144. C_T := TextureCoords[Triangle.TextureCoordIndex.X].Y / Header.SkinHeight;
  145. end;
  146. end;
  147. for I := 0 to Header.Num_Frames - 1 do begin
  148. Frame := PMD2AliasFrame(@Buffer);
  149. // read animation / frame info
  150. aStream.Read(Frame^, Header.FrameSize);
  151. FrameName := Trim(String(Frame^.Name));
  152. if CharInSet(Copy(FrameName, Length(FrameName) - 1, 1)[1], ['0'..'9']) then
  153. FrameName := Copy(FrameName, 1, Length(FrameName) - 2)
  154. else
  155. FrameName := Copy(FrameName, 1, Length(FrameName) - 1);
  156. if FrameNames.IndexOf(FrameName) < 0 then
  157. FrameNames.AddObject(FrameName, TObject(Cardinal(I)));
  158. // fill the vertices list
  159. for J := 0 to FiVertices - 1 do begin
  160. fVertexList[i][J].X := Frame^.Vertices[J].Vert[0] * Frame^.Scale.X + Frame^.Translate.X;
  161. fVertexList[i][J].Y := Frame^.Vertices[J].Vert[1] * Frame^.Scale.Y + Frame^.Translate.Y;
  162. fVertexList[i][J].Z := Frame^.Vertices[J].Vert[2] * Frame^.Scale.Z + Frame^.Translate.Z;
  163. end;
  164. end;
  165. end;
  166. end.