fObjmove.pas 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. unit fObjmove;
  2. interface
  3. uses
  4. Winapi.Windows,
  5. System.SysUtils,
  6. System.Classes,
  7. System.Math,
  8. Vcl.Forms,
  9. Vcl.Dialogs,
  10. Vcl.Controls,
  11. Vcl.Graphics,
  12. Vcl.StdCtrls,
  13. Vcl.ExtCtrls,
  14. Vcl.ComCtrls,
  15. GLS.Scene,
  16. GLS.Objects,
  17. GLS.Graph,
  18. GLS.Collision,
  19. GLS.Texture,
  20. GLS.VectorTypes,
  21. GLS.VectorGeometry,
  22. GLS.VectorFileObjects,
  23. GLS.SceneViewer,
  24. GLS.SpaceText,
  25. GLS.GeomObjects,
  26. GLS.Color,
  27. GLS.Coordinates,
  28. GLS.BaseClasses,
  29. GLS.BitmapFont,
  30. GLS.WindowsFont,
  31. GLS.HUDObjects,
  32. GLS.SimpleNavigation,
  33. GLS.Navigator,
  34. GLS.SmoothNavigator;
  35. type
  36. TFormObjmove = class(TForm)
  37. GLScene1: TGLScene;
  38. Scn: TGLSceneViewer;
  39. GLCamera: TGLCamera;
  40. DummyCube: TGLDummyCube;
  41. ZArrow: TGLArrowLine;
  42. XArrow: TGLArrowLine;
  43. YArrow: TGLArrowLine;
  44. Cube1: TGLCube;
  45. TopLight: TGLLightSource;
  46. Cube2: TGLCube;
  47. Floor: TGLCube;
  48. Panel1: TPanel;
  49. Button1: TButton;
  50. Label2: TLabel;
  51. TxtX: TGLSpaceText;
  52. TxtY: TGLSpaceText;
  53. Label3: TLabel;
  54. Label4: TLabel;
  55. TxtZ: TGLSpaceText;
  56. TopText: TGLHUDText;
  57. GLWindowsBitmapFont1: TGLWindowsBitmapFont;
  58. ObjText: TGLHUDText;
  59. GroupBox1: TGroupBox;
  60. ShowAxes: TCheckBox;
  61. StatusBar1: TStatusBar;
  62. GLSmoothNavigator1: TGLSmoothNavigator;
  63. procedure ScnMouseDown(Sender: TObject; Button: TMouseButton;
  64. Shift: TShiftState; X, Y: Integer);
  65. procedure ScnMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  66. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
  67. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  68. procedure FormKeyPress(Sender: TObject; var Key: Char);
  69. procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  70. procedure FormCreate(Sender: TObject);
  71. procedure ShowAxesClick(Sender: TObject);
  72. private
  73. lastMouseWorldPos: TGLVector;
  74. Cube: TGLCube;
  75. movingOnZ: Boolean;
  76. CurrentPick: TGLCustomSceneObject;
  77. ScnMouseMoveCnt: Integer;
  78. function MouseWorldPos(X, Y: Integer): TGLVector;
  79. procedure UpdateHudText;
  80. procedure ProcessPick(pick: TGLBaseSceneObject);
  81. end;
  82. const
  83. SelectionColor: TColorVector = (X : 0.243; Y : 0.243; Z: 0.243; W : 1.000);
  84. var
  85. FormObjmove: TFormObjmove;
  86. implementation
  87. {$R *.DFM}
  88. procedure TFormObjmove.FormCreate(Sender: TObject);
  89. begin
  90. UpdateHudText;
  91. Cube := TGLCube.CreateAsChild(DummyCube);
  92. Cube.CubeDepth := 0.2;
  93. Cube.CubeWidth := 0.2;
  94. Cube.CubeHeight := 0.2;
  95. Cube.Position.X := 1;
  96. Cube.Position.Y := 1;
  97. Cube.Position.Z := 1;
  98. end;
  99. function TFormObjmove.MouseWorldPos(X, Y: Integer): TGLVector;
  100. var
  101. v: TGLVector;
  102. begin
  103. Y := Scn.Height - Y;
  104. if Assigned(CurrentPick) then
  105. begin
  106. SetVector(v, X, Y, 0);
  107. if movingOnZ then
  108. Scn.Buffer.ScreenVectorIntersectWithPlaneXZ(v, CurrentPick.Position.Y,
  109. Result)
  110. else
  111. Scn.Buffer.ScreenVectorIntersectWithPlaneXY(v, CurrentPick.Position.Z,
  112. Result);
  113. end
  114. else
  115. SetVector(Result, NullVector);
  116. end;
  117. procedure TFormObjmove.ProcessPick(pick: TGLBaseSceneObject);
  118. begin
  119. if Assigned(pick) then
  120. begin
  121. // Only Cube1 and Cube2 can be selected
  122. if (pick.Name <> 'Cube1') and (pick.Name <> 'Cube2') then
  123. pick := nil;
  124. end;
  125. if pick <> CurrentPick then
  126. begin
  127. if Assigned(CurrentPick) then
  128. begin
  129. CurrentPick.ShowAxes := false;
  130. CurrentPick.Material.FrontProperties.Emission.Color := clrBlack;
  131. end;
  132. CurrentPick := TGLCustomSceneObject(pick);
  133. if Assigned(CurrentPick) then
  134. begin
  135. if ShowAxes.Checked then
  136. CurrentPick.ShowAxes := true;
  137. CurrentPick.Material.FrontProperties.Emission.Color := SelectionColor;
  138. end;
  139. end;
  140. UpdateHudText;
  141. end;
  142. procedure TFormObjmove.ScnMouseDown(Sender: TObject; Button: TMouseButton;
  143. Shift: TShiftState; X, Y: Integer);
  144. var
  145. pick: TGLBaseSceneObject;
  146. begin
  147. movingOnZ := (ssShift in Shift);
  148. // If an object is picked...
  149. pick := (Scn.Buffer.GetPickedObject(X, Y) as TGLCustomSceneObject);
  150. ProcessPick(Pick);
  151. // store mouse pos
  152. if Assigned(CurrentPick) then
  153. lastMouseWorldPos := MouseWorldPos(X, Y);
  154. end;
  155. procedure TFormObjmove.ScnMouseMove(Sender: TObject; Shift: TShiftState;
  156. X, Y: Integer);
  157. var
  158. newPos: TGLVector;
  159. begin
  160. Inc(ScnMouseMoveCnt);
  161. Assert(ScnMouseMoveCnt < 2);
  162. if ssLeft in Shift then
  163. begin
  164. // handle hold/unhold of shift
  165. if (ssShift in Shift) <> movingOnZ then
  166. begin
  167. movingOnZ := (ssShift in Shift);
  168. lastMouseWorldPos := MouseWorldPos(X, Y);
  169. end;
  170. newPos := MouseWorldPos(X, Y);
  171. if Assigned(CurrentPick) and (VectorNorm(lastMouseWorldPos) <> 0) then
  172. CurrentPick.Position.Translate(VectorSubtract(newPos, lastMouseWorldPos));
  173. lastMouseWorldPos := newPos;
  174. UpdateHudText;
  175. end;
  176. Dec(ScnMouseMoveCnt);
  177. end;
  178. procedure TFormObjmove.ShowAxesClick(Sender: TObject);
  179. begin
  180. // Unselect all
  181. ProcessPick(nil);
  182. end;
  183. procedure TFormObjmove.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  184. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  185. begin
  186. // Note that 1 wheel-step induces a WheelDelta of 120,
  187. // this code adjusts the distance to target with a 10% per wheel-step ratio
  188. if WheelDelta <> 0 then
  189. GLCamera.AdjustDistanceToTarget(Power(1.1, -WheelDelta / 120));
  190. end;
  191. procedure TFormObjmove.FormKeyPress(Sender: TObject; var Key: Char);
  192. begin
  193. with GLCamera do
  194. case Key of
  195. '2': MoveAroundTarget(3, 0);
  196. '4': MoveAroundTarget(0, -3);
  197. '6': MoveAroundTarget(0, 3);
  198. '8': MoveAroundTarget(-3, 0);
  199. '-': AdjustDistanceToTarget(1.1);
  200. '+': AdjustDistanceToTarget(1 / 1.1);
  201. end;
  202. end;
  203. procedure TFormObjmove.UpdateHudText;
  204. var
  205. objPos, winPos: TAffineVector;
  206. begin
  207. if Assigned(CurrentPick) then
  208. begin
  209. SetVector(objPos, CurrentPick.AbsolutePosition);
  210. TopText.Text := Format(
  211. 'New Object Position: Xn: %4.4f, Yn: %4.4f, Zn: %4.4f',
  212. [objPos.X, objPos.Y, objPos.Z]);
  213. winPos := Scn.Buffer.WorldToScreen(objPos);
  214. with ObjText do
  215. begin
  216. Visible := true;
  217. Text := CurrentPick.Name;
  218. Position.X := winPos.X + 10;
  219. Position.Y := Scn.Height - winPos.Y + 10;
  220. end;
  221. end
  222. else
  223. begin
  224. TopText.Text := 'No selected object';
  225. ObjText.Visible := false;
  226. end;
  227. end;
  228. procedure TFormObjmove.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  229. begin
  230. if Assigned(CurrentPick) then
  231. with CurrentPick do
  232. case Key of
  233. VK_UP:
  234. if ssShift in Shift then
  235. Translate(0, 0, 0.3)
  236. else
  237. Translate(-0.3, 0, 0);
  238. VK_DOWN:
  239. if ssShift in Shift then
  240. Translate(0, 0, -0.3)
  241. else
  242. Translate(0.3, 0, 0);
  243. VK_LEFT:
  244. Translate(0, -0.3, 0);
  245. VK_RIGHT:
  246. Translate(0, 0.3, 0);
  247. end;
  248. end;
  249. end.