fOdeRagdollD.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. unit fOdeRagdollD;
  2. interface
  3. uses
  4. Winapi.Windows,
  5. System.SysUtils,
  6. System.Variants,
  7. System.Classes,
  8. System.Math,
  9. Vcl.Graphics,
  10. Vcl.Controls,
  11. Vcl.Forms,
  12. Vcl.Dialogs,
  13. Vcl.ExtCtrls,
  14. Vcl.ComCtrls,
  15. Stage.VectorTypes,
  16. Stage.VectorGeometry,
  17. Stage.Keyboard,
  18. Stage.Utils,
  19. GLS.Scene,
  20. GLS.Objects,
  21. GLS.SceneViewer,
  22. GLS.Cadencer,
  23. GLS.ShadowPlane,
  24. GLS.GeomObjects,
  25. GLS.BitmapFont,
  26. GLS.WindowsFont,
  27. GLS.HUDObjects,
  28. GLS.XCollection,
  29. GLS.VectorFileObjects,
  30. GLS.Ragdoll,
  31. GLS.Texture,
  32. GLS.Material,
  33. GLS.Coordinates,
  34. GLS.BaseClasses,
  35. ODE.Import,
  36. GLS.ODERagdoll,
  37. GLS.FileSMD,
  38. GLS.ODEUtils;
  39. //Physic World ODE
  40. type
  41. TWorld_ODE = class
  42. world: PdxWorld;
  43. space: PdxSpace;
  44. contactgroup: TdJointGroupID;
  45. ground_box : PdxGeom;
  46. ground_box2 : PdxGeom;
  47. Cube: TGLCube;
  48. Cube2: TGLCube;
  49. ODEEnable : boolean;
  50. physTime : double;
  51. destructor Destroy; override;
  52. constructor Create;
  53. procedure WorldUpdate;
  54. end;
  55. //Form
  56. type
  57. TFormRagdoll = class(TForm)
  58. GLScene1: TGLScene;
  59. GLCadencer1: TGLCadencer;
  60. GLSceneViewer1: TGLSceneViewer;
  61. GLCamera1: TGLCamera;
  62. GLLightSource1: TGLLightSource;
  63. ODEScene: TGLDummyCube;
  64. GLShadowPlane1: TGLShadowPlane;
  65. Targetrag: TGLDummyCube;
  66. GLHUDText1: TGLHUDText;
  67. GLWindowsBitmapFont1: TGLWindowsBitmapFont;
  68. Actor1: TGLActor;
  69. GLMaterialLibrary1: TGLMaterialLibrary;
  70. procedure FormCreate(Sender: TObject);
  71. procedure GLSceneViewer1MouseDown(Sender: TObject;
  72. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  73. procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
  74. X, Y: Integer);
  75. procedure GLCadencer1Progress(Sender: TObject; const deltaTime,
  76. newTime: Double);
  77. procedure FormClose(Sender: TObject; var Action: TCloseAction);
  78. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
  79. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  80. procedure FormKeyUp(Sender: TObject; var Key: Word;
  81. Shift: TShiftState);
  82. private
  83. my,mx: integer;
  84. public
  85. end;
  86. var
  87. FormRagdoll: TFormRagdoll;
  88. WorldODE: TWorld_ODE;
  89. Rag: TGLODERagdoll;
  90. RagWorld: TGLODERagdollWorld;
  91. HeadBone, spine, torso, rightleg : TGLODERagdollBone;
  92. implementation
  93. {$R *.dfm}
  94. constructor TWorld_ODE.Create;
  95. var
  96. R : TdMatrix3;
  97. begin
  98. ODEEnable := False;
  99. PhysTime := 0;
  100. //Create physic
  101. world := dWorldCreate();
  102. dWorldSetQuickStepNumIterations(world, 8);
  103. space := dHashSpaceCreate (nil);
  104. contactgroup := dJointGroupCreate ( 0 );
  105. dWorldSetGravity (world, 0, 0, -0.81);
  106. dWorldSetCFM (world, 1e-5);
  107. //Floor
  108. dCreatePlane (space, 0, 0, 1, 0);
  109. //Box wall limit
  110. dCreatePlane (space, 0, 1, 0, -50.00);
  111. dCreatePlane (space, 1, 0, 0, -50.00);
  112. dCreatePlane (space, 0,-1, 0, -50.00);
  113. dCreatePlane (space, -1, 0, 0, -50.00);
  114. // Create 1 GLSCube and a box space.
  115. ground_box := dCreateBox (space,25,50,50);
  116. dRFromAxisAndAngle (R,0,1,0,0.95);
  117. dGeomSetPosition (ground_box,32,5,0.5);
  118. dGeomSetRotation (ground_box,R);
  119. Cube := TGLCube(FormRagdoll.ODEScene.AddNewChild(TGLCube));
  120. Cube.Material.FrontProperties.Ambient.RandomColor;
  121. PdxGeom(ground_box).data := Cube;
  122. CopyCubeSizeFromBox(Cube, ground_box);
  123. PositionSceneObject(TGLBaseSceneObject(PdxGeom(ground_box).data), ground_box);
  124. // Same Create 1 GLSCube and a box space.
  125. ground_box2 := dCreateBox (space,5,10,5);
  126. dRFromAxisAndAngle (R,0,1,0,0);
  127. dGeomSetPosition (ground_box2,-12,-5,2.5);
  128. dGeomSetRotation (ground_box2,R);
  129. Cube2 := TGLCube(FormRagdoll.ODEScene.AddNewChild(TGLCube));
  130. Cube2.Material.FrontProperties.Ambient.RandomColor;
  131. PdxGeom(ground_box2).data := Cube2;
  132. CopyCubeSizeFromBox(Cube2, ground_box2);
  133. PositionSceneObject(TGLBaseSceneObject(PdxGeom(ground_box2).data), ground_box2);
  134. // Create now a sphere
  135. ground_box2 := dCreateSphere (space,5);
  136. dGeomSetPosition (ground_box2,0,-15,2.5);
  137. PdxGeom(ground_box2).data := TGLSphere(FormRagdoll.ODEScene.AddNewChild(TGLSphere));
  138. TGLSphere(PdxGeom(ground_box2).data).Radius := 5;
  139. TGLSphere(PdxGeom(ground_box2).data).Material.FrontProperties.Ambient.RandomColor;
  140. PositionSceneObject(TGLSphere(PdxGeom(ground_box2).data), ground_box2);
  141. end;
  142. destructor TWorld_ODE.Destroy;
  143. begin
  144. //Destroy the physic
  145. dJointGroupDestroy (contactgroup);
  146. dSpaceDestroy (space);
  147. dWorldDestroy (world);
  148. inherited;
  149. end;
  150. procedure TWorld_ODE.WorldUpdate;
  151. const
  152. cDeltaTime = 1/50;
  153. begin
  154. physTime := physTime + cDeltaTime;
  155. RagWorld.WorldUpdate;
  156. FormRagdoll.GLSceneViewer1.Invalidate;
  157. end;
  158. // NEW1
  159. var
  160. rootBone : TGLODERagdollBone;
  161. hjoint: TGLODERagdollHingeJoint;
  162. JLeg: TGLODERagdollUniversalJoint;
  163. JTorso: TGLODERagdollUniversalJoint;
  164. JKnee: TGLODERagdollHingeJoint;
  165. JLArm,JRarm: TGLODERagdollHingeJoint;
  166. JShoulder: TGLODERagdollUniversalJoint;
  167. ujoint: TGLODERagdollUniversalJoint;
  168. JDummy: TGLODERagdollDummyJoint;
  169. procedure TFormRagdoll.FormCreate(Sender: TObject);
  170. var // rootBone,
  171. tb: TGLODERagdollBone;
  172. {
  173. hjoint: TGLODERagdollHingeJoint;
  174. JLeg: TGLODERagdollUniversalJoint;
  175. JTorso: TGLODERagdollUniversalJoint;
  176. JKnee: TGLODERagdollHingeJoint;
  177. JLArm,JRarm: TGLODERagdollHingeJoint;
  178. JShoulder: TGLODERagdollUniversalJoint;
  179. ujoint: TGLODERagdollUniversalJoint;
  180. JDummy: TGLODERagdollDummyJoint;
  181. }
  182. function bone(oBone: TGLODERagdollBone; id: String; j: TGLRagdolJoint): TGLODERagdollBone;
  183. var b: TGLODERagdollBone;
  184. begin
  185. b := TGLODERagdollBone.CreateOwned(oBone);
  186. with b do
  187. begin
  188. Name := id;
  189. BoneID := Actor1.Skeleton.BoneByName('Bip01 '+id).BoneID;
  190. Joint := j;
  191. end;
  192. Result := b;
  193. end;
  194. begin
  195. var Path: TFileName := GetCurrentAssetPath();
  196. SetCurrentDir(Path + '\modelext');
  197. //Execute Create physic and RagdollPlayer
  198. WorldODE := TWorld_ODE.create;
  199. Actor1.LoadFromFile('trinityRage.smd');
  200. Actor1.Scale.SetVector(0.2,0.2,0.2);
  201. Actor1.AddDataFromFile('walk.smd');
  202. Actor1.Animations[1].MakeSkeletalTranslationStatic;
  203. Actor1.AddDataFromFile('jump.smd');
  204. Actor1.Animations[2].MakeSkeletalTranslationStatic;
  205. RagWorld := TGLODERagdollWorld.CreateFrom(WorldODE.world, WorldODE.space, WorldODE.contactgroup);
  206. Rag := TGLODERagdoll.Create(Actor1);
  207. Rag.ODEWorld := RagWorld;
  208. Rag.GLSceneRoot := GLScene1.Objects;
  209. Rag.ShowBoundingBoxes := False;
  210. hjoint := TGLODERagdollHingeJoint.Create(AffineVectorMake(0,0,1), -0.3, 0.3);
  211. JLeg := TGLODERagdollUniversalJoint.Create(AffineVectorMake(0,1,0), -1, 1, AffineVectorMake(0,0,1), 0, 2);
  212. JTorso := TGLODERagdollUniversalJoint.Create(AffineVectorMake(0,1,0), -1, 1, AffineVectorMake(0,0,1), -1, 1);
  213. JKnee := TGLODERagdollHingeJoint.Create(AffineVectorMake(0,0,-1), -2, 0);
  214. JLArm := TGLODERagdollHingeJoint.Create(AffineVectorMake(0,1,0), -0.1, 2);
  215. JRArm := TGLODERagdollHingeJoint.Create(AffineVectorMake(0,1,0), -2, 0.1);
  216. JShoulder := TGLODERagdollUniversalJoint.Create(AffineVectorMake(0,0,1), -0.5, 0.5, AffineVectorMake(-1,0,0), -1.5, 1.5);
  217. ujoint := TGLODERagdollUniversalJoint.Create(AffineVectorMake(0,1,0), -0.5, 0.5,
  218. AffineVectorMake(0,0,-1), -0.5, 0.5);
  219. JDummy := TGLODERagdollDummyJoint.Create;
  220. rootBone := TGLODERagdollBone.Create(Rag);
  221. rootBone.Joint := hjoint;
  222. rootBone.Name := 'Spine';
  223. rootBone.BoneID := Actor1.Skeleton.BoneByName('Bip01 Spine').BoneID;
  224. Rag.SetRootBone(rootBone);
  225. tb := TGLODERagdollBone.CreateOwned(rootBone);
  226. tb.Joint := JDummy;
  227. tb.Name := '0';
  228. tb.BoneID := Actor1.Skeleton.BoneByName('Bip01').BoneID;
  229. bone(rootbone, 'Pelvis', JDummy);
  230. torso := bone(rootbone, 'Spine1', JTorso);
  231. tb := bone(torso, 'Spine2', hjoint);
  232. spine := bone(tb, 'Spine3', hjoint);
  233. HeadBone := bone(spine, 'Head', ujoint);
  234. bone(spine, 'Neck', JDummy);
  235. tb := bone(spine, 'L Arm', JShoulder);
  236. tb := bone(tb, 'L Arm1', JLArm);
  237. tb := bone(tb, 'L Arm2', hjoint);
  238. tb := bone(tb, 'L Hand', hjoint);
  239. bone(tb, 'L Finger0', JDummy);
  240. bone(tb, 'L Finger01', JDummy);
  241. bone(tb, 'L Finger02', JDummy);
  242. bone(tb, 'L Finger1', JDummy);
  243. bone(tb, 'L Finger11', JDummy);
  244. bone(tb, 'L Finger12', JDummy);
  245. tb := bone(spine, 'R Arm', JShoulder);
  246. tb := bone(tb, 'R Arm1', JRArm);
  247. tb := bone(tb, 'R Arm2', hjoint);
  248. tb := bone(tb, 'R Hand', hjoint);
  249. bone(tb, 'R Finger0', JDummy);
  250. bone(tb, 'R Finger01', JDummy);
  251. bone(tb, 'R Finger02', JDummy);
  252. bone(tb, 'R Finger1', JDummy);
  253. bone(tb, 'R Finger11', JDummy);
  254. bone(tb, 'R Finger12', JDummy);
  255. tb := bone(rootbone, 'L Leg', JLeg);
  256. tb := bone(tb, 'L Leg1', JKnee);
  257. tb := bone(tb, 'L Foot', hjoint);
  258. bone(tb, 'L Toe0', JDummy);
  259. bone(tb, 'L Toe01', JDummy);
  260. bone(tb, 'L Toe02', JDummy);
  261. tb := bone(rootbone, 'R Leg', JLeg);
  262. rightleg := bone(tb, 'R Leg1', JKnee);
  263. tb := bone(rightleg, 'R Foot', hjoint);
  264. bone(tb, 'R Toe0', JDummy);
  265. bone(tb, 'R Toe01', JDummy);
  266. bone(tb, 'R Toe02', JDummy);
  267. Rag.BuildRagdoll;
  268. WorldODE.ODEEnable := True;
  269. end;
  270. procedure TFormRagdoll.GLSceneViewer1MouseDown(Sender: TObject;
  271. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  272. begin
  273. my := y;
  274. mx := x;
  275. end;
  276. procedure TFormRagdoll.GLSceneViewer1MouseMove(Sender: TObject;
  277. Shift: TShiftState; X, Y: Integer);
  278. begin
  279. if ssleft in shift then
  280. begin
  281. GLScene1.CurrentGLCamera.MoveAroundTarget(my-y,mx-x);
  282. my := y;
  283. mx := x;
  284. end;
  285. end;
  286. procedure TFormRagdoll.GLCadencer1Progress(Sender: TObject; const deltaTime, newTime: Double);
  287. begin
  288. if WorldODE.ODEEnable then
  289. begin
  290. while WorldODE.physTime<newtime*10 do
  291. begin
  292. WorldODE.WorldUpdate;
  293. Rag.Update;
  294. end;
  295. if (Rag.Enabled) then
  296. begin
  297. if (IsKeyDown('w')) then
  298. dBodyAddForce(rightleg.Body, 0, 0, 100);
  299. if (IsKeyDown('s')) then
  300. dBodyAddForce(HeadBone.Body, 0, 0, 150);
  301. if (IsKeyDown('a')) then
  302. dBodyAddForce(HeadBone.Body, 0, 100, 0);
  303. if (IsKeyDown('d')) then
  304. dBodyAddForce(HeadBone.Body, 0, -100, 0);
  305. if (IsKeyDown('q')) then
  306. dBodyAddForce(HeadBone.Body, 100, 0, 0);
  307. if (IsKeyDown('e')) then
  308. dBodyAddForce(HeadBone.Body, -100, 0, 0);
  309. if (IsKeyDown('c')) then
  310. begin
  311. Rag.Stop;
  312. Actor1.AnimationMode := aamLoop;
  313. end;
  314. end;
  315. if (IsKeyDown('x')) then
  316. begin
  317. Rag.Start;
  318. Actor1.AnimationMode := aamNone;
  319. end;
  320. if (IsKeyDown(VK_LEFT)) then
  321. Actor1.Roll(deltaTime * -130);
  322. if (IsKeyDown(VK_RIGHT)) then
  323. Actor1.Roll(deltaTime * 130);
  324. if (IsKeyDown(VK_UP)) then
  325. Actor1.Lift(deltaTime * -20);
  326. if (IsKeyDown(VK_DOWN)) then
  327. Actor1.Lift(deltaTime * 20);
  328. end;
  329. end;
  330. procedure TFormRagdoll.FormClose(Sender: TObject; var Action: TCloseAction);
  331. begin
  332. //Execute Destroy Physic RagdollPlayer
  333. GLCadencer1.Enabled := False;
  334. WorldODE.ODEEnable := False;
  335. // NEW1
  336. Rag.Stop;
  337. rootBone.Free;
  338. hjoint.Free;
  339. JLeg.Free;
  340. JTorso.Free;
  341. JKnee.Free;
  342. JLArm.Free;
  343. JRarm.Free;
  344. JShoulder.Free;
  345. ujoint.Free;
  346. JDummy.Free;
  347. // NEW1 end.
  348. Rag.Destroy;
  349. RagWorld.Free; // NEW1
  350. WorldODE.destroy;
  351. end;
  352. procedure TFormRagdoll.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  353. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  354. begin
  355. //Mouse wheel zoom + -
  356. GLScene1.CurrentGLCamera.AdjustDistanceToTarget(Power(1.1, WheelDelta / 120));
  357. end;
  358. procedure TFormRagdoll.FormKeyUp(Sender: TObject; var Key: Word;
  359. Shift: TShiftState);
  360. const
  361. cForce = 3000;
  362. begin
  363. if (Key = VK_F1) then
  364. begin
  365. Actor1.SwitchToAnimation(0);
  366. Actor1.Position.z := 0;
  367. end;
  368. if (Key = VK_F2) then
  369. begin
  370. Actor1.SwitchToAnimation('walk');
  371. Actor1.Position.z := 7;
  372. end;
  373. if (Key = VK_F3) then
  374. begin
  375. Actor1.SwitchToAnimation('jump');
  376. Actor1.Position.z := 7;
  377. end;
  378. if (Key = VK_RETURN) then
  379. begin
  380. Randomize;
  381. if not (Rag.Enabled) then Rag.Start;
  382. dBodyAddForce(HeadBone.Body, random(cForce)-random(cForce), random(cForce)-random(cForce), random(cForce)-random(cForce)+1500);
  383. dBodyAddForce(Torso.Body, random(cForce)-random(cForce),random(cForce)-random(cForce),random(cForce)-random(cForce)+800);
  384. end;
  385. if (Key = VK_F5) then
  386. Rag.ShowBoundingBoxes := not Rag.ShowBoundingBoxes;
  387. end;
  388. end.