fCameraControllerD.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. unit fCameraControllerD;
  2. interface
  3. uses
  4. Winapi.OpenGL,
  5. System.SysUtils,
  6. System.Variants,
  7. System.Classes,
  8. System.Types,
  9. System.Math,
  10. Vcl.Graphics,
  11. Vcl.Controls,
  12. Vcl.Forms,
  13. Vcl.Dialogs,
  14. Vcl.ExtCtrls,
  15. Vcl.StdCtrls,
  16. Vcl.ComCtrls,
  17. GLS.Scene,
  18. GLS.Objects,
  19. GLS.SceneViewer,
  20. GLS.VectorFileObjects,
  21. GLS.CameraController,
  22. GLS.File3DS,
  23. GLS.GeomObjects,
  24. GLS.Texture,
  25. GLS.Cadencer,
  26. GLS.Material,
  27. GLS.Coordinates,
  28. GLS.VectorTypes,
  29. GLS.BaseClasses,
  30. GLS.VectorGeometry,
  31. GLS.Navigator,
  32. GLS.SmoothNavigator,
  33. GLS.Graph;
  34. type
  35. TForm1 = class(TForm)
  36. Panel1: TPanel;
  37. Panel2: TPanel;
  38. Label1: TLabel;
  39. Label2: TLabel;
  40. Label3: TLabel;
  41. eDestX: TEdit;
  42. eDestY: TEdit;
  43. eDestZ: TEdit;
  44. Label5: TLabel;
  45. GLScene1: TGLScene;
  46. dcSphere: TGLDummyCube;
  47. GLSphere1: TGLSphere;
  48. GLCylinder1: TGLCylinder;
  49. GLSphere2: TGLSphere;
  50. GLCamera: TGLCamera;
  51. GLLightSource1: TGLLightSource;
  52. GLMaterialLibrary1: TGLMaterialLibrary;
  53. GLCadencer1: TGLCadencer;
  54. GLSceneViewer1: TGLSceneViewer;
  55. GLSphere3: TGLSphere;
  56. Panel3: TPanel;
  57. Label6: TLabel;
  58. Label9: TLabel;
  59. eDistance: TEdit;
  60. Panel4: TPanel;
  61. Label7: TLabel;
  62. Label8: TLabel;
  63. Label10: TLabel;
  64. Label11: TLabel;
  65. eSafeDistance: TEdit;
  66. eTimeToSafePlacement: TEdit;
  67. eTimeToOrbit: TEdit;
  68. Label12: TLabel;
  69. eTimeToZoomBackIn: TEdit;
  70. Panel5: TPanel;
  71. Label13: TLabel;
  72. eTime: TEdit;
  73. Label14: TLabel;
  74. btnMoveToPos: TButton;
  75. btnZoomToDistance: TButton;
  76. btnOrbitToPos: TButton;
  77. btnSafeOrbitAndZoomToPos: TButton;
  78. pImg: TPanel;
  79. Image1: TImage;
  80. Label4: TLabel;
  81. Panel6: TPanel;
  82. Label15: TLabel;
  83. btnOrbitToPosAdv: TButton;
  84. Timer1: TTimer;
  85. GLCameraController1: TGLCameraController;
  86. Panel8: TPanel;
  87. Label20: TLabel;
  88. Panel7: TPanel;
  89. Label16: TLabel;
  90. Label17: TLabel;
  91. Label18: TLabel;
  92. Label19: TLabel;
  93. camDirX: TEdit;
  94. camDirY: TEdit;
  95. camDirZ: TEdit;
  96. Panel9: TPanel;
  97. Label21: TLabel;
  98. Label22: TLabel;
  99. Label23: TLabel;
  100. Label24: TLabel;
  101. camUpX: TEdit;
  102. camUpY: TEdit;
  103. camUpZ: TEdit;
  104. btSmoothOrbit: TButton;
  105. GLSmoothNavigator: TGLSmoothNavigator;
  106. dcDebugGUI: TGLDummyCube;
  107. ArrowLine: TGLArrowLine;
  108. XYZGrid: TGLXYZGrid;
  109. GLPlane1: TGLPlane;
  110. UpAxis: TCheckBox;
  111. btSmoothOrbitToPosAdv: TButton;
  112. btSmoothOrbitAndZoom: TButton;
  113. dcMovingParent: TGLDummyCube;
  114. cbMoveParent: TCheckBox;
  115. procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  116. Shift: TShiftState; X, Y: Integer);
  117. procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState; X,
  118. Y: Integer);
  119. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
  120. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  121. procedure btnMoveToPosClick(Sender: TObject);
  122. procedure btnZoomToDistanceClick(Sender: TObject);
  123. procedure btnOrbitToPosClick(Sender: TObject);
  124. procedure btnSafeOrbitAndZoomToPosClick(Sender: TObject);
  125. procedure GLSceneViewer1MouseUp(Sender: TObject; Button: TMouseButton;
  126. Shift: TShiftState; X, Y: Integer);
  127. procedure FormClose(Sender: TObject; var Action: TCloseAction);
  128. procedure FormCreate(Sender: TObject);
  129. procedure GLCadencer1Progress(Sender: TObject; const deltaTime,
  130. newTime: Double);
  131. procedure btnOrbitToPosAdvClick(Sender: TObject);
  132. procedure Timer1Timer(Sender: TObject);
  133. procedure btSmoothOrbitToPosAdvClick(Sender: TObject);
  134. procedure btSmoothOrbitClick(Sender: TObject);
  135. procedure btSmoothOrbitAndZoomClick(Sender: TObject);
  136. private
  137. FGLCameraController : TGLCameraController;
  138. DextX, DextY, DextZ, Time, ZoomDistance: double;
  139. mx, my : Integer;
  140. FCameraSmoothAnimator_AbsPos: TGLNavigatorSmoothChangeVector;
  141. FCameraSmoothAnimator_RelPos: TGLNavigatorSmoothChangeVector;
  142. procedure GetInput(Sender:TButton);
  143. function OnGetCameraPosition(const ASender: TGLNavigatorSmoothChangeVector): TGLVector;
  144. procedure OnSetCameraPosition(const ASender: TGLNavigatorSmoothChangeVector; const AValue: TGLVector);
  145. public
  146. end;
  147. var
  148. Form1: TForm1;
  149. implementation
  150. {$R *.dfm}
  151. procedure TForm1.GetInput(Sender:TButton);
  152. begin
  153. FCameraSmoothAnimator_AbsPos.Enabled := False;
  154. FCameraSmoothAnimator_RelPos.Enabled := False;
  155. if (Sender = btnMoveToPos) or
  156. (Sender = btnOrbitToPos) or
  157. (Sender = btnOrbitToPosAdv) or
  158. (Sender = btnSafeOrbitAndZoomToPos) or
  159. (Sender = btSmoothOrbit) or
  160. (Sender = btSmoothOrbitAndZoom) or
  161. (Sender = btSmoothOrbitToPosAdv) then
  162. begin
  163. DextX:=strtofloat(eDestX.text);
  164. DextY:=strtofloat(eDestY.text);
  165. DextZ:=strtofloat(eDestZ.text);
  166. end;
  167. if (Sender = btnMoveToPos) or
  168. (Sender.Name='btnZoomToDistance') or
  169. (Sender.Name='btnOrbitToPosAdv') or
  170. (Sender.Name='btnOrbitToPos') then
  171. begin
  172. Time:= strtofloat(eTime.text);
  173. end;
  174. if (Sender.Name='btnZoomToDistance')then
  175. begin
  176. ZoomDistance:= strtofloat(eDistance.text)
  177. end;
  178. if (Sender.Name='btnSafeOrbitAndZoomToPos')then
  179. begin
  180. FGLCameraController.soSafeDistance := strtofloat(eSafeDistance.text);
  181. FGLCameraController.soTimeToSafePlacement := strtofloat(eTimeToSafePlacement.text);
  182. FGLCameraController.soTimeToOrbit := strtofloat(eTimeToOrbit.text);
  183. FGLCameraController.soTimeToZoomBackIn := strtofloat(eTimeToZoomBackIn.text);
  184. end;
  185. end;
  186. function TForm1.OnGetCameraPosition(const ASender: TGLNavigatorSmoothChangeVector): TGLVector;
  187. begin
  188. if ASender = FCameraSmoothAnimator_AbsPos then
  189. Result := GLCamera.AbsolutePosition
  190. else
  191. Result := GLCamera.Position.DirectVector;
  192. end;
  193. procedure TForm1.OnSetCameraPosition(const ASender: TGLNavigatorSmoothChangeVector; const AValue: TGLVector);
  194. begin
  195. if ASender = FCameraSmoothAnimator_AbsPos then
  196. GLCamera.AbsolutePosition := AValue
  197. else
  198. GLCamera.Position.AsVector := AValue;
  199. end;
  200. procedure TForm1.FormCreate(Sender: TObject);
  201. begin
  202. FGLCameraController := GLCameraController1;
  203. FCameraSmoothAnimator_AbsPos := TGLNavigatorSmoothChangeVector.Create(GLSmoothNavigator.CustomAnimatedItems);
  204. FCameraSmoothAnimator_AbsPos.Enabled := False;
  205. FCameraSmoothAnimator_AbsPos.Inertia := 0.6;
  206. FCameraSmoothAnimator_AbsPos.Speed := 1;
  207. FCameraSmoothAnimator_AbsPos.SpeedLimit := 5000;
  208. FCameraSmoothAnimator_AbsPos.Cutoff := 0.0001;
  209. FCameraSmoothAnimator_AbsPos.OnGetCurrentValue := OnGetCameraPosition;
  210. FCameraSmoothAnimator_AbsPos.OnSetCurrentValue := OnSetCameraPosition;
  211. FCameraSmoothAnimator_RelPos := TGLNavigatorSmoothChangeVector.Create(GLSmoothNavigator.CustomAnimatedItems);
  212. FCameraSmoothAnimator_RelPos.Assign(FCameraSmoothAnimator_AbsPos);
  213. GLSmoothNavigator.MovingObject := GLCamera;
  214. GLSmoothNavigator.MoveAroundParams.TargetObject := GLCamera.TargetObject;
  215. end;
  216. //MoveToPos Usage
  217. procedure TForm1.btnMoveToPosClick(Sender: TObject);
  218. begin
  219. GetInput(TButton(Sender));
  220. FGLCameraController.MoveToPos(DextX, DextY, DextZ, Time);
  221. end;
  222. //ZoomToDistance Usage
  223. procedure TForm1.btnZoomToDistanceClick(Sender: TObject);
  224. begin
  225. GetInput(TButton(Sender));
  226. FGLCameraController.ZoomToDistance(ZoomDistance,Time);
  227. end;
  228. //OrbitToPos Usage
  229. procedure TForm1.btnOrbitToPosClick(Sender: TObject);
  230. var
  231. lTargetPosition: TGLVector;
  232. begin
  233. GetInput(TButton(Sender));
  234. lTargetPosition := dcSphere.LocalToAbsolute(PointMake(DextX, DextY, DextZ));
  235. FGLCameraController.OrbitToPos(lTargetPosition.X, lTargetPosition.Y, lTargetPosition.Z, Time);
  236. end;
  237. procedure TForm1.btnOrbitToPosAdvClick(Sender: TObject);
  238. var
  239. lTargetPosition: TGLVector;
  240. begin
  241. GetInput(TButton(Sender));
  242. lTargetPosition := dcSphere.LocalToAbsolute(PointMake(DextX, DextY, DextZ));
  243. FGLCameraController.OrbitToPosAdvanced(lTargetPosition.X, lTargetPosition.Y, lTargetPosition.Z, Time, UpAxis.Checked);
  244. end;
  245. //SafeOrbitAndZoomToPos Usage
  246. procedure TForm1.btnSafeOrbitAndZoomToPosClick(Sender: TObject);
  247. begin
  248. GetInput(TButton(Sender));
  249. FGLCameraController.SafeOrbitAndZoomToPos(DextX, DextY, DextZ);
  250. end;
  251. //GUI Implementation - Pay attention to FGLCameraController.AllowUserAction!
  252. procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  253. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  254. begin
  255. FCameraSmoothAnimator_AbsPos.Enabled := False;
  256. FCameraSmoothAnimator_RelPos.Enabled := False;
  257. GLCamera.AdjustDistanceToTarget(Power(1.1, WheelDelta/120));
  258. end;
  259. procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  260. newTime: Double);
  261. begin
  262. if cbMoveParent.Checked then
  263. begin
  264. dcMovingParent.Position.X := Sin(newTime * 1.5) * 8;
  265. end;
  266. // For btSmoothOrbitAndZoomClick Order of these commands is important.
  267. GLSmoothNavigator.AdjustDistanceToTarget(0, deltaTime);
  268. FGLCameraController.Step(deltaTime, newTime);
  269. // This component requires FixedDeltaTime higher than FMaxExpectedDeltatime.
  270. GLSmoothNavigator.AnimateCustomItems(deltaTime);
  271. end;
  272. procedure TForm1.GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  273. Shift: TShiftState; X, Y: Integer);
  274. begin
  275. FCameraSmoothAnimator_AbsPos.Enabled := False;
  276. FCameraSmoothAnimator_RelPos.Enabled := False;
  277. FGLCameraController.StopMovement;
  278. if Shift=[ssLeft] then
  279. begin
  280. mx:=x; my:=y;
  281. end;
  282. end;
  283. procedure TForm1.GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState; X,
  284. Y: Integer);
  285. begin
  286. if Shift=[ssLeft] then
  287. begin
  288. GLCamera.MoveAroundTarget(my-Y, mx-X);
  289. mx:=X; my:=Y;
  290. Caption:= 'Camera Controller - camera position = ' +
  291. FormatFloat('0.##',GLCamera.Position.X)+'/'+
  292. FormatFloat('0.##',GLCamera.Position.Y)+'/'+
  293. FormatFloat('0.##',GLCamera.Position.Z);
  294. end;
  295. end;
  296. procedure TForm1.GLSceneViewer1MouseUp(Sender: TObject;
  297. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  298. begin
  299. Caption:= 'Camera Controller';
  300. end;
  301. procedure TForm1.Timer1Timer(Sender: TObject);
  302. begin
  303. camDirX.Text := Format('%.4f',[GLCamera.Direction.X]);
  304. camDirY.Text := Format('%.4f',[GLCamera.Direction.Y]);
  305. camDirZ.Text := Format('%.4f',[GLCamera.Direction.Z]);
  306. camUpX.Text := Format('%.4f',[GLCamera.Up.X]);
  307. camUpY.Text := Format('%.4f',[GLCamera.Up.Y]);
  308. camUpZ.Text := Format('%.4f',[GLCamera.Up.Z]);
  309. end;
  310. procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
  311. begin
  312. GLCadencer1.Enabled := False;
  313. end;
  314. procedure TForm1.btSmoothOrbitClick(Sender: TObject);
  315. var
  316. lAngle: Single; // In radians.
  317. lTime: Single;
  318. lNeedToRecalculateZoom: Boolean;
  319. lTargetPosition: TGLVector;
  320. begin
  321. GetInput(TButton(Sender));
  322. lTargetPosition := dcSphere.LocalToAbsolute(PointMake(DextX, DextY, DextZ));
  323. lAngle := AngleBetweenVectors(GLCamera.AbsolutePosition, lTargetPosition, GLSphere1.AbsolutePosition);
  324. // The final look and feel of smooth animation is affected by
  325. // FCameraSmoothAnimator_AbsPos's propperties and this value.
  326. lTime := lAngle * 2;
  327. FCameraSmoothAnimator_RelPos.ResetTargetValue();
  328. FCameraSmoothAnimator_RelPos.Enabled := True;
  329. if Sender = btSmoothOrbit then
  330. lNeedToRecalculateZoom := False
  331. else if Sender = btSmoothOrbitAndZoom then
  332. lNeedToRecalculateZoom := True
  333. else
  334. begin
  335. lNeedToRecalculateZoom := False;
  336. Assert(False);
  337. end;
  338. FGLCameraController.OrbitToPosSmooth(lTargetPosition, lTime,
  339. FCameraSmoothAnimator_RelPos, lNeedToRecalculateZoom, @YHmgVector);
  340. end;
  341. procedure TForm1.btSmoothOrbitAndZoomClick(Sender: TObject);
  342. begin
  343. btSmoothOrbitClick(btSmoothOrbitAndZoom);
  344. GLSmoothNavigator.AdjustDistanceParams.AddImpulse( Sign(Random - 0.5) * 10);
  345. end;
  346. procedure TForm1.btSmoothOrbitToPosAdvClick(Sender: TObject);
  347. var
  348. lAngle: Single; // In radians.
  349. lTime: Single;
  350. lTargetPosition: TGLVector;
  351. begin
  352. GetInput(TButton(Sender));
  353. lTargetPosition := dcSphere.LocalToAbsolute(PointMake(DextX, DextY, DextZ));
  354. lAngle := AngleBetweenVectors(GLCamera.AbsolutePosition, lTargetPosition, GLSphere1.AbsolutePosition);
  355. lTime := lAngle; // Speed can be controled by applying a multiplier here.
  356. FCameraSmoothAnimator_AbsPos.TargetValue.DirectVector := GLCamera.AbsolutePosition;
  357. FCameraSmoothAnimator_AbsPos.Enabled := True;
  358. FGLCameraController.OrbitToPosAdvancedSmooth(
  359. lTargetPosition.X, lTargetPosition.Y, lTargetPosition.Z,
  360. lTime, FCameraSmoothAnimator_AbsPos);
  361. end;
  362. initialization
  363. FormatSettings.DecimalSeparator := '.';
  364. end.