GLS.FileMD2.pas 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. //
  2. // The multimedia graphics platform GLScene https://github.com/glscene
  3. //
  4. unit GLS.FileMD2;
  5. (* Quake2 MD2 vector file format implementation. *)
  6. interface
  7. {$I GLScene.inc}
  8. uses
  9. System.Classes,
  10. System.SysUtils,
  11. GLS.VectorFileObjects,
  12. GLS.ApplicationFileIO,
  13. Formats.MD2;
  14. type
  15. (* The MD2 vector file (Quake2 actor file).
  16. Stores a set of "frames" describing the different postures of the actor,
  17. it may be animated by TGLActor. The "Skin" must be loaded indepentendly
  18. (the whole mesh uses a single texture bitmap).
  19. Based on code by Roger Cao. *)
  20. TGLMD2VectorFile = class(TGLVectorFile)
  21. public
  22. class function Capabilities: TGLDataFileCapabilities; override;
  23. procedure LoadFromStream(aStream: TStream); override;
  24. end;
  25. // ------------------------------------------------------------------
  26. implementation
  27. // ------------------------------------------------------------------
  28. // ------------------
  29. // ------------------ TGLMD2VectorFile ------------------
  30. // ------------------
  31. class function TGLMD2VectorFile.Capabilities: TGLDataFileCapabilities;
  32. begin
  33. Result := [dfcRead];
  34. end;
  35. procedure TGLMD2VectorFile.LoadFromStream(aStream: TStream);
  36. var
  37. i, j: Integer;
  38. MD2File: TFileMD2;
  39. mesh: TGLMorphableMeshObject;
  40. faceGroup: TFGIndexTexCoordList;
  41. morphTarget: TGLMeshMorphTarget;
  42. begin
  43. MD2File := TFileMD2.Create;
  44. MD2File.LoadFromStream(aStream);
  45. try
  46. // retrieve mesh data
  47. mesh := TGLMorphableMeshObject.CreateOwned(Owner.MeshObjects);
  48. with mesh, MD2File do
  49. begin
  50. Mode := momFaceGroups;
  51. faceGroup := TFGIndexTexCoordList.CreateOwned(FaceGroups);
  52. with faceGroup do
  53. begin
  54. MaterialName := '';
  55. VertexIndices.Capacity := iTriangles * 3;
  56. TexCoords.Capacity := iTriangles * 3;
  57. // copy the face list
  58. for i := 0 to iTriangles - 1 do
  59. with IndexList[i] do
  60. begin
  61. Add(a, a_s, -a_t);
  62. Add(b, b_s, -b_t);
  63. Add(c, c_s, -c_t);
  64. end;
  65. end;
  66. // retrieve frames data (morph targets)
  67. for i := 0 to iFrames - 1 do
  68. begin
  69. morphTarget := TGLMeshMorphTarget.CreateOwned(MorphTargets);
  70. with morphTarget do
  71. begin
  72. Name := 'Frame' + IntToStr(i);
  73. Vertices.Capacity := iVertices;
  74. for j := 0 to iVertices - 1 do
  75. Vertices.Add(VertexList[i][j]);
  76. BuildNormals(faceGroup.VertexIndices, momTriangles);
  77. end;
  78. end;
  79. end;
  80. if GetOwner is TGLActor then
  81. with TGLActor(GetOwner).Animations do
  82. begin
  83. Clear;
  84. with MD2File do
  85. for i := 0 to frameNames.Count - 1 do
  86. with Add do
  87. begin
  88. Name := frameNames[i];
  89. Reference := aarMorph;
  90. StartFrame := Integer(frameNames.Objects[i]);
  91. if i < frameNames.Count - 1 then
  92. EndFrame := Integer(frameNames.Objects[i + 1]) - 1
  93. else
  94. EndFrame := iFrames - 1;
  95. end;
  96. end;
  97. if mesh.MorphTargets.Count > 0 then
  98. mesh.MorphTo(0);
  99. finally
  100. MD2File.Free;
  101. end;
  102. end;
  103. // ------------------------------------------------------------------
  104. initialization
  105. // ------------------------------------------------------------------
  106. RegisterVectorFileFormat('md2', 'Quake II model files', TGLMD2VectorFile);
  107. end.