fHTFpackD.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. unit fHTFpackD;
  2. interface
  3. uses
  4. Winapi.Windows,
  5. System.SysUtils,
  6. System.Classes,
  7. System.Actions,
  8. System.Math,
  9. System.ImageList,
  10. Vcl.Graphics,
  11. Vcl.Controls,
  12. Vcl.Forms,
  13. Vcl.Dialogs,
  14. ValEdit,
  15. Vcl.Grids,
  16. Vcl.Menus,
  17. Vcl.StdCtrls,
  18. Vcl.ComCtrls,
  19. Vcl.ToolWin,
  20. Vcl.ExtCtrls,
  21. Vcl.ActnList,
  22. Vcl.ImgList,
  23. GLS.HeightTileFileHDS;
  24. type
  25. TSrc = record
  26. fs: TFileStream;
  27. x, y, w, h: Integer;
  28. format: Integer;
  29. FlipRotate: Integer;
  30. end;
  31. PSrc = ^TSrc;
  32. TMainForm = class(TForm)
  33. MainMenu: TMainMenu;
  34. StringGrid: TStringGrid;
  35. File1: TMenuItem;
  36. ActionList: TActionList;
  37. ImageList: TImageList;
  38. ACOpen: TAction;
  39. ACSave: TAction;
  40. ACExit: TAction;
  41. Open1: TMenuItem;
  42. Save1: TMenuItem;
  43. N1: TMenuItem;
  44. Exit1: TMenuItem;
  45. Panel1: TPanel;
  46. Label1: TLabel;
  47. Label2: TLabel;
  48. EDHTFName: TEdit;
  49. EDDEMPath: TEdit;
  50. BUDEMPath: TButton;
  51. BUPickHTF: TButton;
  52. ToolBar: TToolBar;
  53. ToolButton1: TToolButton;
  54. ToolButton2: TToolButton;
  55. ToolButton3: TToolButton;
  56. DEMs1: TMenuItem;
  57. ACNewDEM: TAction;
  58. ACRemoveDEM: TAction;
  59. ToolButton4: TToolButton;
  60. ToolButton5: TToolButton;
  61. AddDEMsource1: TMenuItem;
  62. RemoveDEMsource1: TMenuItem;
  63. SDHTF: TSaveDialog;
  64. PopupMenu: TPopupMenu;
  65. AddDEMsource2: TMenuItem;
  66. RemoveDEMsource2: TMenuItem;
  67. MIAbout: TMenuItem;
  68. CBType: TComboBox;
  69. CBFile: TComboBox;
  70. Label3: TLabel;
  71. EDSizeX: TEdit;
  72. EDSizeY: TEdit;
  73. Label4: TLabel;
  74. Label5: TLabel;
  75. EDDefaultZ: TEdit;
  76. ODTerrainPack: TOpenDialog;
  77. SDTerrainPack: TSaveDialog;
  78. ToolButton6: TToolButton;
  79. ACProcess: TAction;
  80. ToolButton7: TToolButton;
  81. N2: TMenuItem;
  82. Process1: TMenuItem;
  83. PanelFoot: TPanel;
  84. ProgressBar: TProgressBar;
  85. EDTileSize: TEdit;
  86. Label6: TLabel;
  87. ToolButton8: TToolButton;
  88. ACViewer: TAction;
  89. N3: TMenuItem;
  90. HTFViewer1: TMenuItem;
  91. ToolButton9: TToolButton;
  92. ODPath: TOpenDialog;
  93. Label7: TLabel;
  94. EDTileOverlap: TEdit;
  95. Label8: TLabel;
  96. EDZFilter: TEdit;
  97. Label9: TLabel;
  98. EDZScale: TEdit;
  99. CBWholeOnly: TCheckBox;
  100. CBFlipRotate: TComboBox;
  101. procedure ACExitExecute(Sender: TObject);
  102. procedure FormCreate(Sender: TObject);
  103. procedure BUDEMPathClick(Sender: TObject);
  104. procedure BUPickHTFClick(Sender: TObject);
  105. procedure MIAboutClick(Sender: TObject);
  106. procedure ActionListUpdate(Action: TBasicAction; var Handled: Boolean);
  107. procedure ACNewDEMExecute(Sender: TObject);
  108. procedure ACRemoveDEMExecute(Sender: TObject);
  109. procedure StringGridSelectCell(Sender: TObject; ACol, ARow: Integer;
  110. var CanSelect: Boolean);
  111. procedure CBTypeChange(Sender: TObject);
  112. procedure ACSaveExecute(Sender: TObject);
  113. procedure ACOpenExecute(Sender: TObject);
  114. procedure EDDEMPathChange(Sender: TObject);
  115. procedure FormDestroy(Sender: TObject);
  116. procedure EDDefaultZChange(Sender: TObject);
  117. procedure ACProcessExecute(Sender: TObject);
  118. procedure ACViewerExecute(Sender: TObject);
  119. procedure EDZFilterChange(Sender: TObject);
  120. procedure EDZScaleChange(Sender: TObject);
  121. private
  122. sources: array of TSrc;
  123. defaultZ: SmallInt;
  124. filterZ: SmallInt;
  125. zScale: Single;
  126. procedure Parse;
  127. procedure Cleanup;
  128. procedure SrcExtractFlip(src: PSrc; relX, relY, len: Integer;
  129. dest: PSmallInt);
  130. procedure SrcExtract(src: PSrc; relX, relY, len: Integer; dest: PSmallInt;
  131. DiagFlip: Boolean = false);
  132. procedure WorldExtract(x, y, len: Integer; dest: PSmallInt);
  133. public
  134. end;
  135. var
  136. MainForm: TMainForm;
  137. implementation
  138. uses
  139. fViewerD;
  140. {$R *.dfm}
  141. procedure TMainForm.FormCreate(Sender: TObject);
  142. var
  143. i: Integer;
  144. begin
  145. with ActionList do
  146. for i := 0 to ActionCount - 1 do
  147. with TAction(Actions[i]) do
  148. Hint := Caption;
  149. with StringGrid do
  150. begin
  151. Cells[0, 0] := 'File Name';
  152. ColWidths[0] := 140;
  153. Cells[1, 0] := 'World Offset';
  154. ColWidths[1] := 80;
  155. Cells[2, 0] := 'Size (rotated)';
  156. ColWidths[2] := 80;
  157. Cells[3, 0] := 'Data type';
  158. ColWidths[3] := 120;
  159. Cells[4, 0] := 'Flip and Rotate';
  160. ColWidths[4] := 110;
  161. Row := 0;
  162. end;
  163. zScale := 1;
  164. end;
  165. procedure TMainForm.FormDestroy(Sender: TObject);
  166. begin
  167. Cleanup;
  168. end;
  169. procedure TMainForm.ACExitExecute(Sender: TObject);
  170. begin
  171. Close;
  172. end;
  173. procedure TMainForm.BUDEMPathClick(Sender: TObject);
  174. begin
  175. ODPath.InitialDir := EDDEMPath.Text;
  176. ODPath.FileName := EDDEMPath.Text + 'pick a dummy.file';
  177. if ODPath.Execute then
  178. EDDEMPath.Text := ExtractFilePath(ODPath.FileName);
  179. end;
  180. procedure TMainForm.BUPickHTFClick(Sender: TObject);
  181. begin
  182. SDHTF.FileName := EDHTFName.Text;
  183. if SDHTF.Execute then
  184. EDHTFName.Text := SDHTF.FileName;
  185. end;
  186. procedure TMainForm.MIAboutClick(Sender: TObject);
  187. begin
  188. ShowMessage(Caption + #13#10#13#10 + 'HTF Generation Utility'#13#10 +
  189. 'Part of GLScene library.'#13#10#13#10 + 'http://glscene.org');
  190. end;
  191. procedure TMainForm.ActionListUpdate(Action: TBasicAction;
  192. var Handled: Boolean);
  193. begin
  194. ACRemoveDEM.Enabled := (StringGrid.RowCount > 2);
  195. end;
  196. procedure TMainForm.ACNewDEMExecute(Sender: TObject);
  197. begin
  198. StringGrid.RowCount := StringGrid.RowCount + 1;
  199. end;
  200. procedure TMainForm.ACRemoveDEMExecute(Sender: TObject);
  201. var
  202. i: Integer;
  203. begin
  204. with StringGrid do
  205. begin
  206. i := Row;
  207. if i < RowCount - 1 then
  208. begin
  209. while i < RowCount - 1 do
  210. begin
  211. Rows[i] := Rows[i + 1];
  212. Inc(i);
  213. end;
  214. end
  215. else
  216. Row := i - 1;
  217. RowCount := RowCount - 1;
  218. end;
  219. end;
  220. procedure TMainForm.StringGridSelectCell(Sender: TObject; ACol, ARow: Integer;
  221. var CanSelect: Boolean);
  222. procedure SetCB(const cb: TComboBox);
  223. var
  224. r: TRect;
  225. i: Integer;
  226. begin
  227. r := StringGrid.CellRect(ACol, ARow);
  228. cb.Left := r.Left + StringGrid.Left;
  229. cb.Top := r.Top + StringGrid.Top;
  230. cb.Width := r.Right + 1 - r.Left;
  231. i := cb.Items.IndexOf(StringGrid.Cells[ACol, ARow]);
  232. if i >= 0 then
  233. cb.ItemIndex := i
  234. else
  235. cb.Text := StringGrid.Cells[ACol, ARow];
  236. if Visible then
  237. cb.SetFocus;
  238. end;
  239. begin
  240. if ARow > 0 then
  241. begin
  242. if ACol = 0 then
  243. begin
  244. CBFile.Visible := True;
  245. SetCB(CBFile);
  246. end
  247. else
  248. CBFile.Visible := false;
  249. if ACol = 3 then
  250. begin
  251. CBType.Visible := True;
  252. SetCB(CBType);
  253. end
  254. else
  255. CBType.Visible := false;
  256. if ACol = 4 then
  257. begin
  258. CBFlipRotate.Visible := True;
  259. SetCB(CBFlipRotate);
  260. end
  261. else
  262. CBFlipRotate.Visible := false;
  263. CanSelect := True;
  264. end;
  265. end;
  266. procedure TMainForm.CBTypeChange(Sender: TObject);
  267. begin
  268. with StringGrid do
  269. Cells[Col, Row] := (Sender as TComboBox).Text;
  270. end;
  271. procedure TMainForm.ACSaveExecute(Sender: TObject);
  272. var
  273. i: Integer;
  274. sl, sg: TStringList;
  275. begin
  276. if SDTerrainPack.Execute then
  277. begin
  278. sl := TStringList.Create;
  279. with sl do
  280. begin
  281. Values['HTFName'] := EDHTFName.Text;
  282. Values['WorldSizeX'] := EDSizeX.Text;
  283. Values['WorldSizeY'] := EDSizeY.Text;
  284. Values['TileSize'] := EDTileSize.Text;
  285. Values['TileOverlap'] := EDTileOverlap.Text;
  286. Values['DefaultZ'] := EDDefaultZ.Text;
  287. Values['FilterZ'] := EDZFilter.Text;
  288. Values['ZScale'] := EDZScale.Text;
  289. Values['DEMPath'] := EDDEMPath.Text;
  290. Values['WholeTiles'] := IntToStr(Integer(CBWholeOnly.Checked));
  291. sg := TStringList.Create;
  292. for i := 1 to StringGrid.RowCount - 1 do
  293. sg.Add(StringGrid.Rows[i].CommaText);
  294. Values['DEMs'] := sg.CommaText;
  295. sg.Free;
  296. end;
  297. sl.SaveToFile(SDTerrainPack.FileName);
  298. sl.Free;
  299. end;
  300. end;
  301. procedure TMainForm.ACOpenExecute(Sender: TObject);
  302. var
  303. i: Integer;
  304. sl, sg: TStringList;
  305. begin
  306. if ODTerrainPack.Execute then
  307. begin
  308. sl := TStringList.Create;
  309. sl.LoadFromFile(ODTerrainPack.FileName);
  310. with sl do
  311. begin
  312. EDHTFName.Text := Values['HTFName'];
  313. EDSizeX.Text := Values['WorldSizeX'];
  314. EDSizeY.Text := Values['WorldSizeY'];
  315. EDTileSize.Text := Values['TileSize'];
  316. EDTileOverlap.Text := Values['TileOverlap'];
  317. EDDefaultZ.Text := Values['DefaultZ'];
  318. EDZFilter.Text := Values['FilterZ'];
  319. EDZScale.Text := Values['ZScale'];
  320. EDDEMPath.Text := Values['DEMPath'];
  321. CBWholeOnly.Checked := (Values['WholeTiles'] = '1');
  322. sg := TStringList.Create;
  323. sg.CommaText := Values['DEMs'];
  324. StringGrid.RowCount := sg.Count + 1;
  325. for i := 0 to sg.Count - 1 do
  326. StringGrid.Rows[i + 1].CommaText := sg[i];
  327. sg.Free;
  328. end;
  329. sl.Free;
  330. SDTerrainPack.FileName := ODTerrainPack.FileName;
  331. end;
  332. end;
  333. procedure TMainForm.EDDEMPathChange(Sender: TObject);
  334. var
  335. f: TSearchRec;
  336. r: Integer;
  337. begin
  338. CBFile.Items.Clear;
  339. r := FindFirst(EDDEMPath.Text + '\*.*', faAnyFile, f);
  340. while r = 0 do
  341. begin
  342. if (f.Attr and faDirectory) = 0 then
  343. CBFile.Items.Add(f.Name);
  344. r := FindNext(f);
  345. end;
  346. FindClose(f);
  347. end;
  348. procedure TMainForm.EDDefaultZChange(Sender: TObject);
  349. begin
  350. defaultZ := StrToIntDef(EDDefaultZ.Text, 0);
  351. if EDZFilter.Text = '' then
  352. filterZ := defaultZ;
  353. end;
  354. procedure TMainForm.EDZFilterChange(Sender: TObject);
  355. begin
  356. filterZ := StrToIntDef(EDZFilter.Text, defaultZ);
  357. end;
  358. procedure TMainForm.EDZScaleChange(Sender: TObject);
  359. begin
  360. zScale := StrToFloatDef(EDZScale.Text, 1.0);
  361. end;
  362. procedure TMainForm.Parse;
  363. var
  364. i, p: Integer;
  365. Row: TStrings;
  366. begin
  367. Cleanup;
  368. SetLength(sources, StringGrid.RowCount - 1);
  369. for i := 0 to High(sources) do
  370. begin
  371. Row := StringGrid.Rows[i + 1];
  372. sources[i].fs := TFileStream.Create(EDDEMPath.Text + '\' + Row[0],
  373. fmOpenRead + fmShareDenyNone);
  374. p := Pos(',', Row[1]);
  375. sources[i].x := StrToInt(Copy(Row[1], 1, p - 1));
  376. sources[i].y := StrToInt(Copy(Row[1], p + 1, MaxInt));
  377. p := Pos('x', Row[2]);
  378. sources[i].w := StrToInt(Copy(Row[2], 1, p - 1));
  379. sources[i].h := StrToInt(Copy(Row[2], p + 1, MaxInt));
  380. sources[i].format := CBType.Items.IndexOf(Row[3]); // File format
  381. sources[i].FlipRotate := CBFlipRotate.Items.IndexOf(Row[4]);
  382. // Flip and Rotate
  383. end;
  384. end;
  385. procedure TMainForm.Cleanup;
  386. var
  387. i: Integer;
  388. begin
  389. for i := 0 to High(sources) do
  390. sources[i].fs.Free;
  391. SetLength(sources, 0);
  392. end;
  393. procedure TMainForm.SrcExtractFlip(src: PSrc; relX, relY, len: Integer;
  394. dest: PSmallInt);
  395. var
  396. i: Integer;
  397. val: SmallInt;
  398. begin
  399. if src.FlipRotate <= 0 then
  400. SrcExtract(src, relX, relY, len, dest) // None
  401. else
  402. begin
  403. for i := 0 to len - 1 do
  404. begin
  405. case src.FlipRotate of
  406. // 0 : SrcExtract(src,relX, relY+i,1,@val); //No change ( )
  407. 1:
  408. SrcExtract(src, src.w - (relX + i), relY, 1, @val);
  409. // H-Flip (Flip)
  410. 2:
  411. SrcExtract(src, relY, src.w - (relX + i), 1, @val, True);
  412. // DiagFlip + H-Flip (90deg)
  413. 3:
  414. SrcExtract(src, src.w - (relX + i), src.h - relY, 1, @val);
  415. // H-Flip + V-Flip (180deg)
  416. 4:
  417. SrcExtract(src, src.h - relY, (relX + i), 1, @val, True);
  418. // DiagFlip + V-Flip (270deg)
  419. 5:
  420. SrcExtract(src, src.h - relY, src.w - (relX + i), 1, @val, True);
  421. // DiagFlip + V-Flip + H-Flip (Flip-90deg)
  422. 6:
  423. SrcExtract(src, relX + i, src.h - relY, 1, @val);
  424. // V-FLIP (Flip-180deg)
  425. 7:
  426. SrcExtract(src, relY, relX + i, 1, @val, True);
  427. // DiagFlip (Flip-270deg)
  428. end;
  429. PSmallIntArray(dest)[i] := val;
  430. end;
  431. end;
  432. end;
  433. procedure TMainForm.SrcExtract(src: PSrc; relX, relY, len: Integer;
  434. dest: PSmallInt; DiagFlip: Boolean = false);
  435. var
  436. i, c: Integer;
  437. wd: Word;
  438. buf: array of Single;
  439. bmp: TBitmap;
  440. rw: Integer; // rotated width
  441. begin
  442. if DiagFlip then
  443. rw := src.h
  444. else
  445. rw := src.w;
  446. with src^ do
  447. begin
  448. case format of
  449. 0:
  450. begin // 16bits Intel
  451. fs.Position := (relX + relY * rw) * 2;
  452. fs.Read(dest^, len * 2);
  453. end;
  454. 1:
  455. begin // 16bits unsigned Intel
  456. fs.Position := (relX + relY * rw) * 2;
  457. fs.Read(dest^, len * 2);
  458. for i := 0 to len - 1 do
  459. begin
  460. wd := PWord(Integer(dest) + i * 2)^;
  461. PSmallInt(Integer(dest) + i * 2)^ := Integer(wd) - 32768;
  462. end;
  463. end;
  464. 2:
  465. begin // 16bits non-Intel
  466. fs.Position := (relX + relY * rw) * 2;
  467. fs.Read(dest^, len * 2);
  468. for i := 0 to len - 1 do
  469. begin
  470. wd := PWord(Integer(dest) + i * 2)^;
  471. PWord(Integer(dest) + i * 2)^ := ((wd and 255) shl 8) + (wd shr 8);
  472. end;
  473. end;
  474. 3:
  475. begin // VTP's BT single
  476. fs.Position := (relX + relY * rw) * 4 + 256;
  477. SetLength(buf, len);
  478. fs.Read(buf[0], len * 4);
  479. for i := 0 to len - 1 do
  480. PSmallInt(Integer(dest) + i * 2)^ := Round(buf[i]);
  481. end;
  482. 4:
  483. begin // windows BMP
  484. bmp := TBitmap.Create;
  485. try
  486. fs.Position := 0;
  487. bmp.LoadFromStream(fs);
  488. if DiagFlip then
  489. rw := bmp.Width
  490. else
  491. rw := bmp.Height;
  492. for i := 0 to len - 1 do
  493. begin
  494. c := bmp.Canvas.Pixels[relX + i, rw - relY - 1];
  495. PSmallInt(Integer(dest) + i * 2)^ := (GetGValue(c) - 128) shl 7;
  496. end;
  497. finally
  498. bmp.Free;
  499. end;
  500. end;
  501. 5:
  502. begin // 32bits FP Intel
  503. fs.Position := (relX + relY * rw) * 4;
  504. SetLength(buf, len);
  505. fs.Read(buf[0], len * 4);
  506. for i := 0 to len - 1 do
  507. PSmallInt(Integer(dest) + i * 2)^ := Round((buf[i] - 0.5) * 32000);
  508. end;
  509. 6:
  510. begin // DTED
  511. fs.Position := 3434 + (relX + relY * rw) * 2 + (relY * 12);
  512. fs.Read(dest^, len * 2);
  513. for i := 0 to len - 1 do
  514. begin
  515. wd := PWord(Integer(dest) + i * 2)^;
  516. PWord(Integer(dest) + i * 2)^ := ((wd and 255) shl 8) + (wd shr 8);
  517. end;
  518. end;
  519. end;
  520. end;
  521. end;
  522. procedure TMainForm.WorldExtract(x, y, len: Integer; dest: PSmallInt);
  523. var
  524. i, n, rx, ry: Integer;
  525. src: PSrc;
  526. begin
  527. while len > 0 do
  528. begin
  529. src := nil;
  530. for i := 0 to High(sources) do
  531. begin
  532. if (sources[i].x <= x) and (sources[i].y <= y) and
  533. (x < sources[i].x + sources[i].w) and (y < sources[i].y + sources[i].h)
  534. then
  535. begin
  536. src := @sources[i];
  537. Break;
  538. end;
  539. end;
  540. if Assigned(src) then
  541. begin
  542. rx := x - src.x;
  543. ry := y - src.y;
  544. n := len;
  545. if rx + n > src.w then
  546. n := src.w - rx;
  547. SrcExtractFlip(src, rx, ry, n, dest);
  548. if filterZ <> defaultZ then
  549. begin
  550. for i := 0 to n - 1 do
  551. if PSmallIntArray(dest)[i] = filterZ then
  552. PSmallIntArray(dest)[i] := defaultZ;
  553. end;
  554. if zScale <> 1 then
  555. begin
  556. for i := 0 to n - 1 do
  557. PSmallIntArray(dest)[i] := Round(PSmallIntArray(dest)[i] * zScale);
  558. end;
  559. Dec(len, n);
  560. Inc(dest, n);
  561. Inc(x, n);
  562. end
  563. else
  564. begin
  565. dest^ := defaultZ;
  566. Inc(dest);
  567. Dec(len);
  568. Inc(x);
  569. end;
  570. end;
  571. end;
  572. procedure TMainForm.ACProcessExecute(Sender: TObject);
  573. var
  574. x, y, wx, wy, ts, tx, ty, i, j, overlap: Integer;
  575. n, maxN: Cardinal;
  576. htf: TGLHeightTileFile;
  577. buf: array of SmallInt;
  578. f: file of Byte;
  579. begin
  580. Screen.Cursor := crHourGlass;
  581. wx := StrToInt(EDSizeX.Text);
  582. wy := StrToInt(EDSizeY.Text);
  583. ts := StrToInt(EDTileSize.Text);
  584. overlap := StrToInt(EDTileOverlap.Text);
  585. Parse;
  586. SetLength(buf, ts * ts);
  587. htf := TGLHeightTileFile.CreateNew(EDHTFName.Text, wx, wy, ts);
  588. htf.defaultZ := defaultZ;
  589. ProgressBar.Max := 1000;
  590. maxN := Ceil(wx / ts) * Ceil(wy / ts);
  591. n := 0;
  592. ProgressBar.Position := 0;
  593. y := 0;
  594. while y < wy do
  595. begin
  596. ty := wy + overlap - y;
  597. if ty > ts then
  598. ty := ts;
  599. x := 0;
  600. while x < wx do
  601. begin
  602. tx := wx + overlap - x;
  603. if (not CBWholeOnly.Checked) or ((tx >= ts) and ((wy - y) >= ts)) then
  604. begin
  605. if tx > ts then
  606. tx := ts;
  607. for i := 0 to ty - 1 do
  608. begin
  609. WorldExtract(x, y + i, tx, @buf[i * ts]);
  610. if overlap > 0 then
  611. begin
  612. for j := tx to ts - 1 do
  613. buf[i * ts + j] := buf[i * ts + tx - 1];
  614. end
  615. else
  616. begin
  617. for j := tx to ts - 1 do
  618. buf[i * ts + j] := defaultZ;
  619. end;
  620. end;
  621. if overlap > 0 then
  622. begin
  623. for i := ty to ts - 1 do
  624. for j := 0 to ts - 1 do
  625. buf[i * ts + j] := buf[(i - 1) * ts + j];
  626. end
  627. else
  628. begin
  629. for i := ty to ts - 1 do
  630. for j := 0 to ts - 1 do
  631. buf[i * ts + j] := defaultZ;
  632. end;
  633. htf.CompressTile(x, y, ts, ts, @buf[0]);
  634. end;
  635. Inc(x, ts - overlap);
  636. Inc(n);
  637. ProgressBar.Position := (n * 1000) div maxN;
  638. if (n and 15) = 0 then
  639. begin
  640. Application.ProcessMessages;
  641. end;
  642. end;
  643. Inc(y, ts - overlap);
  644. end;
  645. htf.Free;
  646. Cleanup;
  647. Screen.Cursor := crDefault;
  648. AssignFile(f, EDHTFName.Text);
  649. Reset(f);
  650. i := FileSize(f);
  651. CloseFile(f);
  652. ShowMessage('HTF file created.'#13#10#13#10 + IntToStr(i) +
  653. ' bytes in file'#13#10 + '(' + IntToStr(wx * wy * 2) + ' raw bytes)');
  654. end;
  655. procedure TMainForm.ACViewerExecute(Sender: TObject);
  656. var
  657. viewer: TViewerForm;
  658. begin
  659. viewer := TViewerForm.Create(nil);
  660. try
  661. viewer.htf := TGLHeightTileFile.Create(EDHTFName.Text); // R
  662. viewer.Caption := 'HTFViewer - ' + ExtractFileName(EDHTFName.Text); // R
  663. viewer.ShowModal;
  664. finally
  665. viewer.Free;
  666. end;
  667. end;
  668. end.