fHFPick.pas 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. unit fHFPick;
  2. interface
  3. uses
  4. Winapi.OpenGL,
  5. System.SysUtils,
  6. System.Classes,
  7. Vcl.Graphics,
  8. Vcl.Controls,
  9. Vcl.Forms,
  10. Vcl.Dialogs,
  11. Vcl.StdCtrls,
  12. Vcl.ExtCtrls,
  13. GLS.Scene,
  14. GLS.Graph,
  15. GLS.SceneViewer,
  16. GLS.VectorGeometry,
  17. GLS.VectorTypes,
  18. GLS.Texture,
  19. GLS.Objects,
  20. GLS.Color,
  21. GLS.Coordinates,
  22. GLS.BaseClasses;
  23. type
  24. TFormHFPick = class(TForm)
  25. GLScene1: TGLScene;
  26. GLSceneViewer: TGLSceneViewer;
  27. GLCamera1: TGLCamera;
  28. HeightField: TGLHeightField;
  29. GLLightSource1: TGLLightSource;
  30. Panel1: TPanel;
  31. RBPaint: TRadioButton;
  32. RadioButton2: TRadioButton;
  33. Label1: TLabel;
  34. Label2: TLabel;
  35. procedure HeightFieldGetHeight(const x, y: Single; var z: Single;
  36. var color: TVector4f; var texPoint: TTexPoint);
  37. procedure GLSceneViewerMouseDown(Sender: TObject; Button: TMouseButton;
  38. Shift: TShiftState; x, y: Integer);
  39. procedure GLSceneViewerMouseMove(Sender: TObject; Shift: TShiftState;
  40. x, y: Integer);
  41. procedure FormCreate(Sender: TObject);
  42. private
  43. public
  44. mx, my: Integer;
  45. grid: array [-5 .. 5, -5 .. 5] of TColor;
  46. end;
  47. var
  48. FormHFPick: TFormHFPick;
  49. implementation
  50. {$R *.dfm}
  51. procedure TFormHFPick.FormCreate(Sender: TObject);
  52. var
  53. ix, iy: Integer;
  54. begin
  55. // initialize grid color to white/gray (checked pattern)
  56. for ix := -5 to 5 do
  57. for iy := -5 to 5 do
  58. if ((ix xor iy) and 1) = 0 then
  59. grid[ix, iy] := clWhite
  60. else
  61. grid[ix, iy] := clSilver;
  62. end;
  63. procedure TFormHFPick.HeightFieldGetHeight(const x, y: Single; var z: Single;
  64. var color: TVector4f; var texPoint: TTexPoint);
  65. var
  66. ix, iy: Integer;
  67. begin
  68. // Nothing fancy here, the color is directly taken from the grid,
  69. // and the z function is a basic cosinus. The '+0.01' are to take
  70. // rounding issues out of the equation.
  71. ix := Round(ClampValue(x + 0.01, -5, 5));
  72. iy := Round(ClampValue(y + 0.01, -5, 5));
  73. color := ConvertWinColor(grid[ix, iy]);
  74. z := Cos(VectorLength(x, y) * 1.5);
  75. end;
  76. procedure TFormHFPick.GLSceneViewerMouseDown(Sender: TObject; Button: TMouseButton;
  77. Shift: TShiftState; x, y: Integer);
  78. var
  79. v: TAffineVector;
  80. ix, iy: Integer;
  81. begin
  82. mx := x;
  83. my := y;
  84. if RBPaint.Checked then
  85. begin
  86. // In Paint mode
  87. // get absolute 3D coordinates of the point below the mouse
  88. v := GLSceneViewer.Buffer.PixelRayToWorld(x, y);
  89. // convert to heightfield local coordinates
  90. v := HeightField.AbsoluteToLocal(v);
  91. // convert that local coords to grid pos
  92. ix := Round(v.x);
  93. iy := Round(v.y);
  94. // if we are in the grid...
  95. if (ix >= -5) and (ix <= 5) and (iy >= -5) and (iy <= 5) then
  96. begin
  97. // show last coord in the caption bar
  98. Label2.Caption := Format('%d %d', [ix, iy]);
  99. // and paint blue or red depending on the button
  100. if Button = TMouseButton(mbLeft) then
  101. grid[ix, iy] := clBlue
  102. else
  103. grid[ix, iy] := clRed;
  104. // Height field changed, rebuild it!
  105. HeightField.StructureChanged;
  106. end;
  107. end;
  108. end;
  109. procedure TFormHFPick.GLSceneViewerMouseMove(Sender: TObject; Shift: TShiftState;
  110. x, y: Integer);
  111. begin
  112. if RBPaint.Checked then
  113. begin
  114. // in paint mode, paint if a button is pressed
  115. if ssLeft in Shift then
  116. GLSceneViewerMouseDown(Sender, TMouseButton(mbLeft), Shift, x, y)
  117. else if ssRight in Shift then
  118. GLSceneViewerMouseDown(Sender, TMouseButton(mbRight), Shift, x, y);
  119. end
  120. else
  121. begin
  122. // rotate mode
  123. if Shift <> [] then
  124. begin
  125. GLCamera1.MoveAroundTarget(my - y, mx - x);
  126. mx := x;
  127. my := y;
  128. end;
  129. end;
  130. end;
  131. end.