GXS.FileMD3.pas 4.4 KB

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