FileMD3.pas 4.3 KB

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