Advertisement
bero1985

Conservative advancement

May 28th, 2015
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 5.92 KB | None | 0 0
  1. procedure CalculateVelocity(const cA:TVector3;const qA:TQuaternion;const cB:TVector3;const qB:TQuaternion;const DeltaTime:single;var LinearVelocity,AngularVelocity:TVector3);
  2. var InverseDeltaTime,Angle:single;
  3.     Axis:TVector3;
  4.     qD,qS,qB0:TQuaternion;
  5. begin
  6.  InverseDeltaTime:=1.0/DeltaTime;
  7.  LinearVelocity:=Vector3ScalarMul(Vector3Sub(cB,cA),InverseDeltaTime);
  8.  if (abs(qA.x-qB.x)<EPSILON) and (abs(qA.y-qB.y)<EPSILON) and (abs(qA.z-qB.z)<EPSILON) and (abs(qA.w-qB.w)<EPSILON) then begin
  9.   AngularVelocity:=Vector3Origin;
  10.  end else begin
  11.   qD:=QuaternionSub(qA,qB);
  12.   qS:=QuaternionAdd(qA,qB);
  13.   if QuaternionLengthSquared(qD)<QuaternionLengthSquared(qS) then begin
  14.    qB0:=qD;
  15.   end else begin
  16.    qB0:=QuaternionNeg(qD);
  17.   end;
  18.   qD:=QuaternionMul(qB0,QuaternionInverse(qA));
  19.   QuaternionToAxisAngle(qD,Axis,Angle);
  20.   AngularVelocity:=Vector3ScalarMul(Vector3SafeNorm(Axis),Angle*InverseDeltaTime);
  21.  end;
  22. end;
  23.  
  24. // Conservative advancement
  25. function TEnginePhysics.GetTimeOfImpactForContinuousCollisionDetection(const ShapeA:TEnginePhysicsShape;const SweepA:TEnginePhysicsSweep;const ShapeB:TEnginePhysicsShape;const ShapeBTriangleIndex:longint;const SweepB:TEnginePhysicsSweep;const DeltaTime:single;const ThreadIndex:longint;var Beta:single):boolean;
  26.  function GetDistanceOfShapes(const ShapeA,ShapeB:TEnginePhysicsShape;const TransformA,TransformB:TMatrix4x4;out Normal:TVector3):single;
  27.  var GJKState:TEnginePhysicsGJKState;
  28.  begin
  29.   ClearGJKState(GJKState);
  30.   GJKState.Shapes[0]:=ShapeA;
  31.   GJKState.Shapes[1]:=ShapeB;
  32.   GJKState.Transforms[0]:=@TransformA;
  33.   GJKState.Transforms[1]:=@TransformB;
  34.   if not GJKRun(GJKState) then begin
  35.    result:=0.0;
  36.   end else begin
  37.    result:=GJKState.Distance;
  38.    Normal:=GJKState.v;
  39.   end;
  40.  end;
  41. var Tries:longint;
  42.     BoundingRadiusA,BoundingRadiusB,MaximumAngularProjectedVelocity,RelativeLinearVelocityLength,Lambda,LastLambda,Radius,
  43.     ProjectedLinearVelocity,DistanceLambda,Distance:single;
  44.     MeshShape:TEnginePhysicsShapeMesh;
  45.     MeshTriangle:PEnginePhysicsMeshTriangle;
  46.     ShapeTriangle:TEnginePhysicsShapeTriangle;
  47.     Shapes:array[0..1] of TEnginePhysicsShape;
  48.     RelativeLinearVelocity,Normal:TVector3;
  49.     LinearVelocities,AngularVelocities:array[0..1] of TVector3;
  50. begin
  51.  
  52.  result:=false;
  53.  
  54.  Shapes[0]:=ShapeA;
  55.  
  56.  if (ShapeBTriangleIndex>=0) and (ShapeB is TEnginePhysicsShapeMesh) then begin
  57.   MeshShape:=TEnginePhysicsShapeMesh(ShapeB);
  58.   ShapeTriangle:=TEnginePhysicsShapeTriangle(TriangleShapes[ThreadIndex]);
  59.   Shapes[1]:=ShapeTriangle;
  60.   MeshTriangle:=@MeshShape.Mesh.Triangles[ShapeBTriangleIndex];
  61.   ShapeTriangle.LocalTransform:=MeshShape.LocalTransform;
  62.   ShapeTriangle.WorldTransform:=MeshShape.WorldTransform;
  63.   ShapeTriangle.ConvexHull.Vertices[0].Position:=MeshShape.Mesh.Vertices[MeshTriangle^.Vertices[0]];
  64.   ShapeTriangle.ConvexHull.Vertices[1].Position:=MeshShape.Mesh.Vertices[MeshTriangle^.Vertices[1]];
  65.   ShapeTriangle.ConvexHull.Vertices[2].Position:=MeshShape.Mesh.Vertices[MeshTriangle^.Vertices[2]];
  66.   ShapeTriangle.UpdateData;
  67.  end else begin
  68.   Shapes[1]:=ShapeB;
  69.  end;
  70.  
  71.  CalculateVelocity(SweepA.c0,SweepA.q0,SweepA.c,SweepA.q,1.0,LinearVelocities[0],AngularVelocities[0]);
  72.  CalculateVelocity(SweepB.c0,SweepB.q0,SweepB.c,SweepB.q,1.0,LinearVelocities[1],AngularVelocities[1]);
  73.  
  74.  BoundingRadiusA:=Shapes[0].AngularMotionDisc;
  75.  BoundingRadiusB:=Shapes[1].AngularMotionDisc;
  76.  
  77.  MaximumAngularProjectedVelocity:=((Vector3Length(AngularVelocities[0])*BoundingRadiusA)+(Vector3Length(AngularVelocities[1])*BoundingRadiusB));
  78.  
  79.  RelativeLinearVelocity:=Vector3Sub(LinearVelocities[1],LinearVelocities[0]);
  80.  
  81.  RelativeLinearVelocityLength:=Vector3Length(RelativeLinearVelocity);
  82.  
  83.  if abs(RelativeLinearVelocityLength+MaximumAngularProjectedVelocity)<EPSILON then begin
  84.   exit;
  85.  end;
  86.  
  87.  if RelativeLinearVelocityLength<Max(EPSILON,Min(BoundingRadiusA,BoundingRadiusB)*0.25) then begin
  88.   exit;
  89.  end;
  90.  
  91.  Lambda:=0.0;
  92.  
  93.  LastLambda:=Lambda;
  94.  
  95.  Radius:=1e-4;
  96.  
  97.  Distance:=GetDistanceOfShapes(Shapes[0],
  98.                                Shapes[1],
  99.                                Matrix4x4TermMul(Shapes[0].LocalTransform,SweepTransform(SweepA,0.0)),
  100.                                Matrix4x4TermMul(Shapes[1].LocalTransform,SweepTransform(SweepB,0.0)),
  101.                                Normal);
  102.  if Distance<EPSILON then begin
  103.   exit;
  104.  end;
  105.  
  106.  ProjectedLinearVelocity:=Vector3Dot(RelativeLinearVelocity,Normal);
  107.  if (ProjectedLinearVelocity+MaximumAngularProjectedVelocity)<EPSILON then begin
  108.   exit;
  109.  end;
  110.  
  111.  Tries:=TimeOfImpactMaximumIterations;
  112.  while Radius<Distance do begin
  113.  
  114.   ProjectedLinearVelocity:=Vector3Dot(RelativeLinearVelocity,Normal);
  115.  
  116.   if (ProjectedLinearVelocity+MaximumAngularProjectedVelocity)<EPSILON then begin
  117.    break;
  118.   end;
  119.  
  120.   DistanceLambda:=Distance/(ProjectedLinearVelocity+MaximumAngularProjectedVelocity);
  121.  
  122.   Lambda:=Lambda+DistanceLambda;
  123.   if ((Lambda<0.0) or (Lambda>1.0)) or (IsSameValue(Lambda,LastLambda) or (Lambda<LastLambda)) then begin
  124.    break;
  125.   end;
  126.  
  127.   LastLambda:=Lambda;
  128.  
  129.   Distance:=GetDistanceOfShapes(Shapes[0],
  130.                                 Shapes[1],
  131.                                 Matrix4x4TermMul(Shapes[0].LocalTransform,SweepTransform(SweepA,Lambda)),
  132.                                 Matrix4x4TermMul(Shapes[1].LocalTransform,SweepTransform(SweepB,Lambda)),Normal);
  133.   if Distance<EPSILON then begin
  134.    Beta:=Lambda;
  135.    result:=true;
  136.    exit;
  137.   end;
  138.  
  139.   dec(Tries);
  140.   if Tries<=0 then begin
  141.    exit;
  142.   end;
  143.  
  144.  end;
  145.  
  146.  if (Lambda>=0.0) and (Lambda<=1.0) then begin
  147.   Distance:=GetDistanceOfShapes(Shapes[0],
  148.                                 Shapes[1],
  149.                                 Matrix4x4TermMul(Shapes[0].LocalTransform,SweepTransform(SweepA,Lambda)),
  150.                                 Matrix4x4TermMul(Shapes[1].LocalTransform,SweepTransform(SweepB,Lambda)),
  151.                                 Normal);
  152.   if Distance<EPSILON then begin
  153.    Beta:=Lambda;
  154.    result:=true;
  155.   end;
  156.  end;
  157.  
  158. end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement