GLVerletSkeletonColliders.pas 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. unit GLVerletSkeletonColliders;
  5. (* Skeleton colliders for defining and controlling verlet constraints. *)
  6. interface
  7. uses
  8. System.Classes,
  9. GLPersistentClasses,
  10. GLVectorGeometry,
  11. GLVectorFileObjects,
  12. GLVerletTypes,
  13. GLVectorTypes;
  14. type
  15. //Base verlet skeleton collider class.
  16. TSCVerletBase = class(TGLSkeletonCollider)
  17. private
  18. FVerletConstraint : TVerletConstraint;
  19. public
  20. procedure WriteToFiler(writer : TVirtualWriter); override;
  21. procedure ReadFromFiler(reader : TVirtualReader); override;
  22. procedure AddToVerletWorld(VerletWorld : TGLVerletWorld); virtual;
  23. // The verlet constraint is created through the AddToVerletWorld procedure
  24. property VerletConstraint : TVerletConstraint read FVerletConstraint;
  25. end;
  26. // Sphere shaped verlet constraint in a skeleton collider
  27. TSCVerletSphere = class(TSCVerletBase)
  28. private
  29. FRadius : Single;
  30. protected
  31. procedure SetRadius(const val : Single);
  32. public
  33. constructor Create; override;
  34. procedure WriteToFiler(writer : TVirtualWriter); override;
  35. procedure ReadFromFiler(reader : TVirtualReader); override;
  36. procedure AddToVerletWorld(VerletWorld : TGLVerletWorld); override;
  37. procedure AlignCollider; override;
  38. property Radius : Single read FRadius write SetRadius;
  39. end;
  40. // Capsule shaped verlet constraint in a skeleton collider
  41. TSCVerletCapsule = class(TSCVerletBase)
  42. private
  43. FRadius,
  44. FLength : Single;
  45. protected
  46. procedure SetRadius(const val : Single);
  47. procedure SetLength(const val : Single);
  48. public
  49. constructor Create; override;
  50. procedure WriteToFiler(writer : TVirtualWriter); override;
  51. procedure ReadFromFiler(reader : TVirtualReader); override;
  52. procedure AddToVerletWorld(VerletWorld : TGLVerletWorld); override;
  53. procedure AlignCollider; override;
  54. property Radius : Single read FRadius write SetRadius;
  55. property Length : Single read FLength write SetLength;
  56. end;
  57. (* After loading call this function to add all the constraints in a
  58. skeleton collider list to a given verlet world. *)
  59. procedure AddSCVerletConstriantsToVerletWorld(
  60. colliders : TGLSkeletonColliderList; world : TGLVerletWorld);
  61. // ------------------------------------------------------------------
  62. implementation
  63. // ------------------------------------------------------------------
  64. // ------------------
  65. // ------------------ Global methods ------------------
  66. // ------------------
  67. procedure AddSCVerletConstriantsToVerletWorld
  68. (colliders: TGLSkeletonColliderList; world: TGLVerletWorld);
  69. var
  70. i: Integer;
  71. begin
  72. for i := 0 to colliders.Count - 1 do
  73. if colliders[i] is TSCVerletBase then
  74. TSCVerletBase(colliders[i]).AddToVerletWorld(world);
  75. end;
  76. // ------------------
  77. // ------------------ TSCVerletBase ------------------
  78. // ------------------
  79. procedure TSCVerletBase.WriteToFiler(writer: TVirtualWriter);
  80. begin
  81. inherited WriteToFiler(writer);
  82. with writer do
  83. begin
  84. WriteInteger(0); // Archive Version 0
  85. end;
  86. end;
  87. procedure TSCVerletBase.ReadFromFiler(reader: TVirtualReader);
  88. var
  89. archiveVersion: Integer;
  90. begin
  91. inherited ReadFromFiler(reader);
  92. archiveVersion := reader.ReadInteger;
  93. if archiveVersion = 0 then
  94. with reader do
  95. // Nothing yet
  96. else
  97. RaiseFilerException(archiveVersion);
  98. end;
  99. procedure TSCVerletBase.AddToVerletWorld(VerletWorld: TGLVerletWorld);
  100. begin
  101. AlignCollider;
  102. end;
  103. // ------------------
  104. // ------------------ TSCVerletSphere ------------------
  105. // ------------------
  106. constructor TSCVerletSphere.Create;
  107. begin
  108. inherited;
  109. Radius := 0.5;
  110. AlignCollider;
  111. end;
  112. procedure TSCVerletSphere.WriteToFiler(writer: TVirtualWriter);
  113. begin
  114. inherited WriteToFiler(writer);
  115. with writer do
  116. begin
  117. WriteInteger(0); // Archive Version 0
  118. WriteFloat(FRadius);
  119. end;
  120. end;
  121. procedure TSCVerletSphere.ReadFromFiler(reader: TVirtualReader);
  122. var
  123. archiveVersion: Integer;
  124. begin
  125. inherited ReadFromFiler(reader);
  126. archiveVersion := reader.ReadInteger;
  127. if archiveVersion = 0 then
  128. with reader do
  129. Radius := ReadFloat
  130. else
  131. RaiseFilerException(archiveVersion);
  132. end;
  133. procedure TSCVerletSphere.AddToVerletWorld(VerletWorld: TGLVerletWorld);
  134. begin
  135. FVerletConstraint := TVCSphere.Create(VerletWorld);
  136. TVCSphere(FVerletConstraint).Radius := FRadius;
  137. inherited;
  138. end;
  139. procedure TSCVerletSphere.AlignCollider;
  140. begin
  141. inherited;
  142. if Assigned(FVerletConstraint) then
  143. TVCSphere(FVerletConstraint).Location := AffineVectorMake(GlobalMatrix.W);
  144. end;
  145. procedure TSCVerletSphere.SetRadius(const val: Single);
  146. begin
  147. if val <> FRadius then
  148. begin
  149. FRadius := val;
  150. if Assigned(FVerletConstraint) then
  151. TVCSphere(FVerletConstraint).Radius := FRadius;
  152. end;
  153. end;
  154. // ------------------
  155. // ------------------ TSCVerletCapsule ------------------
  156. // ------------------
  157. constructor TSCVerletCapsule.Create;
  158. begin
  159. inherited;
  160. Radius := 0.5;
  161. Length := 1;
  162. AlignCollider;
  163. end;
  164. procedure TSCVerletCapsule.WriteToFiler(writer : TVirtualWriter);
  165. begin
  166. inherited WriteToFiler(writer);
  167. with writer do
  168. begin
  169. WriteInteger(0); // Archive Version 0
  170. WriteFloat(FRadius);
  171. WriteFloat(FLength);
  172. end;
  173. end;
  174. procedure TSCVerletCapsule.ReadFromFiler(reader : TVirtualReader);
  175. var
  176. archiveVersion : integer;
  177. begin
  178. inherited ReadFromFiler(reader);
  179. archiveVersion:=reader.ReadInteger;
  180. if archiveVersion=0 then with reader do begin
  181. Radius:=ReadFloat;
  182. Length:=ReadFloat;
  183. end else RaiseFilerException(archiveVersion);
  184. end;
  185. procedure TSCVerletCapsule.AddToVerletWorld(VerletWorld : TGLVerletWorld);
  186. begin
  187. FVerletConstraint := TVCCapsule.Create(VerletWorld);
  188. TVCCapsule(FVerletConstraint).Radius := FRadius;
  189. TVCCapsule(FVerletConstraint).Length := FLength;
  190. inherited;
  191. end;
  192. procedure TSCVerletCapsule.AlignCollider;
  193. begin
  194. inherited;
  195. if Assigned(FVerletConstraint) then
  196. begin
  197. TVCCapsule(FVerletConstraint).Location := AffineVectorMake(GlobalMatrix.W);
  198. TVCCapsule(FVerletConstraint).Axis := AffineVectorMake(GlobalMatrix.Y);
  199. end;
  200. end;
  201. procedure TSCVerletCapsule.SetRadius(const val : Single);
  202. begin
  203. if val <> FRadius then
  204. begin
  205. FRadius := val;
  206. if Assigned(FVerletConstraint) then
  207. TVCCapsule(FVerletConstraint).Radius := FRadius;
  208. end;
  209. end;
  210. procedure TSCVerletCapsule.SetLength(const val : Single);
  211. begin
  212. if val <> FLength then
  213. begin
  214. FLength := val;
  215. if Assigned(FVerletConstraint) then
  216. TVCCapsule(FVerletConstraint).Length := FLength;
  217. end;
  218. end;
  219. // ------------------------------------------------------------------
  220. initialization
  221. // ------------------------------------------------------------------
  222. RegisterClasses([TSCVerletBase,TSCVerletSphere,TSCVerletCapsule]);
  223. end.