GLHeightTileFileHDS.pas 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. unit GLHeightTileFileHDS;
  5. (* HeightDataSource for the HTF (HeightTileFile) format *)
  6. interface
  7. {$I GLScene.inc}
  8. uses
  9. System.Classes,
  10. System.SysUtils,
  11. GLHeightData,
  12. GLHeightTileFile;
  13. type
  14. // An Height Data Source for the HTF format.
  15. TGLHeightTileFileHDS = class (TGLHeightDataSource)
  16. private
  17. FInfiniteWrap : Boolean;
  18. FInverted : Boolean;
  19. FHTFFileName : String;
  20. FHTF : TGLHeightTileFile;
  21. FMinElevation : Integer;
  22. protected
  23. procedure SetHTFFileName(const val : String);
  24. procedure SetInfiniteWrap(val : Boolean);
  25. procedure SetInverted(val : Boolean);
  26. procedure SetMinElevation(val : Integer);
  27. public
  28. constructor Create(AOwner: TComponent); override;
  29. destructor Destroy; override;
  30. procedure StartPreparingData(HeightData : TGLHeightData); override;
  31. function Width :integer; override;
  32. function Height:integer; override;
  33. function OpenHTF:TGLHeightTileFile; //gives you direct access to the HTF object
  34. published
  35. {FileName of the HTF file.
  36. Note that it is accessed via the services of GLApplicationFileIO,
  37. so this may not necessarily be a regular file on a disk... }
  38. property HTFFileName : String read FHTFFileName write SetHTFFileName;
  39. {If true the height field is wrapped indefinetely. }
  40. property InfiniteWrap : Boolean read FInfiniteWrap write SetInfiniteWrap default True;
  41. {If true the height data is inverted.(Top to bottom) }
  42. property Inverted : Boolean read FInverted write SetInverted default True;
  43. {Minimum elevation of the tiles that are considered to exist.
  44. This property can typically be used to hide underwater tiles. }
  45. property MinElevation : Integer read FMinElevation write SetMinElevation default -32768;
  46. property MaxPoolSize;
  47. property DefaultHeight;
  48. end;
  49. // ------------------------------------------------------------------
  50. implementation
  51. // ------------------------------------------------------------------
  52. constructor TGLHeightTileFileHDS.Create(AOwner: TComponent);
  53. begin
  54. inherited Create(AOwner);
  55. FInfiniteWrap:=True;
  56. FInverted:=True;
  57. FMinElevation:=-32768;
  58. end;
  59. destructor TGLHeightTileFileHDS.Destroy;
  60. begin
  61. FHTF.Free;
  62. inherited Destroy;
  63. end;
  64. procedure TGLHeightTileFileHDS.SetHTFFileName(const val : String);
  65. begin
  66. if FHTFFileName<>val then begin
  67. MarkDirty;
  68. FreeAndNil(FHTF);
  69. FHTFFileName:=val;
  70. end;
  71. end;
  72. procedure TGLHeightTileFileHDS.SetInfiniteWrap(val : Boolean);
  73. begin
  74. if FInfiniteWrap=val then exit;
  75. FInfiniteWrap:=val;
  76. MarkDirty;
  77. end;
  78. procedure TGLHeightTileFileHDS.SetInverted(val : Boolean);
  79. begin
  80. if FInverted=Val then exit;
  81. FInverted:=val;
  82. MarkDirty;
  83. end;
  84. procedure TGLHeightTileFileHDS.SetMinElevation(val : Integer);
  85. begin
  86. if FMinElevation<>val then begin
  87. FMinElevation:=val;
  88. MarkDirty;
  89. end;
  90. end;
  91. // Tries to open the assigned HeightTileFile.
  92. //
  93. function TGLHeightTileFileHDS.OpenHTF:TGLHeightTileFile;
  94. begin
  95. if not Assigned(FHTF) then begin
  96. if FHTFFileName='' then FHTF:=nil
  97. else FHTF:=TGLHeightTileFile.Create(FHTFFileName);
  98. end;
  99. result:=FHTF;
  100. end;
  101. procedure TGLHeightTileFileHDS.StartPreparingData(HeightData : TGLHeightData);
  102. var
  103. oldType : TGLHeightDataType;
  104. htfTile : PHeightTile;
  105. htfTileInfo : PHeightTileInfo;
  106. x, y : Integer;
  107. YPos:integer;
  108. inY,outY:integer;
  109. PLineIn, PLineOut : ^PSmallIntArray;
  110. LineDataSize:integer;
  111. begin
  112. // access htf data
  113. if OpenHTF=nil then begin
  114. HeightData.DataState:=hdsNone;
  115. Exit;
  116. end else Assert(FHTF.TileSize=HeightData.Size,
  117. 'HTF TileSize and HeightData size don''t match.('+IntToStr(FHTF.TileSize)+' and '+Inttostr(HeightData.Size)+')');
  118. heightdata.DataState := hdsPreparing;
  119. // retrieve data and place it in the HeightData
  120. with HeightData do begin
  121. if Inverted then YPos:=YTop
  122. else YPos:=FHTF.SizeY-YTop-size+1;
  123. if InfiniteWrap then begin
  124. x:=XLeft mod FHTF.SizeX;
  125. if x<0 then x:=x+FHTF.SizeX;
  126. y:=YPos mod FHTF.SizeY;
  127. if y<0 then y:=y+FHTF.SizeY;
  128. htfTile:=FHTF.GetTile(x, y, @htfTileInfo);
  129. end else begin
  130. htfTile:=FHTF.GetTile(XLeft, YPos, @htfTileInfo);
  131. end;
  132. if (htfTile=nil) or (htfTileInfo.max<=FMinElevation) then begin
  133. // non-aligned tiles aren't handled (would be slow anyway)
  134. DataState:=hdsNone;
  135. end else begin
  136. oldType:=DataType;
  137. Allocate(hdtSmallInt);
  138. if Inverted then Move(htfTile.data[0], SmallIntData^, DataSize)
  139. else begin // invert the terrain (top to bottom) To compensate for the inverted terrain renderer
  140. LineDataSize:=DataSize div size;
  141. for y:=0 to size-1 do begin
  142. inY:=y*HeightData.Size;
  143. outY:=((size-1)-y)*HeightData.Size;
  144. PLineIn :[email protected][inY];
  145. PLineOut:[email protected][outY];
  146. Move(PLineIn^,PLineOut^,LineDataSize);
  147. end;
  148. end;
  149. //---Move(htfTile.data[0], SmallIntData^, DataSize);---
  150. if oldType<>hdtSmallInt then DataType:=oldType;
  151. TextureCoordinates(HeightData);
  152. inherited;
  153. HeightMin:=htfTileInfo.min;
  154. HeightMax:=htfTileInfo.max;
  155. end;
  156. end;
  157. end;
  158. function TGLHeightTileFileHDS.Width :integer;
  159. begin
  160. if OpenHTF=nil then result:=0
  161. else result:=FHTF.SizeX;
  162. end;
  163. function TGLHeightTileFileHDS.Height:integer;
  164. begin
  165. if OpenHTF=nil then result:=0
  166. else result:=FHTF.SizeY;
  167. end;
  168. // ------------------------------------------------------------------
  169. initialization
  170. // ------------------------------------------------------------------
  171. RegisterClasses([TGLHeightTileFileHDS]);
  172. end.