GXS.FileX.pas 4.6 KB

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