123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- unit fHFPick;
- interface
- uses
- Winapi.OpenGL,
- System.SysUtils,
- System.Classes,
- Vcl.Graphics,
- Vcl.Controls,
- Vcl.Forms,
- Vcl.Dialogs,
- Vcl.StdCtrls,
- Vcl.ExtCtrls,
- GLS.Scene,
- GLS.Graph,
- GLS.SceneViewer,
- GLS.VectorGeometry,
- GLS.VectorTypes,
- GLS.Texture,
- GLS.Objects,
- GLS.Color,
- GLS.Coordinates,
- GLS.BaseClasses;
- type
- TFormHFPick = class(TForm)
- GLScene1: TGLScene;
- GLSceneViewer: TGLSceneViewer;
- GLCamera1: TGLCamera;
- HeightField: TGLHeightField;
- GLLightSource1: TGLLightSource;
- Panel1: TPanel;
- RBPaint: TRadioButton;
- RadioButton2: TRadioButton;
- Label1: TLabel;
- Label2: TLabel;
- procedure HeightFieldGetHeight(const x, y: Single; var z: Single;
- var color: TVector4f; var texPoint: TTexPoint);
- procedure GLSceneViewerMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; x, y: Integer);
- procedure GLSceneViewerMouseMove(Sender: TObject; Shift: TShiftState;
- x, y: Integer);
- procedure FormCreate(Sender: TObject);
- private
- public
- mx, my: Integer;
- grid: array [-5 .. 5, -5 .. 5] of TColor;
- end;
- var
- FormHFPick: TFormHFPick;
- implementation
- {$R *.dfm}
- procedure TFormHFPick.FormCreate(Sender: TObject);
- var
- ix, iy: Integer;
- begin
- // initialize grid color to white/gray (checked pattern)
- for ix := -5 to 5 do
- for iy := -5 to 5 do
- if ((ix xor iy) and 1) = 0 then
- grid[ix, iy] := clWhite
- else
- grid[ix, iy] := clSilver;
- end;
- procedure TFormHFPick.HeightFieldGetHeight(const x, y: Single; var z: Single;
- var color: TVector4f; var texPoint: TTexPoint);
- var
- ix, iy: Integer;
- begin
- // Nothing fancy here, the color is directly taken from the grid,
- // and the z function is a basic cosinus. The '+0.01' are to take
- // rounding issues out of the equation.
- ix := Round(ClampValue(x + 0.01, -5, 5));
- iy := Round(ClampValue(y + 0.01, -5, 5));
- color := ConvertWinColor(grid[ix, iy]);
- z := Cos(VectorLength(x, y) * 1.5);
- end;
- procedure TFormHFPick.GLSceneViewerMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; x, y: Integer);
- var
- v: TAffineVector;
- ix, iy: Integer;
- begin
- mx := x;
- my := y;
- if RBPaint.Checked then
- begin
- // In Paint mode
- // get absolute 3D coordinates of the point below the mouse
- v := GLSceneViewer.Buffer.PixelRayToWorld(x, y);
- // convert to heightfield local coordinates
- v := HeightField.AbsoluteToLocal(v);
- // convert that local coords to grid pos
- ix := Round(v.x);
- iy := Round(v.y);
- // if we are in the grid...
- if (ix >= -5) and (ix <= 5) and (iy >= -5) and (iy <= 5) then
- begin
- // show last coord in the caption bar
- Label2.Caption := Format('%d %d', [ix, iy]);
- // and paint blue or red depending on the button
- if Button = TMouseButton(mbLeft) then
- grid[ix, iy] := clBlue
- else
- grid[ix, iy] := clRed;
- // Height field changed, rebuild it!
- HeightField.StructureChanged;
- end;
- end;
- end;
- procedure TFormHFPick.GLSceneViewerMouseMove(Sender: TObject; Shift: TShiftState;
- x, y: Integer);
- begin
- if RBPaint.Checked then
- begin
- // in paint mode, paint if a button is pressed
- if ssLeft in Shift then
- GLSceneViewerMouseDown(Sender, TMouseButton(mbLeft), Shift, x, y)
- else if ssRight in Shift then
- GLSceneViewerMouseDown(Sender, TMouseButton(mbRight), Shift, x, y);
- end
- else
- begin
- // rotate mode
- if Shift <> [] then
- begin
- GLCamera1.MoveAroundTarget(my - y, mx - x);
- mx := x;
- my := y;
- end;
- end;
- end;
- end.
|