fObjmoveD.pas 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. unit fObjmoveD;
  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. Stage.VectorTypes,
  21. Stage.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. type
  33. TFormObjmove = class(TForm)
  34. GLScene1: TGLScene;
  35. Scene: TGLSceneViewer;
  36. Camera: TGLCamera;
  37. DummyCube: TGLDummyCube;
  38. ZArrow: TGLArrowLine;
  39. XArrow: TGLArrowLine;
  40. YArrow: TGLArrowLine;
  41. Cube1: TGLCube;
  42. TopLight: TGLLightSource;
  43. Cube2: TGLCube;
  44. Floor: TGLCube;
  45. Panel1: TPanel;
  46. SpaceTextX: TGLSpaceText;
  47. SpaceTextY: TGLSpaceText;
  48. SpaceTextZ: TGLSpaceText;
  49. HUDText: TGLHUDText;
  50. GLWindowsBitmapFont1: TGLWindowsBitmapFont;
  51. HUDTextObj: TGLHUDText;
  52. GroupBox1: TGroupBox;
  53. ShowAxes: TCheckBox;
  54. StatusBar1: TStatusBar;
  55. Button1: TButton;
  56. ButtonReset: TButton;
  57. procedure SceneMouseDown(Sender: TObject; Button: TMouseButton;
  58. Shift: TShiftState; X, Y: Integer);
  59. procedure SceneMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  60. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
  61. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  62. procedure FormKeyPress(Sender: TObject; var Key: Char);
  63. procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  64. procedure FormCreate(Sender: TObject);
  65. procedure ShowAxesClick(Sender: TObject);
  66. procedure ButtonResetClick(Sender: TObject);
  67. private
  68. lastMouseWorldPos: TGLVector;
  69. movingOnZ: Boolean;
  70. CurrentPick: TGLCustomSceneObject;
  71. SceneMouseMoveCnt: Integer;
  72. function MouseWorldPos(X, Y: Integer): TGLVector;
  73. procedure UpdateHUDText;
  74. procedure ProcessPick(pick: TGLBaseSceneObject);
  75. end;
  76. const
  77. SelectionColor: TGLColorVector = (X : 0.243; Y : 0.243; Z: 0.243; W : 1.000);
  78. var
  79. FormObjmove: TFormObjmove;
  80. implementation
  81. {$R *.DFM}
  82. //------------------------------------------------------------------
  83. procedure TFormObjmove.FormCreate(Sender: TObject);
  84. begin
  85. UpdateHUDText;
  86. end;
  87. //------------------------------------------------------------------
  88. function TFormObjmove.MouseWorldPos(X, Y: Integer): TGLVector;
  89. var
  90. v: TGLVector;
  91. begin
  92. Y := Scene.Height - Y;
  93. if Assigned(CurrentPick) then
  94. begin
  95. SetVector(v, X, Y, 0);
  96. if movingOnZ then
  97. Scene.Buffer.ScreenVectorIntersectWithPlaneXZ(v, CurrentPick.Position.Y, Result)
  98. else
  99. Scene.Buffer.ScreenVectorIntersectWithPlaneXY(v, CurrentPick.Position.Z, Result);
  100. end
  101. else
  102. SetVector(Result, NullVector);
  103. end;
  104. //------------------------------------------------------------------
  105. procedure TFormObjmove.ProcessPick(pick: TGLBaseSceneObject);
  106. begin
  107. if Assigned(pick) then
  108. begin
  109. // Only Cube1 and Cube2 can be selected
  110. if (pick.Name <> 'Cube1') and (pick.Name <> 'Cube2') then
  111. pick := nil;
  112. end;
  113. if pick <> CurrentPick then
  114. begin
  115. if Assigned(CurrentPick) then
  116. begin
  117. CurrentPick.ShowAxes := false;
  118. CurrentPick.Material.FrontProperties.Emission.Color := clrBlack;
  119. end;
  120. CurrentPick := TGLCustomSceneObject(pick);
  121. if Assigned(CurrentPick) then
  122. begin
  123. if ShowAxes.Checked then
  124. CurrentPick.ShowAxes := true;
  125. CurrentPick.Material.FrontProperties.Emission.Color := SelectionColor;
  126. end;
  127. end;
  128. UpdateHudText;
  129. end;
  130. //------------------------------------------------------------------
  131. procedure TFormObjmove.SceneMouseDown(Sender: TObject; Button: TMouseButton;
  132. Shift: TShiftState; X, Y: Integer);
  133. var
  134. pick: TGLBaseSceneObject;
  135. begin
  136. movingOnZ := (ssShift in Shift);
  137. // If an object is picked...
  138. pick := (Scene.Buffer.GetPickedObject(X, Y) as TGLCustomSceneObject);
  139. ProcessPick(Pick);
  140. // store mouse pos
  141. if Assigned(CurrentPick) then
  142. lastMouseWorldPos := MouseWorldPos(X, Y);
  143. end;
  144. //------------------------------------------------------------------
  145. procedure TFormObjmove.SceneMouseMove(Sender: TObject; Shift: TShiftState;
  146. X, Y: Integer);
  147. var
  148. newPos: TGLVector;
  149. begin
  150. Inc(SceneMouseMoveCnt);
  151. Assert(SceneMouseMoveCnt < 2);
  152. if ssLeft in Shift then
  153. begin
  154. // handle hold/unhold of shift
  155. if (ssShift in Shift) <> movingOnZ then
  156. begin
  157. movingOnZ := (ssShift in Shift);
  158. lastMouseWorldPos := MouseWorldPos(X, Y);
  159. end;
  160. newPos := MouseWorldPos(X, Y);
  161. if Assigned(CurrentPick) and (VectorNorm(lastMouseWorldPos) <> 0) then
  162. CurrentPick.Position.Translate(VectorSubtract(newPos, lastMouseWorldPos));
  163. lastMouseWorldPos := newPos;
  164. UpdateHudText;
  165. end;
  166. Dec(SceneMouseMoveCnt);
  167. end;
  168. //------------------------------------------------------------------
  169. procedure TFormObjmove.ShowAxesClick(Sender: TObject);
  170. begin
  171. // Unselect all
  172. ProcessPick(nil);
  173. end;
  174. //------------------------------------------------------------------
  175. procedure TFormObjmove.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  176. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  177. begin
  178. // Note that 1 wheel-step induces a WheelDelta of 120,
  179. // this code adjusts the distance to target with a 10% per wheel-step ratio
  180. if WheelDelta <> 0 then
  181. Camera.AdjustDistanceToTarget(Power(1.1, -WheelDelta / 120));
  182. end;
  183. //------------------------------------------------------------------
  184. procedure TFormObjmove.FormKeyPress(Sender: TObject; var Key: Char);
  185. begin
  186. case Key of
  187. '1': Camera.MoveAroundTarget(3, 0);
  188. '2': Camera.MoveAroundTarget(-3, 0);
  189. '3': Camera.MoveAroundTarget(0, 3);
  190. '4': Camera.MoveAroundTarget(0, -3);
  191. '-': Camera.AdjustDistanceToTarget(1.1);
  192. '+': Camera.AdjustDistanceToTarget(1 / 1.1);
  193. end;
  194. end;
  195. //------------------------------------------------------------------
  196. procedure TFormObjmove.UpdateHUDText;
  197. var
  198. objPos, winPos: TAffineVector;
  199. begin
  200. if Assigned(CurrentPick) then
  201. begin
  202. SetVector(objPos, CurrentPick.AbsolutePosition);
  203. HUDText.Text := Format('New Object Position: Xn: %4.3f, Yn: %4.3f, Zn: %4.3f',
  204. [objPos.X, objPos.Y, objPos.Z]);
  205. winPos := Scene.Buffer.WorldToScreen(objPos);
  206. HUDTextObj.Visible := True;
  207. HUDTextObj.Text := CurrentPick.Name;
  208. HUDTextObj.Position.X := winPos.X + 20;
  209. HUDTextObj.Position.Y := Scene.Height - winPos.Y + 20;
  210. end
  211. else
  212. begin
  213. HUDText.Text := 'No selected object';
  214. HUDTextObj.Visible := False;
  215. end;
  216. end;
  217. //------------------------------------------------------------------
  218. procedure TFormObjmove.FormKeyUp(Sender: TObject; var Key: Word;
  219. Shift: TShiftState);
  220. begin
  221. if Assigned(CurrentPick) then
  222. case Key of
  223. VK_UP:
  224. if ssShift in Shift then
  225. CurrentPick.Translate(0, 0, 0.3)
  226. else
  227. CurrentPick.Translate(-0.3, 0, 0);
  228. VK_DOWN:
  229. if ssShift in Shift then
  230. CurrentPick.Translate(0, 0, -0.3)
  231. else
  232. CurrentPick.Translate(0.3, 0, 0);
  233. VK_LEFT:
  234. CurrentPick.Translate(0, -0.3, 0);
  235. VK_RIGHT:
  236. CurrentPick.Translate(0, 0.3, 0);
  237. end;
  238. end;
  239. procedure TFormObjmove.ButtonResetClick(Sender: TObject);
  240. begin
  241. Cube1.Position.X := 0.1;
  242. Cube1.Position.Y := 0.1;
  243. Cube1.Position.Z := -0.9;
  244. Cube2.Position.X := -0.4;
  245. Cube2.Position.Y := 0.4;
  246. Cube2.Position.Z := -0.5;
  247. UpdateHUDText;
  248. end;
  249. end.