fMeshHitD.pas 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. unit fMeshHitD;
  2. interface
  3. uses
  4. Winapi.OpenGL,
  5. System.SysUtils,
  6. System.Classes,
  7. Vcl.Controls,
  8. Vcl.Forms,
  9. Vcl.StdCtrls,
  10. GLS.Scene,
  11. GLS.VectorFileObjects,
  12. GLS.Objects,
  13. GLS.SceneViewer,
  14. GLScene.VectorTypes,
  15. GLScene.VectorGeometry,
  16. GLS.GeomObjects,
  17. GLS.Coordinates,
  18. GLS.BaseClasses,
  19. GLS.File3DS,
  20. GLScene.Utils;
  21. type
  22. TFormMeshHit = class(TForm)
  23. GLSceneViewer1: TGLSceneViewer;
  24. GLScene1: TGLScene;
  25. GLCamera1: TGLCamera;
  26. GLLightSource1: TGLLightSource;
  27. DummyCube1: TGLDummyCube;
  28. FreeForm1: TGLFreeForm;
  29. Sphere1: TGLSphere;
  30. ArrowLine1: TGLArrowLine;
  31. GLSceneViewer2: TGLSceneViewer;
  32. GLCamera2: TGLCamera;
  33. Label1: TLabel;
  34. Label2: TLabel;
  35. procedure FormCreate(Sender: TObject);
  36. procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  37. Shift: TShiftState; X, Y: Integer);
  38. procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
  39. X, Y: Integer);
  40. procedure GLSceneViewer2MouseDown(Sender: TObject; Button: TMouseButton;
  41. Shift: TShiftState; X, Y: Integer);
  42. procedure GLSceneViewer2MouseMove(Sender: TObject; Shift: TShiftState;
  43. X, Y: Integer);
  44. private
  45. end;
  46. var
  47. FormMeshHit: TFormMeshHit;
  48. implementation
  49. {$R *.dfm}
  50. procedure TFormMeshHit.FormCreate(Sender: TObject);
  51. begin
  52. // Load mushroom mesh
  53. var Path: TFileName := GetCurrentAssetPath();
  54. SetCurrentDir(Path + '\model');
  55. FreeForm1.LoadFromFile('mushroom.3ds');
  56. end;
  57. // Perform the raycasting for the perspective camera & viewer
  58. procedure TFormMeshHit.GLSceneViewer1MouseDown(Sender: TObject;
  59. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  60. var
  61. rayStart, rayVector, iPoint, iNormal: TGLVector;
  62. begin
  63. // retrieve raycasting data:
  64. // rayStart is obtained for camera and screen position
  65. // rayVector is the camera direction (i.e direction to target since our camera is targeted)
  66. // (note that (0, 0) is lower left for the Screen function, whereas Delphi
  67. // uses top-left as origin, hence the Y inversion)
  68. SetVector(rayStart, GLSceneViewer1.Buffer.OrthoScreenToWorld(X,
  69. GLSceneViewer1.Height - Y));
  70. SetVector(rayVector, GLCamera1.AbsoluteVectorToTarget);
  71. NormalizeVector(rayVector);
  72. // Here we require RayCast intersection
  73. if FreeForm1.RayCastIntersect(rayStart, rayVector, @iPoint, @iNormal) then
  74. begin
  75. // got one, move the sphere there and orient it appropriately
  76. Sphere1.Position.AsVector := iPoint;
  77. Sphere1.Direction.AsVector := VectorNormalize(iNormal);
  78. // make it visible
  79. Sphere1.Visible := True;
  80. end
  81. else
  82. begin
  83. // hide it if we did not hit
  84. Sphere1.Visible := False;
  85. end;
  86. end;
  87. procedure TFormMeshHit.GLSceneViewer1MouseMove(Sender: TObject;
  88. Shift: TShiftState; X, Y: Integer);
  89. begin
  90. // when mouse moves, recompute intersection
  91. if Shift <> [] then
  92. GLSceneViewer1MouseDown(Sender, TMouseButton(mbLeft), Shift, X, Y);
  93. end;
  94. // Perform the raycasting for the perspective camera & viewer
  95. procedure TFormMeshHit.GLSceneViewer2MouseDown(Sender: TObject;
  96. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  97. var
  98. rayStart, rayVector, iPoint, iNormal: TGLVector;
  99. begin
  100. // retrieve raycasting data:
  101. // rayStart is the eye (camera) position
  102. // rayVector is computed from screen position
  103. // (note that (0, 0) is lower left for the Screen function, whereas Delphi
  104. // uses top-left as origin, hence the Y inversion)
  105. SetVector(rayStart, GLCamera2.AbsolutePosition);
  106. SetVector(rayVector, GLSceneViewer2.Buffer.ScreenToVector(AffineVectorMake(X,
  107. GLSceneViewer2.Height - Y, 0)));
  108. NormalizeVector(rayVector);
  109. // Here we request RayCast intersection
  110. if FreeForm1.RayCastIntersect(rayStart, rayVector, @iPoint, @iNormal) then
  111. begin
  112. // got one, move the sphere there and orient it appropriately
  113. Sphere1.Position.AsVector := iPoint;
  114. Sphere1.Direction.AsVector := VectorNormalize(iNormal);
  115. // make it visible
  116. Sphere1.Visible := True;
  117. end
  118. else
  119. begin
  120. // hide it if we did not hit
  121. Sphere1.Visible := False;
  122. end;
  123. end;
  124. procedure TFormMeshHit.GLSceneViewer2MouseMove(Sender: TObject;
  125. Shift: TShiftState; X, Y: Integer);
  126. begin
  127. if Shift <> [] then
  128. GLSceneViewer2MouseDown(Sender, TMouseButton(mbLeft), Shift, X, Y);
  129. end;
  130. end.