2
0

GLFileMD3.pas 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. {
  5. Code for loading animated MD3 files into GLScene
  6. FreeForms and Actors.
  7. }
  8. unit GLFileMD3;
  9. interface
  10. uses
  11. System.Classes,
  12. System.SysUtils,
  13. GLVectorFileObjects,
  14. GLMaterial,
  15. GLApplicationFileIO,
  16. GLVectorGeometry,
  17. FileMD3,
  18. GLTexture;
  19. type
  20. TGLMD3VectorFile = class (TGLVectorFile)
  21. public
  22. class function Capabilities : TGLDataFileCapabilities; override;
  23. procedure LoadFromStream(aStream : TStream); override;
  24. end;
  25. // ------------------------------------------------------------------
  26. implementation
  27. // ------------------------------------------------------------------
  28. // ------------------
  29. // ------------------ TGLMD3VectorFile ------------------
  30. // ------------------
  31. class function TGLMD3VectorFile.Capabilities : TGLDataFileCapabilities;
  32. begin
  33. Result:=[dfcRead];
  34. end;
  35. procedure TGLMD3VectorFile.LoadFromStream(aStream : TStream);
  36. var
  37. i,j,k,
  38. numVerts,
  39. numtris : Integer;
  40. MD3File : TFileMD3;
  41. mesh : TGLMorphableMeshObject;
  42. faceGroup : TFGIndexTexCoordList;
  43. morphTarget : TGLMeshMorphTarget;
  44. function GetNormalFromMD3Normal(n : array of Byte) : TAffineVector;
  45. var
  46. lat,lng : single;
  47. begin
  48. // The MD3 normal is a latitude/longitude value that needs
  49. // to be calculated into cartesian space.
  50. lat:=(n[1])*(2*pi)/255; lng:=(n[0])*(2*pi)/255;
  51. result.X:=cos(lat)*sin(lng);
  52. result.Y:=sin(lat)*sin(lng);
  53. result.Z:=cos(lng);
  54. end;
  55. procedure AllocateMaterial(meshname:string);
  56. var
  57. LibMat : TGLLibMaterial;
  58. begin
  59. // If a material library is assigned to the actor/freeform the
  60. // mesh name will be added as a material.
  61. if Assigned(Owner.MaterialLibrary) then with Owner.MaterialLibrary do begin
  62. if Assigned(Materials.GetLibMaterialByName(meshname)) then exit;
  63. LibMat:=Materials.Add;
  64. LibMat.name:=meshname;
  65. LibMat.Material.Texture.Disabled:=False;
  66. end;
  67. end;
  68. begin
  69. MD3File:=TFileMD3.Create;
  70. MD3File.LoadFromStream(aStream);
  71. try
  72. for i:=0 to MD3File.ModelHeader.numMeshes-1 do begin
  73. mesh:=TGLMorphableMeshObject.CreateOwned(Owner.MeshObjects);
  74. mesh.Name:=trim(string(MD3File.MeshData[i].MeshHeader.strName));
  75. with mesh, MD3File do begin
  76. Mode:=momFaceGroups;
  77. faceGroup:=TFGIndexTexCoordList.CreateOwned(FaceGroups);
  78. with faceGroup do begin
  79. AllocateMaterial(mesh.Name);
  80. MaterialName:=mesh.Name;
  81. numTris:=MeshData[i].MeshHeader.numTriangles;
  82. VertexIndices.Capacity:=numTris*3;
  83. TexCoords.Capacity:=numTris*3;
  84. // Get the vertex indices and texture coordinates
  85. for j:=0 to MeshData[i].MeshHeader.numTriangles-1 do begin
  86. with MeshData[i].Triangles[j] do begin
  87. Add(vertexIndices.X,
  88. MeshData[i].TexCoords[vertexIndices.X].textureCoord.X,
  89. 1-MeshData[i].TexCoords[vertexIndices.X].textureCoord.Y);
  90. Add(vertexIndices.Z,
  91. MeshData[i].TexCoords[vertexIndices.Z].textureCoord.X,
  92. 1-MeshData[i].TexCoords[vertexIndices.Z].textureCoord.Y);
  93. Add(vertexIndices.Y,
  94. MeshData[i].TexCoords[vertexIndices.Y].textureCoord.X,
  95. 1-MeshData[i].TexCoords[vertexIndices.Y].textureCoord.Y);
  96. end;
  97. end;
  98. end;
  99. // Get the mesh data for each morph frame
  100. for j:=0 to ModelHeader.numFrames-1 do begin
  101. morphTarget:=TGLMeshMorphTarget.CreateOwned(MorphTargets);
  102. morphTarget.Name:=Trim(string(MeshData[i].MeshHeader.strName))+'['+IntToStr(j)+']';
  103. numVerts:=MeshData[i].MeshHeader.numVertices;
  104. morphTarget.Vertices.Capacity:=numVerts;
  105. for k:=numVerts*j to numVerts*(j+1)-1 do begin
  106. morphTarget.Vertices.Add(
  107. MeshData[i].Vertices[k].Vertex.X/64,
  108. MeshData[i].Vertices[k].Vertex.Y/64,
  109. MeshData[i].Vertices[k].Vertex.Z/64);
  110. morphTarget.Normals.Add(
  111. GetNormalFromMD3Normal(MeshData[i].Vertices[k].normal.V));
  112. end;
  113. end;
  114. end;
  115. if mesh.MorphTargets.Count>0 then
  116. mesh.MorphTo(0);
  117. end;
  118. finally
  119. MD3File.Free;
  120. end;
  121. end;
  122. // ------------------------------------------------------------------
  123. initialization
  124. // ------------------------------------------------------------------
  125. RegisterVectorFileFormat('md3', 'MD3 files', TGLMD3VectorFile);
  126. end.