2
0

GLS.FileNMF.pas 4.4 KB

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