fActorTwocamD.pas 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. unit fActorTwocamD;
  2. interface
  3. uses
  4. Winapi.Windows,
  5. Winapi.OpenGL,
  6. System.SysUtils,
  7. System.Classes,
  8. System.UITypes,
  9. Vcl.Imaging.Jpeg,
  10. Vcl.Buttons,
  11. Vcl.Controls,
  12. Vcl.ExtCtrls,
  13. Vcl.ComCtrls,
  14. Vcl.Forms,
  15. Vcl.StdCtrls,
  16. Vcl.Graphics,
  17. GLScene.Keyboard,
  18. GLScene.VectorTypes,
  19. GLS.Coordinates,
  20. GLS.BaseClasses,
  21. GLScene.Utils,
  22. GLScene.VectorGeometry,
  23. GLS.XCollection,
  24. GLS.PersistentClasses,
  25. GLS.Scene,
  26. GLS.Objects,
  27. GLS.Cadencer,
  28. GLS.VectorFileObjects,
  29. GLS.SkyDome,
  30. GLS.SceneViewer,
  31. GLS.Navigator,
  32. GLS.FileMD2,
  33. GLS.File3DS,
  34. GLS.GeomObjects,
  35. GLS.DCE;
  36. type
  37. TFormActorTwocam = class(TForm)
  38. GLScene1: TGLScene;
  39. GLCamera1: TGLCamera;
  40. dcMushroom: TGLDummyCube;
  41. diskClover: TGLDisk;
  42. GLSceneViewer1: TGLSceneViewer;
  43. Actor1: TGLActor;
  44. Actor2: TGLActor;
  45. GLCadencer1: TGLCadencer;
  46. Panel1: TPanel;
  47. Timer1: TTimer;
  48. GLCamera2: TGLCamera;
  49. Label3: TLabel;
  50. Label4: TLabel;
  51. DummyCube2: TGLDummyCube;
  52. ffMushroom: TGLFreeForm;
  53. GLLightSource2: TGLLightSource;
  54. DummyCube3: TGLDummyCube;
  55. Label1: TLabel;
  56. SkyDome1: TGLSkyDome;
  57. GLNavigator1: TGLNavigator;
  58. GLUserInterface1: TGLUserInterface;
  59. CBMouseLook: TCheckBox;
  60. GLDCEManager1: TGLDCEManager;
  61. procedure FormCreate(Sender: TObject);
  62. procedure Timer1Timer(Sender: TObject);
  63. procedure GLCadencer1Progress(Sender: TObject;
  64. const deltaTime, newTime: Double);
  65. procedure CBMouseLookClick(Sender: TObject);
  66. private
  67. Path: TFileName;
  68. procedure AddMushrooms;
  69. procedure HandleKeys(const deltaTime: Double);
  70. end;
  71. var
  72. FormActorTwocam: TFormActorTwocam;
  73. implementation
  74. {$R *.DFM}
  75. const
  76. cWalkStep = 6; // this is our walking speed, in 3D units / second
  77. cStrafeStep = 6; // this is our strafing speed, in 3D units / second
  78. cRotAngle = 60; // this is our turning speed, in degrees / second
  79. cRunBoost = 2; // speed boost when running
  80. cSpread = 90;
  81. cNbMushrooms = 15;
  82. procedure TFormActorTwocam.FormCreate(Sender: TObject);
  83. begin
  84. Path := GetCurrentAssetPath();
  85. SetCurrentDir(Path + '\model');
  86. // Load static mushroom mesh
  87. ffMushroom.LoadFromFile('mushroom.3ds');
  88. // Duplicate our reference mushroom (but not its mesh data !)
  89. AddMushrooms;
  90. // Load skeletal Actor model
  91. SetCurrentDir(Path + '\modelext');
  92. Actor1.LoadFromFile('waste.md2');
  93. Actor1.Animations.LoadFromFile('Quake2Animations.aaf');
  94. Actor1.Scale.SetVector(0.04, 0.04, 0.04, 0);
  95. // Load weapon model
  96. Actor2.LoadFromFile('WeaponWaste.md2');
  97. // Load weapon texture
  98. Actor1.Material.Texture.Image.LoadFromFile('Waste.jpg');
  99. Actor2.Material.Texture.Image.LoadFromFile('WeaponWaste.jpg');
  100. Actor2.Animations.Assign(Actor1.Animations);
  101. // Define animation properties
  102. Actor1.AnimationMode := aamLoop;
  103. Actor1.SwitchToAnimation('stand');
  104. Actor1.FrameInterpolation := afpLinear;
  105. Actor2.Synchronize(Actor1);
  106. // Load Texture for ground disk
  107. SetCurrentDir(Path + '\texture');
  108. diskClover.Material.Texture.Disabled := False;
  109. diskClover.Material.Texture.Image.LoadFromFile('clover.jpg');
  110. end;
  111. procedure TFormActorTwocam.CBMouseLookClick(Sender: TObject);
  112. begin
  113. GLUserInterface1.MouseLookActive := CBMouseLook.Checked;
  114. end;
  115. procedure TFormActorTwocam.HandleKeys(const deltaTime: Double);
  116. var
  117. moving: String;
  118. boost: Single;
  119. begin
  120. // This function uses asynchronous keyboard check (see GLS.XCollection.pas)
  121. if IsKeyDown(VK_ESCAPE) then
  122. Close;
  123. if IsKeyDown('A') then
  124. begin
  125. CBMouseLook.Checked := True;
  126. CBMouseLookClick(Self);
  127. end;
  128. if IsKeyDown('D') then
  129. begin
  130. CBMouseLook.Checked := False;
  131. CBMouseLookClick(Self);
  132. end;
  133. // Change Cameras
  134. if IsKeyDown(VK_F7) then
  135. begin
  136. GLSceneViewer1.Camera := GLCamera1;
  137. Actor1.Visible := True;
  138. Label4.Font.Style := Label4.Font.Style - [fsBold];
  139. Label3.Font.Style := Label3.Font.Style + [fsBold];
  140. end;
  141. if IsKeyDown(VK_F8) then
  142. begin
  143. GLSceneViewer1.Camera := GLCamera2;
  144. Actor1.Visible := False;
  145. Label4.Font.Style := Label4.Font.Style + [fsBold];
  146. Label3.Font.Style := Label3.Font.Style - [fsBold];
  147. end;
  148. // Move Actor in the scene
  149. // if nothing specified, we are standing
  150. moving := 'stand';
  151. // first, are we running ? if yes give animation & speed a boost
  152. if IsKeyDown(VK_SHIFT) then
  153. begin
  154. Actor1.Interval := 100;
  155. boost := cRunBoost * deltaTime
  156. end
  157. else
  158. begin
  159. Actor1.Interval := 150;
  160. boost := deltaTime;
  161. end;
  162. Actor2.Interval := Actor1.Interval;
  163. // are we advaning/backpedaling ?
  164. if IsKeyDown(VK_UP) then
  165. begin
  166. GLNavigator1.MoveForward(cWalkStep * boost);
  167. moving := 'run';
  168. end;
  169. if IsKeyDown(VK_DOWN) then
  170. begin
  171. GLNavigator1.MoveForward(-cWalkStep * boost);
  172. moving := 'run';
  173. end;
  174. // slightly more complex, depending on CTRL key, we either turn or strafe
  175. if IsKeyDown(VK_LEFT) then
  176. begin
  177. if IsKeyDown(VK_CONTROL) then
  178. GLNavigator1.StrafeHorizontal(-cStrafeStep * boost)
  179. else
  180. GLNavigator1.TurnHorizontal(-cRotAngle * boost);
  181. moving := 'run';
  182. end;
  183. if IsKeyDown(VK_RIGHT) then
  184. begin
  185. if IsKeyDown(VK_CONTROL) then
  186. GLNavigator1.StrafeHorizontal(cStrafeStep * boost)
  187. else
  188. GLNavigator1.TurnHorizontal(cRotAngle * boost);
  189. moving := 'run';
  190. end;
  191. // update animation (if required)
  192. // you can use faster methods (such as storing the last value of "moving")
  193. // but this ones shows off the brand new "CurrentAnimation" function :)
  194. if Actor1.CurrentAnimation <> moving then
  195. begin
  196. Actor1.SwitchToAnimation(moving);
  197. Actor2.Synchronize(Actor1);
  198. end;
  199. end;
  200. procedure TFormActorTwocam.GLCadencer1Progress(Sender: TObject;
  201. const deltaTime, newTime: Double);
  202. begin
  203. HandleKeys(deltaTime);
  204. GLUserInterface1.MouseLook;
  205. GLSceneViewer1.Invalidate;
  206. GLUserInterface1.MouseUpdate;
  207. end;
  208. // add a few mushrooms to make the "landscape"
  209. procedure TFormActorTwocam.AddMushrooms;
  210. var
  211. i: Integer;
  212. proxy: TGLProxyObject;
  213. s: TGLVector;
  214. f: Single;
  215. begin
  216. // spawn some more mushrooms using proxy objects
  217. for i := 0 to cNbMushrooms - 1 do
  218. begin
  219. // create a new proxy and set its MasterObject property
  220. proxy := TGLProxyObject(dcMushroom.AddNewChild(TGLProxyObject));
  221. proxy.ProxyOptions := [pooObjects];
  222. proxy.MasterObject := ffMushroom;
  223. // retrieve reference attitude
  224. proxy.Direction := ffMushroom.Direction;
  225. proxy.Up := ffMushroom.Up;
  226. // randomize scale
  227. s := ffMushroom.Scale.AsVector;
  228. f := (1 * Random + 1);
  229. ScaleVector(s, f);
  230. proxy.Scale.AsVector := s;
  231. // randomize position
  232. proxy.Position.SetPoint(Random(cSpread) - (cSpread / 2),
  233. ffMushroom.Position.z + 0.8 * f, Random(cSpread) - (cSpread / 2));
  234. // randomize orientation
  235. proxy.RollAngle := Random(360);
  236. proxy.TransformationChanged;
  237. end;
  238. end;
  239. procedure TFormActorTwocam.Timer1Timer(Sender: TObject);
  240. begin
  241. Caption := Format('%.2f FPS', [GLSceneViewer1.FramesPerSecond]);
  242. GLSceneViewer1.ResetPerformanceMonitor;
  243. end;
  244. end.