2
0

GLS.FileX.pas 4.6 KB

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