fOdeConveyor.pas 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. unit fOdeConveyor;
  2. interface
  3. uses
  4. Winapi.Windows,
  5. Winapi.Messages,
  6. System.SysUtils,
  7. System.Variants,
  8. System.Classes,
  9. Vcl.Graphics,
  10. Vcl.Controls,
  11. Vcl.Forms,
  12. Vcl.Dialogs,
  13. Vcl.StdCtrls,
  14. Vcl.ComCtrls,
  15. Vcl.ExtCtrls,
  16. Imports.ODE,
  17. Physics.ODEManager,
  18. GLS.Scene,
  19. GLS.VectorTypes,
  20. GLS.Objects,
  21. GLS.Cadencer,
  22. GLS.Coordinates,
  23. GLS.BaseClasses,
  24. GLS.SceneViewer,
  25. GLS.VectorGeometry,
  26. GLS.Keyboard,
  27. GLS.SimpleNavigation;
  28. type
  29. TFormOdeConveyor = class(TForm)
  30. GLSceneViewer1: TGLSceneViewer;
  31. GLScene1: TGLScene;
  32. GLCamera1: TGLCamera;
  33. GLLightSource1: TGLLightSource;
  34. GLCube1: TGLCube;
  35. ConveyorBelt1: TGLCube;
  36. GLCadencer1: TGLCadencer;
  37. GLODEManager1: TGLODEManager;
  38. GLRenderPoint1: TGLRenderPoint;
  39. GLSimpleNavigation1: TGLSimpleNavigation;
  40. Panel1: TPanel;
  41. Label1: TLabel;
  42. TrackBarMotionSpeed: TTrackBar;
  43. Label2: TLabel;
  44. Friction: TEdit;
  45. FrictionFeedback: TLabel;
  46. FDirX: TEdit;
  47. Label3: TLabel;
  48. Label4: TLabel;
  49. Label5: TLabel;
  50. FDirY: TEdit;
  51. Label6: TLabel;
  52. FDirZ: TEdit;
  53. NormZ: TLabel;
  54. NormY: TLabel;
  55. NormX: TLabel;
  56. AddODECube: TButton;
  57. SpawnPoint: TGLDummyCube;
  58. procedure GLCadencer1Progress(Sender: TObject;
  59. const deltaTime, newTime: Double);
  60. procedure FormShow(Sender: TObject);
  61. procedure GLODEManager1Collision(Sender, Object1, Object2: TObject;
  62. var Contact: TdContact; var HandleCollision: Boolean);
  63. procedure TrackBarMotionSpeedChange(Sender: TObject);
  64. procedure FrictionChange(Sender: TObject);
  65. procedure FormCreate(Sender: TObject);
  66. procedure FDirChange(Sender: TObject);
  67. procedure AddODECubeClick(Sender: TObject);
  68. private
  69. FUserDirection: TGLVector;
  70. FDirectionVector: TGLVector;
  71. end;
  72. var
  73. FormOdeConveyor: TFormOdeConveyor;
  74. implementation
  75. {$R *.dfm}
  76. procedure TFormOdeConveyor.FormCreate(Sender: TObject);
  77. begin
  78. // Initialize default values from the one of DesignTime;
  79. with GetOrCreateOdeStatic(ConveyorBelt1) do
  80. begin
  81. TrackBarMotionSpeed.Position := Round(Surface.Motion1);
  82. Friction.Text := FloatToStr(Surface.Mu);
  83. end;
  84. FDirX.Text := '0';
  85. FDirY.Text := '0';
  86. FDirZ.Text := '1';
  87. end;
  88. procedure TFormOdeConveyor.FormShow(Sender: TObject);
  89. begin
  90. GLCadencer1.Enabled := true;
  91. end;
  92. procedure TFormOdeConveyor.GLCadencer1Progress(Sender: TObject;
  93. const deltaTime, newTime: Double);
  94. begin
  95. GLODEManager1.Step(deltaTime);
  96. end;
  97. procedure TFormOdeConveyor.GLODEManager1Collision(Sender, Object1, Object2: TObject;
  98. var Contact: TdContact; var HandleCollision: Boolean);
  99. begin
  100. if Object2 = GetOrCreateOdeStatic(ConveyorBelt1) then
  101. begin
  102. Contact.fdir1[0] := FDirectionVector.X;
  103. Contact.fdir1[1] := FDirectionVector.Y;
  104. Contact.fdir1[2] := FDirectionVector.Z;
  105. Contact.fdir1[3] := FDirectionVector.W; // not used
  106. end;
  107. end;
  108. procedure TFormOdeConveyor.TrackBarMotionSpeedChange(Sender: TObject);
  109. begin
  110. GetOrCreateOdeStatic(ConveyorBelt1).Surface.Motion1 := TrackBarMotionSpeed.Position;
  111. end;
  112. procedure TFormOdeConveyor.FrictionChange(Sender: TObject);
  113. begin
  114. with GetOrCreateOdeStatic(ConveyorBelt1) do
  115. begin
  116. Surface.Mu := StrToFloatDef(Friction.Text, Surface.Mu);
  117. FrictionFeedback.Caption := Format('µs = %.2f', [Surface.Mu]);
  118. end;
  119. end;
  120. procedure TFormOdeConveyor.AddODECubeClick(Sender: TObject);
  121. var
  122. ACube: TGLCube;
  123. AODEDynamic: TGLODEDynamic;
  124. AODEElementBox: TGLODEElementBox;
  125. begin
  126. // Create a new GLScene cube and add it to the current GLScene1
  127. ACube := TGLCube.Create(GLScene1.Objects);
  128. with ACube do
  129. begin
  130. Parent := GLScene1.Objects;
  131. Position.Assign(SpawnPoint.Position);
  132. Material.FrontProperties.Diffuse.RandomColor;
  133. end;
  134. // Add ODE Dynamic behaviour on it
  135. AODEDynamic := GetOrCreateOdeDynamic(ACube);
  136. AODEDynamic.Manager := GLODEManager1;
  137. // Set µs value to 1 (default=1000), just uses the one from the conveyor
  138. AODEDynamic.Surface.Mu := 1;
  139. // Finally create physical data in this behaviour
  140. AODEElementBox := TGLODEElementBox(AODEDynamic.AddNewElement(TGLODEElementBox));
  141. if Assigned(AODEElementBox) then
  142. with AODEElementBox do
  143. begin
  144. BoxWidth := ACube.CubeWidth;
  145. BoxDepth := ACube.CubeDepth;
  146. BoxHeight := ACube.CubeHeight;
  147. end;
  148. // The new camera target is the last added cube
  149. GLCamera1.TargetObject := ACube;
  150. // The spawn position is increased
  151. SpawnPoint.Position.Y := SpawnPoint.Position.Y + 1;
  152. end;
  153. procedure TFormOdeConveyor.FDirChange(Sender: TObject);
  154. begin
  155. // Get back user data from GUI
  156. FUserDirection.X := StrToFloatDef(FDirX.Text, FUserDirection.X); // x
  157. FUserDirection.Y := StrToFloatDef(FDirY.Text, FUserDirection.Y); // y
  158. FUserDirection.Z := StrToFloatDef(FDirZ.Text, FUserDirection.Z); // z
  159. FUserDirection.W := 0; // not used
  160. // Copy user data and normalized it
  161. FDirectionVector := FUserDirection;
  162. NormalizeVector(FDirectionVector);
  163. // Now returned normalized data to user to understand the 1-unit thing
  164. NormX.Caption := Format('Norm(X) = %.3f', [FDirectionVector.X]);
  165. NormY.Caption := Format('Norm(Y) = %.3f', [FDirectionVector.Y]);
  166. NormZ.Caption := Format('Norm(Z) = %.3f', [FDirectionVector.Z]);
  167. end;
  168. end.