fSkeletalD.pas 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. unit fSkeletalD;
  2. interface
  3. uses
  4. System.SysUtils,
  5. System.Classes,
  6. System.Types,
  7. System.Math,
  8. Vcl.Graphics,
  9. Vcl.Controls,
  10. Vcl.Forms,
  11. Vcl.Dialogs,
  12. Vcl.StdCtrls,
  13. Vcl.ComCtrls,
  14. Vcl.ExtCtrls,
  15. GLS.VectorFileObjects,
  16. GLS.Scene,
  17. GLS.Objects,
  18. GLS.Texture,
  19. GLS.Cadencer,
  20. GLS.SceneViewer,
  21. GLS.Graph,
  22. GLS.FileSMD,
  23. GLS.Material,
  24. GLS.Coordinates,
  25. GLS.BaseClasses,
  26. GLScene.VectorGeometry,
  27. GLScene.Utils;
  28. type
  29. TFormSkeletal = class(TForm)
  30. GLScene1: TGLScene;
  31. GLSceneViewer1: TGLSceneViewer;
  32. GLCamera1: TGLCamera;
  33. GLLightSource1: TGLLightSource;
  34. Actor1: TGLActor;
  35. DummyCube1: TGLDummyCube;
  36. GLMaterialLibrary1: TGLMaterialLibrary;
  37. Timer1: TTimer;
  38. GLCadencer1: TGLCadencer;
  39. Panel1: TPanel;
  40. BULongJump: TButton;
  41. CheckBox1: TCheckBox;
  42. LabelFPS: TLabel;
  43. BUHighJump: TButton;
  44. XYZGrid1: TGLXYZGrid;
  45. RBWalk: TRadioButton;
  46. RBRun: TRadioButton;
  47. AnimationControler1: TGLAnimationControler;
  48. Panel2: TPanel;
  49. TrackBar1: TTrackBar;
  50. CBBlend: TCheckBox;
  51. procedure FormCreate(Sender: TObject);
  52. procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  53. procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  54. X, Y: Integer);
  55. procedure Timer1Timer(Sender: TObject);
  56. procedure BULongJumpClick(Sender: TObject);
  57. procedure CheckBox1Click(Sender: TObject);
  58. procedure GLCadencer1Progress(Sender: TObject; const deltaTime, newTime: Double);
  59. procedure Actor1EndFrameReached(Sender: TObject);
  60. procedure BUHighJumpClick(Sender: TObject);
  61. procedure RBWalkClick(Sender: TObject);
  62. procedure RBRunClick(Sender: TObject);
  63. procedure TrackBar1Change(Sender: TObject);
  64. procedure CBBlendClick(Sender: TObject);
  65. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer;
  66. MousePos: TPoint; var Handled: Boolean);
  67. private
  68. public
  69. baseAnimation: String;
  70. mx, my: Integer;
  71. end;
  72. var
  73. FormSkeletal: TFormSkeletal;
  74. implementation
  75. {$R *.DFM}
  76. procedure TFormSkeletal.FormCreate(Sender: TObject);
  77. begin
  78. var Path: TFileName := GetCurrentAssetPath();
  79. SetCurrentDir(Path + '\modelext');
  80. // We load the SMD model here
  81. // Note the actor was linked to a material library, and textures are loaded
  82. // automatically (4 textures are used by this model)
  83. //
  84. // Kind thanks to ~A.u.s.t.i.n. & Neal 'Guplik' Corbett for the model
  85. // and allowing its use ;)
  86. Actor1.LoadFromFile('trinityRage.smd');
  87. // Now we load the walk & run animations and "fix" their translation
  88. // (HL walk/run animations have a built-in "slide" that we don't want here)
  89. Actor1.AddDataFromFile('walk.smd');
  90. Actor1.Animations[1].MakeSkeletalTranslationStatic;
  91. Actor1.AddDataFromFile('run.smd');
  92. Actor1.Animations[2].MakeSkeletalTranslationStatic;
  93. // Then load the two jumps
  94. Actor1.AddDataFromFile('long_jump.smd');
  95. Actor1.AddDataFromFile('jump.smd');
  96. // And the 'look_left_right' blending animations, that we immediately
  97. // assign to the controler. The MakeSkeletalRotationDelta removes absolute
  98. // information from the SMD (which HL may use, but GLScene doesn't)
  99. Actor1.AddDataFromFile('look_left_right.smd');
  100. Actor1.Animations[5].MakeSkeletalRotationDelta;
  101. AnimationControler1.AnimationName := 'look_left_right';
  102. // Skeleton visible, and start with walk animation
  103. // (pseudo-animation 0 is for the static model in its default attitude)
  104. Actor1.OverlaySkeleton := True;
  105. baseAnimation := 'walk';
  106. Actor1.SwitchToAnimation(baseAnimation);
  107. end;
  108. procedure TFormSkeletal.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer;
  109. MousePos: TPoint; var Handled: Boolean);
  110. begin
  111. GLCamera1 := GLSceneViewer1.Camera;
  112. GLCamera1.AdjustDistanceToTarget(Power(1.1, WheelDelta / 120));
  113. end;
  114. procedure TFormSkeletal.RBWalkClick(Sender: TObject);
  115. begin
  116. // user requested 'walk'
  117. baseAnimation := 'walk';
  118. Actor1.SwitchToAnimation(baseAnimation, True);
  119. end;
  120. procedure TFormSkeletal.RBRunClick(Sender: TObject);
  121. begin
  122. // user requested 'run'
  123. baseAnimation := 'run';
  124. Actor1.SwitchToAnimation(baseAnimation, True);
  125. end;
  126. procedure TFormSkeletal.BULongJumpClick(Sender: TObject);
  127. begin
  128. // Smoothly switch to Long Jump
  129. Actor1.SwitchToAnimation(3, True);
  130. end;
  131. procedure TFormSkeletal.BUHighJumpClick(Sender: TObject);
  132. begin
  133. // Smoothly switch to High Jump
  134. Actor1.SwitchToAnimation(4, True);
  135. end;
  136. procedure TFormSkeletal.Actor1EndFrameReached(Sender: TObject);
  137. begin
  138. // If we weren't walking, switch back to walk
  139. if Actor1.CurrentAnimation <> baseAnimation then
  140. Actor1.SwitchToAnimation(baseAnimation, True);
  141. end;
  142. procedure TFormSkeletal.CBBlendClick(Sender: TObject);
  143. begin
  144. // Enable/disable blending by binding or unbinding the animation controler
  145. // to the actor
  146. if CBBlend.Checked then
  147. begin
  148. AnimationControler1.Actor := Actor1;
  149. TrackBar1Change(Self);
  150. end
  151. else
  152. AnimationControler1.Actor := nil;
  153. end;
  154. procedure TFormSkeletal.TrackBar1Change(Sender: TObject);
  155. begin
  156. // Blending along the controler's animation is just a matter of adjusting
  157. // the ratio, with 0 = first frame and 1 = last frame.
  158. AnimationControler1.Ratio := TrackBar1.Position * 0.01;
  159. end;
  160. // Nothing fancy below, just the same old stuff
  161. procedure TFormSkeletal.CheckBox1Click(Sender: TObject);
  162. begin
  163. Actor1.OverlaySkeleton := CheckBox1.Checked;
  164. end;
  165. procedure TFormSkeletal.GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  166. Shift: TShiftState; X, Y: Integer);
  167. begin
  168. mx := X;
  169. my := Y;
  170. end;
  171. procedure TFormSkeletal.GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  172. begin
  173. if Shift <> [] then
  174. begin
  175. GLCamera1.MoveAroundTarget(my - Y, mx - X);
  176. mx := X;
  177. my := Y;
  178. end;
  179. end;
  180. procedure TFormSkeletal.Timer1Timer(Sender: TObject);
  181. begin
  182. LabelFPS.Caption := Format('%.1f FPS', [GLSceneViewer1.FramesPerSecond]);
  183. GLSceneViewer1.ResetPerformanceMonitor;
  184. end;
  185. procedure TFormSkeletal.GLCadencer1Progress(Sender: TObject; const deltaTime, newTime: Double);
  186. begin
  187. GLScene1.NotifyChange(nil);
  188. end;
  189. end.