GLFileX.pas 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. unit GLFileX;
  5. (* Simple X format support for Delphi (Microsoft's favorite format) *)
  6. interface
  7. {$I GLScene.inc}
  8. uses
  9. System.Classes,
  10. System.SysUtils,
  11. GLVectorTypes,
  12. GLVectorFileObjects,
  13. GLApplicationFileIO,
  14. GLVectorGeometry,
  15. GLTexture,
  16. GLVectorLists,
  17. GLMaterial,
  18. // Misc
  19. FileX;
  20. type
  21. TGLXVectorFile = class(TGLVectorFile)
  22. public
  23. class function Capabilities: TGLDataFileCapabilities; override;
  24. procedure LoadFromStream(aStream: TStream); override;
  25. end;
  26. // -------------------------------------------------------------
  27. implementation
  28. // -------------------------------------------------------------
  29. class function TGLXVectorFile.Capabilities: TGLDataFileCapabilities;
  30. begin
  31. Result := [dfcRead];
  32. end;
  33. procedure TGLXVectorFile.LoadFromStream(aStream: TStream);
  34. var
  35. DXFile: TDXFile;
  36. procedure RecursDXFile(DXNode: TDXNode);
  37. var
  38. i, j, k, l, vertcount: integer;
  39. mo: TMeshObject;
  40. mat: TMatrix;
  41. libmat: TGLLibMaterial;
  42. fg: TFGVertexNormalTexIndexList;
  43. str: String;
  44. begin
  45. mat := IdentityHMGMatrix;
  46. if Assigned(DXNode.Owner) then
  47. if DXNode.Owner is TDXFrame then
  48. begin
  49. mat := TDXFrame(DXNode.Owner).GlobalMatrix;
  50. TransposeMatrix(mat);
  51. end;
  52. if DXNode is TDXMesh then
  53. begin
  54. mo := TMeshObject.CreateOwned(Owner.MeshObjects);
  55. mo.Mode := momFaceGroups;
  56. mo.Vertices.Assign(TDXMesh(DXNode).Vertices);
  57. mo.Vertices.TransformAsPoints(mat);
  58. mo.Normals.Assign(TDXMesh(DXNode).Normals);
  59. mo.Normals.TransformAsVectors(mat);
  60. mo.TexCoords.Assign(TDXMesh(DXNode).TexCoords);
  61. if TDXMesh(DXNode).MaterialList.Count > 0 then
  62. begin
  63. // Add the materials
  64. if (Owner.UseMeshMaterials) and Assigned(Owner.MaterialLibrary) then
  65. begin
  66. for i := 0 to TDXMesh(DXNode).MaterialList.Count - 1 do
  67. begin
  68. str := TDXMesh(DXNode).MaterialList.Items[i].Texture;
  69. if FileExists(str) then
  70. libmat := Owner.MaterialLibrary.AddTextureMaterial('', str)
  71. else
  72. libmat := Owner.MaterialLibrary.Materials.Add;
  73. libmat.Name := Format('%s_%d', [DXNode.Name, i]);
  74. with libmat.Material.FrontProperties do
  75. begin
  76. Diffuse.Color := TDXMesh(DXNode).MaterialList.Items[i].Diffuse;
  77. Shininess := Round(TDXMesh(DXNode).MaterialList.Items[i]
  78. .SpecPower / 2);
  79. Specular.Color :=
  80. VectorMake(TDXMesh(DXNode).MaterialList.Items[i].Specular);
  81. Emission.Color :=
  82. VectorMake(TDXMesh(DXNode).MaterialList.Items[i].Emissive);
  83. end;
  84. end;
  85. end;
  86. // Add the facegroups (separate since material library
  87. // can be unassigned)
  88. for i := 0 to TDXMesh(DXNode).MaterialList.Count - 1 do
  89. begin
  90. fg := TFGVertexNormalTexIndexList.CreateOwned(mo.FaceGroups);
  91. fg.MaterialName := Format('%s_%d', [DXNode.Name, i]);
  92. end;
  93. // Now add the indices per material
  94. vertcount := 0;
  95. for i := 0 to TDXMesh(DXNode).VertCountIndices.Count - 1 do
  96. begin
  97. if (i < TDXMesh(DXNode).MaterialIndices.Count) then
  98. begin
  99. j := TDXMesh(DXNode).MaterialIndices[i];
  100. k := TDXMesh(DXNode).VertCountIndices[i];
  101. for l := vertcount to vertcount + k - 1 do
  102. begin
  103. TFGVertexNormalTexIndexList(mo.FaceGroups[j])
  104. .VertexIndices.Add(TDXMesh(DXNode).VertexIndices[l]);
  105. if mo.TexCoords.Count > 0 then
  106. TFGVertexNormalTexIndexList(mo.FaceGroups[j])
  107. .TexCoordIndices.Add(TDXMesh(DXNode).VertexIndices[l]);
  108. if TDXMesh(DXNode).NormalIndices.Count > 0 then
  109. TFGVertexNormalTexIndexList(mo.FaceGroups[j])
  110. .NormalIndices.Add(TDXMesh(DXNode).NormalIndices[l])
  111. end;
  112. vertcount := vertcount + k;
  113. end;
  114. end;
  115. end
  116. else
  117. begin
  118. fg := TFGVertexNormalTexIndexList.CreateOwned(mo.FaceGroups);
  119. fg.NormalIndices.Assign(TDXMesh(DXNode).NormalIndices);
  120. fg.VertexIndices.Assign(TDXMesh(DXNode).VertexIndices);
  121. end;
  122. end;
  123. for i := 0 to DXNode.Count - 1 do
  124. RecursDXFile(TDXNode(DXNode[i]));
  125. end;
  126. begin
  127. DXFile := TDXFile.Create;
  128. try
  129. DXFile.LoadFromStream(aStream);
  130. RecursDXFile(DXFile.RootNode);
  131. finally
  132. DXFile.Free;
  133. end;
  134. end;
  135. //--------------------------------------------------------
  136. initialization
  137. //--------------------------------------------------------
  138. RegisterVectorFileFormat('x', 'DirectX Model files', TGLXVectorFile);
  139. end.