123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- unit fObjmove;
- interface
- uses
- Winapi.Windows,
- System.SysUtils,
- System.Classes,
- System.Math,
- Vcl.Forms,
- Vcl.Dialogs,
- Vcl.Controls,
- Vcl.Graphics,
- Vcl.StdCtrls,
- Vcl.ExtCtrls,
- Vcl.ComCtrls,
- GLS.Scene,
- GLS.Objects,
- GLS.Graph,
- GLS.Collision,
- GLS.Texture,
- GLS.VectorTypes,
- GLS.VectorGeometry,
- GLS.VectorFileObjects,
- GLS.SceneViewer,
- GLS.SpaceText,
- GLS.GeomObjects,
- GLS.Color,
- GLS.Coordinates,
- GLS.BaseClasses,
- GLS.BitmapFont,
- GLS.WindowsFont,
- GLS.HUDObjects,
- GLS.SimpleNavigation,
- GLS.Navigator,
- GLS.SmoothNavigator;
- type
- TFormObjmove = class(TForm)
- GLScene1: TGLScene;
- Scn: TGLSceneViewer;
- GLCamera: TGLCamera;
- DummyCube: TGLDummyCube;
- ZArrow: TGLArrowLine;
- XArrow: TGLArrowLine;
- YArrow: TGLArrowLine;
- Cube1: TGLCube;
- TopLight: TGLLightSource;
- Cube2: TGLCube;
- Floor: TGLCube;
- Panel1: TPanel;
- Button1: TButton;
- Label2: TLabel;
- TxtX: TGLSpaceText;
- TxtY: TGLSpaceText;
- Label3: TLabel;
- Label4: TLabel;
- TxtZ: TGLSpaceText;
- TopText: TGLHUDText;
- GLWindowsBitmapFont1: TGLWindowsBitmapFont;
- ObjText: TGLHUDText;
- GroupBox1: TGroupBox;
- ShowAxes: TCheckBox;
- StatusBar1: TStatusBar;
- GLSmoothNavigator1: TGLSmoothNavigator;
- procedure ScnMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure ScnMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
- procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
- WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
- procedure FormKeyPress(Sender: TObject; var Key: Char);
- procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
- procedure FormCreate(Sender: TObject);
- procedure ShowAxesClick(Sender: TObject);
- private
- lastMouseWorldPos: TGLVector;
- Cube: TGLCube;
- movingOnZ: Boolean;
- CurrentPick: TGLCustomSceneObject;
- ScnMouseMoveCnt: Integer;
- function MouseWorldPos(X, Y: Integer): TGLVector;
- procedure UpdateHudText;
- procedure ProcessPick(pick: TGLBaseSceneObject);
- end;
- const
- SelectionColor: TColorVector = (X : 0.243; Y : 0.243; Z: 0.243; W : 1.000);
- var
- FormObjmove: TFormObjmove;
- implementation
- {$R *.DFM}
- procedure TFormObjmove.FormCreate(Sender: TObject);
- begin
- UpdateHudText;
- Cube := TGLCube.CreateAsChild(DummyCube);
- Cube.CubeDepth := 0.2;
- Cube.CubeWidth := 0.2;
- Cube.CubeHeight := 0.2;
- Cube.Position.X := 1;
- Cube.Position.Y := 1;
- Cube.Position.Z := 1;
- end;
- function TFormObjmove.MouseWorldPos(X, Y: Integer): TGLVector;
- var
- v: TGLVector;
- begin
- Y := Scn.Height - Y;
- if Assigned(CurrentPick) then
- begin
- SetVector(v, X, Y, 0);
- if movingOnZ then
- Scn.Buffer.ScreenVectorIntersectWithPlaneXZ(v, CurrentPick.Position.Y,
- Result)
- else
- Scn.Buffer.ScreenVectorIntersectWithPlaneXY(v, CurrentPick.Position.Z,
- Result);
- end
- else
- SetVector(Result, NullVector);
- end;
- procedure TFormObjmove.ProcessPick(pick: TGLBaseSceneObject);
- begin
- if Assigned(pick) then
- begin
- // Only Cube1 and Cube2 can be selected
- if (pick.Name <> 'Cube1') and (pick.Name <> 'Cube2') then
- pick := nil;
- end;
- if pick <> CurrentPick then
- begin
- if Assigned(CurrentPick) then
- begin
- CurrentPick.ShowAxes := false;
- CurrentPick.Material.FrontProperties.Emission.Color := clrBlack;
- end;
- CurrentPick := TGLCustomSceneObject(pick);
- if Assigned(CurrentPick) then
- begin
- if ShowAxes.Checked then
- CurrentPick.ShowAxes := true;
- CurrentPick.Material.FrontProperties.Emission.Color := SelectionColor;
- end;
- end;
- UpdateHudText;
- end;
- procedure TFormObjmove.ScnMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- var
- pick: TGLBaseSceneObject;
- begin
- movingOnZ := (ssShift in Shift);
- // If an object is picked...
- pick := (Scn.Buffer.GetPickedObject(X, Y) as TGLCustomSceneObject);
- ProcessPick(Pick);
- // store mouse pos
- if Assigned(CurrentPick) then
- lastMouseWorldPos := MouseWorldPos(X, Y);
- end;
- procedure TFormObjmove.ScnMouseMove(Sender: TObject; Shift: TShiftState;
- X, Y: Integer);
- var
- newPos: TGLVector;
- begin
- Inc(ScnMouseMoveCnt);
- Assert(ScnMouseMoveCnt < 2);
- if ssLeft in Shift then
- begin
- // handle hold/unhold of shift
- if (ssShift in Shift) <> movingOnZ then
- begin
- movingOnZ := (ssShift in Shift);
- lastMouseWorldPos := MouseWorldPos(X, Y);
- end;
- newPos := MouseWorldPos(X, Y);
- if Assigned(CurrentPick) and (VectorNorm(lastMouseWorldPos) <> 0) then
- CurrentPick.Position.Translate(VectorSubtract(newPos, lastMouseWorldPos));
- lastMouseWorldPos := newPos;
- UpdateHudText;
- end;
- Dec(ScnMouseMoveCnt);
- end;
- procedure TFormObjmove.ShowAxesClick(Sender: TObject);
- begin
- // Unselect all
- ProcessPick(nil);
- end;
- procedure TFormObjmove.FormMouseWheel(Sender: TObject; Shift: TShiftState;
- WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
- begin
- // Note that 1 wheel-step induces a WheelDelta of 120,
- // this code adjusts the distance to target with a 10% per wheel-step ratio
- if WheelDelta <> 0 then
- GLCamera.AdjustDistanceToTarget(Power(1.1, -WheelDelta / 120));
- end;
- procedure TFormObjmove.FormKeyPress(Sender: TObject; var Key: Char);
- begin
- with GLCamera do
- case Key of
- '2': MoveAroundTarget(3, 0);
- '4': MoveAroundTarget(0, -3);
- '6': MoveAroundTarget(0, 3);
- '8': MoveAroundTarget(-3, 0);
- '-': AdjustDistanceToTarget(1.1);
- '+': AdjustDistanceToTarget(1 / 1.1);
- end;
- end;
- procedure TFormObjmove.UpdateHudText;
- var
- objPos, winPos: TAffineVector;
- begin
- if Assigned(CurrentPick) then
- begin
- SetVector(objPos, CurrentPick.AbsolutePosition);
- TopText.Text := Format(
- 'New Object Position: Xn: %4.4f, Yn: %4.4f, Zn: %4.4f',
- [objPos.X, objPos.Y, objPos.Z]);
- winPos := Scn.Buffer.WorldToScreen(objPos);
- with ObjText do
- begin
- Visible := true;
- Text := CurrentPick.Name;
- Position.X := winPos.X + 10;
- Position.Y := Scn.Height - winPos.Y + 10;
- end;
- end
- else
- begin
- TopText.Text := 'No selected object';
- ObjText.Visible := false;
- end;
- end;
- procedure TFormObjmove.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
- begin
- if Assigned(CurrentPick) then
- with CurrentPick do
- case Key of
- VK_UP:
- if ssShift in Shift then
- Translate(0, 0, 0.3)
- else
- Translate(-0.3, 0, 0);
- VK_DOWN:
- if ssShift in Shift then
- Translate(0, 0, -0.3)
- else
- Translate(0.3, 0, 0);
- VK_LEFT:
- Translate(0, -0.3, 0);
- VK_RIGHT:
- Translate(0, 0.3, 0);
- end;
- end;
- end.
|