GLFileX.pas 4.9 KB

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