Formats.MD3.pas 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. //
  2. // The multimedia graphics platform GLScene https://github.com/glscene
  3. //
  4. unit Formats.MD3;
  5. (* File loading methods for the MD3 file format *)
  6. interface
  7. uses
  8. System.Classes,
  9. GLS.VectorTypes;
  10. type
  11. // Quake3 MD3 structure types
  12. TMD3Tag = record
  13. strName: array[0..63] of AnsiChar;
  14. vPosition: TVector3f;
  15. rotation: TMatrix3f;
  16. end;
  17. (* This part of the MD3 structure called 2 things:
  18. A frame and a bone. It doesn't matter because we don't use it *)
  19. (*
  20. TMD3Frame = record
  21. min_bound,max_bounds,
  22. local_origin : TVector3f;
  23. radius : single;
  24. name : array[0..15] of char;
  25. end;
  26. *)
  27. TMD3Bone = record
  28. mins,maxs,
  29. position: TVector3f;
  30. scale: single;
  31. creator: array[0..15] of AnsiChar;
  32. end;
  33. TMD3Triangle = record
  34. vertex: TVector3s; // value/64 to get real number position
  35. normal: TVector2b; // Latitude,Longitude
  36. end;
  37. TMD3Face = record
  38. vertexIndices: TVector3i;
  39. end;
  40. TMD3TexCoord = record
  41. textureCoord: TVector2f;
  42. end;
  43. TMD3Skin = record
  44. strName : array[0..63] of AnsiChar;
  45. shaderIndex: Integer;
  46. end;
  47. TMD3Header = record
  48. fileID : array[0..3] of AnsiChar;
  49. version : integer;
  50. strFile : array[0..63] of AnsiChar;
  51. flags,
  52. numFrames,
  53. numTags,
  54. numMeshes,
  55. numMaxSkins,
  56. headerSize,
  57. tagStart,
  58. tagEnd,
  59. fileSize : integer;
  60. end;
  61. TMD3MeshHeader = record
  62. meshID : array[0..3] of AnsiChar;
  63. strName : array[0..63] of AnsiChar;
  64. flags,
  65. numMeshFrames,
  66. numSkins,
  67. numVertices,
  68. numTriangles,
  69. triStart,
  70. headerSize,
  71. uvStart,
  72. vertexStart,
  73. meshSize : integer;
  74. end;
  75. TMD3MeshData = record
  76. MeshHeader : TMD3MeshHeader;
  77. Skins : array of TMD3Skin;
  78. Triangles : array of TMD3Face;
  79. TexCoords : array of TMD3TexCoord;
  80. Vertices : array of TMD3Triangle;
  81. end;
  82. // MD3 Main file class
  83. TFileMD3 = class
  84. public
  85. ModelHeader: TMD3Header;
  86. Bones : array of TMD3Bone;
  87. Tags : array of TMD3Tag;
  88. MeshData : array of TMD3MeshData;
  89. procedure LoadFromStream(aStream : TStream);
  90. end;
  91. // ------------------------------------------------------------------
  92. implementation
  93. // ------------------------------------------------------------------
  94. // ------------------
  95. // ------------------ TFileMD3 ------------------
  96. // ------------------
  97. procedure TFileMD3.LoadFromStream(aStream : TStream);
  98. var
  99. i : Integer;
  100. meshOffset : LongInt;
  101. begin
  102. aStream.Read(ModelHeader, sizeof(ModelHeader));
  103. // Test for correct file ID and version
  104. Assert(ModelHeader.fileID='IDP3','Incorrect MD3 file ID');
  105. Assert(ModelHeader.version=15,'Incorrect MD3 version number');
  106. // Read in the bones
  107. SetLength(Bones,ModelHeader.numFrames);
  108. aStream.Read(Bones[0],sizeof(TMD3Bone)*ModelHeader.numFrames);
  109. // Read in the Tags
  110. SetLength(Tags,ModelHeader.numFrames*ModelHeader.numTags);
  111. if ModelHeader.numTags > 0 then
  112. aStream.Read(Tags[0],sizeof(TMD3Tag)*ModelHeader.numFrames*ModelHeader.numTags);
  113. // Read in the Mesh data
  114. meshOffset:=aStream.Position;
  115. SetLength(MeshData,ModelHeader.numMeshes);
  116. for i:=0 to ModelHeader.numMeshes-1 do begin
  117. with MeshData[i] do begin
  118. aStream.Position:=meshOffset;
  119. aStream.Read(MeshHeader,sizeof(MeshHeader));
  120. // Set up the dynamic arrays
  121. SetLength(Skins,MeshHeader.numSkins);
  122. SetLength(Triangles,MeshHeader.numTriangles);
  123. SetLength(TexCoords,MeshHeader.numVertices);
  124. SetLength(Vertices,MeshHeader.numVertices*MeshHeader.numMeshFrames);
  125. // Skins
  126. aStream.read(Skins[0],sizeof(TMD3Skin)*MeshHeader.numSkins);
  127. // Face data
  128. aStream.Position:=meshOffset+MeshHeader.triStart;
  129. aStream.read(Triangles[0],sizeof(TMD3Face)*MeshHeader.numTriangles);
  130. // Texture coordinates
  131. aStream.Position:=meshOffset+meshHeader.uvStart;
  132. aStream.read(TexCoords[0],sizeof(TMD3TexCoord)*meshHeader.numVertices);
  133. // Vertices
  134. aStream.Position:=meshOffset+meshHeader.vertexStart;
  135. aStream.read(Vertices[0],sizeof(TMD3Triangle)*MeshHeader.numMeshFrames*MeshHeader.numVertices);
  136. // Increase the offset
  137. meshOffset:=meshOffset+MeshHeader.meshSize;
  138. end;
  139. end;
  140. end;
  141. end.