GXS.FileNMF.pas 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. //
  2. // The graphics engine GLXEngine. The unit of GXScene for Delphi
  3. //
  4. unit GXS.FileNMF;
  5. (* NormalMapper loading into GLScene FreeForms/Actors *)
  6. interface
  7. uses
  8. System.Classes,
  9. Stage.VectorTypes,
  10. GXS.VectorFileObjects,
  11. Stage.VectorGeometry,
  12. GXS.VectorLists,
  13. GXS.ApplicationFileIO;
  14. const
  15. NMF_HEADER_TAG = 'NMF ';
  16. NMF_TRIANGLE_TAG = 'TRIS';
  17. type
  18. TNmHeader = record
  19. hdr: array [0 .. 3] of AnsiChar;
  20. size: cardinal;
  21. end;
  22. TNmRawTriangle = record
  23. vert, norm: array [0 .. 2] of TAffineVector;
  24. texCoord: array [0 .. 2] of TTexPoint;
  25. end;
  26. TFileNMF = class
  27. public
  28. FileHeader, TrisHeader: TNmHeader;
  29. NumTris: Integer;
  30. RawTriangles: array of TNmRawTriangle;
  31. procedure LoadFromStream(Stream: TStream);
  32. procedure SaveToStream(Stream: TStream);
  33. end;
  34. type
  35. TgxNMFVectorFile = class(TgxVectorFile)
  36. public
  37. class function Capabilities: TDataFileCapabilities; override;
  38. procedure LoadFromStream(aStream: TStream); override;
  39. procedure SaveToStream(aStream: TStream); override;
  40. end;
  41. // ------------------------------------------------------------------
  42. implementation
  43. // ------------------------------------------------------------------
  44. procedure TFileNMF.LoadFromStream(Stream: TStream);
  45. var
  46. Done: Boolean;
  47. begin
  48. Stream.Read(FileHeader, SizeOf(TNmHeader));
  49. if FileHeader.hdr <> NMF_HEADER_TAG then
  50. exit;
  51. Done := False;
  52. while not Done do
  53. begin
  54. Stream.Read(TrisHeader, SizeOf(TNmHeader));
  55. if TrisHeader.hdr = NMF_TRIANGLE_TAG then
  56. begin
  57. Stream.Read(NumTris, SizeOf(NumTris));
  58. if NumTris < 0 then
  59. exit;
  60. SetLength(RawTriangles, NumTris);
  61. Stream.Read(RawTriangles[0], SizeOf(TNmRawTriangle) * NumTris);
  62. Done := True;
  63. end;
  64. end;
  65. end;
  66. procedure TFileNMF.SaveToStream(Stream: TStream);
  67. begin
  68. NumTris := Length(RawTriangles);
  69. TrisHeader.hdr := NMF_TRIANGLE_TAG;
  70. TrisHeader.size := SizeOf(TNmRawTriangle) * NumTris + SizeOf(FileHeader);
  71. FileHeader.hdr := NMF_HEADER_TAG;
  72. FileHeader.size := TrisHeader.size + SizeOf(TrisHeader);
  73. Stream.Write(FileHeader, SizeOf(TNmHeader));
  74. Stream.Write(TrisHeader, SizeOf(TNmHeader));
  75. NumTris := Length(RawTriangles);
  76. Stream.Write(NumTris, SizeOf(NumTris));
  77. Stream.Write(RawTriangles[0], SizeOf(TNmRawTriangle) * NumTris);
  78. end;
  79. // ------------------
  80. // ------------------ TgxNMFVectorFile ------------------
  81. // ------------------
  82. class function TgxNMFVectorFile.Capabilities: TDataFileCapabilities;
  83. begin
  84. Result := [dfcRead, dfcWrite];
  85. end;
  86. // LoadFromStream
  87. //
  88. procedure TgxNMFVectorFile.LoadFromStream(aStream: TStream);
  89. var
  90. i, j: Integer;
  91. mesh: TgxMeshObject;
  92. nmf: TFileNMF;
  93. begin
  94. nmf := TFileNMF.Create;
  95. try
  96. nmf.LoadFromStream(aStream);
  97. mesh := TgxMeshObject.CreateOwned(Owner.MeshObjects);
  98. mesh.Mode := momTriangles;
  99. for i := 0 to nmf.NumTris - 1 do
  100. begin
  101. for j := 0 to 2 do
  102. begin
  103. mesh.Vertices.Add(nmf.RawTriangles[i].vert[j]);
  104. mesh.Normals.Add(nmf.RawTriangles[i].norm[j]);
  105. mesh.TexCoords.Add(nmf.RawTriangles[i].texCoord[j]);
  106. end;
  107. end;
  108. finally
  109. nmf.Free;
  110. end;
  111. end;
  112. // SaveToStream
  113. //
  114. procedure TgxNMFVectorFile.SaveToStream(aStream: TStream);
  115. var
  116. i, j: Integer;
  117. nmf: TFileNMF;
  118. Vertices, TempVertices, Normals, TexCoords: TgxAffineVectorList;
  119. begin
  120. nmf := TFileNMF.Create;
  121. Vertices := TgxAffineVectorList.Create;
  122. Normals := TgxAffineVectorList.Create;
  123. TexCoords := TgxAffineVectorList.Create;
  124. try
  125. for i := 0 to Owner.MeshObjects.Count - 1 do
  126. begin
  127. TempVertices := Owner.MeshObjects[i].ExtractTriangles(TexCoords, Normals);
  128. Vertices.Add(TempVertices);
  129. TempVertices.Free;
  130. end;
  131. nmf.NumTris := (Vertices.Count div 3);
  132. SetLength(nmf.RawTriangles, nmf.NumTris);
  133. for i := 0 to nmf.NumTris - 1 do
  134. begin
  135. for j := 0 to 2 do
  136. begin
  137. nmf.RawTriangles[i].vert[j] := Vertices[3 * i + j];
  138. nmf.RawTriangles[i].norm[j] := Normals[3 * i + j];
  139. nmf.RawTriangles[i].texCoord[j].S := TexCoords[3 * i + j].X;
  140. nmf.RawTriangles[i].texCoord[j].T := TexCoords[3 * i + j].Y;
  141. end;
  142. end;
  143. nmf.SaveToStream(aStream);
  144. finally
  145. Vertices.Free;
  146. Normals.Free;
  147. TexCoords.Free;
  148. nmf.Free;
  149. end;
  150. end;
  151. // ------------------------------------------------------------------
  152. // ------------------------------------------------------------------
  153. // ------------------------------------------------------------------
  154. initialization
  155. // ------------------------------------------------------------------
  156. // ------------------------------------------------------------------
  157. // ------------------------------------------------------------------
  158. RegisterVectorFileFormat('nmf', 'NormalMapper files', TgxNMFVectorFile);
  159. end.