Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- type PEnginePhysicsGJKStateSimplexRow=^TEnginePhysicsGJKStateSimplexRow;
- TEnginePhysicsGJKStateSimplexRow=array[0..3] of TVector3;
- PEnginePhysicsGJKStateSimplices=^TEnginePhysicsGJKStateSimplices;
- TEnginePhysicsGJKStateSimplices=array[0..3] of TEnginePhysicsGJKStateSimplexRow;
- PEnginePhysicsGJKStateLambdas=^TEnginePhysicsGJKStateLambdas;
- TEnginePhysicsGJKStateLambdas=array[0..3] of single;
- PEnginePhysicsGJKStatePermutation=^TEnginePhysicsGJKStatePermutation;
- TEnginePhysicsGJKStatePermutation=array[0..3] of longint;
- PEnginePhysicsGJKStateShapes=^TEnginePhysicsGJKStateShapes;
- TEnginePhysicsGJKStateShapes=array[0..1] of TEnginePhysicsShape;
- PEnginePhysicsGJKStateTransforms=^TEnginePhysicsGJKStateTransforms;
- TEnginePhysicsGJKStateTransforms=array[0..1] of PMatrix4x4;
- PEnginePhysicsGJKState=^TEnginePhysicsGJKState;
- TEnginePhysicsGJKState=record
- v:TVector3;
- w:TVector3;
- p:TVector3;
- q:TVector3;
- Distance:single;
- Simplices:TEnginePhysicsGJKStateSimplices;
- Lambda:TEnginePhysicsGJKStateLambdas;
- Permutation:TEnginePhysicsGJKStatePermutation;
- OldPermutation:TEnginePhysicsGJKStatePermutation;
- SimplexSize:longint;
- OldSimplexSize:longint;
- Iterations:longint;
- Failed:longbool;
- Initialized:longbool;
- Shapes:TEnginePhysicsGJKStateShapes;
- Transforms:TEnginePhysicsGJKStateTransforms;
- end;
- PEnginePhysicsFeatureGJKStateSimplexRow=^TEnginePhysicsFeatureGJKStateSimplexRow;
- TEnginePhysicsFeatureGJKStateSimplexRow=array[0..3] of TVector3;
- PEnginePhysicsFeatureGJKStateSimplices=^TEnginePhysicsGJKStateSimplices;
- TEnginePhysicsFeatureGJKStateSimplices=array[0..3] of TEnginePhysicsFeatureGJKStateSimplexRow;
- PEnginePhysicsFeatureGJKStateVertexIndexSimplexRow=^TEnginePhysicsFeatureGJKStateVertexIndexSimplexRow;
- TEnginePhysicsFeatureGJKStateVertexIndexSimplexRow=array[0..1] of longint;
- PEnginePhysicsFeatureGJKStateVertexIndexSimplices=^TEnginePhysicsFeatureGJKStateVertexIndexSimplices;
- TEnginePhysicsFeatureGJKStateVertexIndexSimplices=array[0..3] of TEnginePhysicsFeatureGJKStateVertexIndexSimplexRow;
- PEnginePhysicsFeatureGJKStateLambdas=^TEnginePhysicsFeatureGJKStateLambdas;
- TEnginePhysicsFeatureGJKStateLambdas=array[0..3] of single;
- PEnginePhysicsFeatureGJKStatePermutation=^TEnginePhysicsFeatureGJKStatePermutation;
- TEnginePhysicsFeatureGJKStatePermutation=array[0..3] of longint;
- PEnginePhysicsFeatureGJKStateShapes=^TEnginePhysicsFeatureGJKStateShapes;
- TEnginePhysicsFeatureGJKStateShapes=array[0..1] of TEnginePhysicsShape;
- PEnginePhysicsFeatureGJKStateTransforms=^TEnginePhysicsFeatureGJKStateTransforms;
- TEnginePhysicsFeatureGJKStateTransforms=array[0..1] of PMatrix4x4;
- PEnginePhysicsFeatureGJKState=^TEnginePhysicsFeatureGJKState;
- TEnginePhysicsFeatureGJKState=record
- v:TVector3;
- w:TVector3;
- p:TVector3;
- q:TVector3;
- Distance:single;
- Simplices:TEnginePhysicsFeatureGJKStateSimplices;
- VertexIndexSimplices:TEnginePhysicsFeatureGJKStateVertexIndexSimplices;
- Lambda:TEnginePhysicsFeatureGJKStateLambdas;
- Permutation:TEnginePhysicsFeatureGJKStatePermutation;
- OldPermutation:TEnginePhysicsFeatureGJKStatePermutation;
- SimplexSize:longint;
- OldSimplexSize:longint;
- Iterations:longint;
- UseRadii:longbool;
- Failed:longbool;
- Initialized:longbool;
- Shapes:TEnginePhysicsFeatureGJKStateShapes;
- Transforms:TEnginePhysicsFeatureGJKStateTransforms;
- end;
- procedure ClearGJKState(var State:TEnginePhysicsGJKState);
- const EmptyGJKState:TEnginePhysicsGJKState=(
- v:(x:1.0;y:0.0;z:0.0);
- w:(x:0.0;y:0.0;z:0.0);
- p:(x:0.0;y:0.0;z:0.0);
- q:(x:0.0;y:0.0;z:0.0);
- Distance:0.0;
- Simplices:(((x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0)),
- ((x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0)),
- ((x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0)),
- ((x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0)));
- Lambda:(1.0,0.0,0.0,0.0);
- Permutation:(0,1,2,3);
- OldPermutation:(0,1,2,3);
- SimplexSize:0;
- OldSimplexSize:0;
- Iterations:0;
- Failed:false;
- Initialized:false;
- Shapes:(nil,nil);
- Transforms:(nil,nil);
- );
- begin
- State:=EmptyGJKState;
- end;
- function GJKRun(var State:TEnginePhysicsGJKState):boolean;
- function ReduceSimplex(var State:TEnginePhysicsGJKState):boolean;
- const EPSILON=1e-6;
- var t:longint;
- Row0,Row1,Row2,Row3:PEnginePhysicsGJKStateSimplexRow;
- y1,y2,y3,y4:PVector3;
- d12_1,d12_2,d12,d13_3,d23_3,d13_1,d23_2,d23,d13,d123_1,d123_2,d123_3,d123,d14_4,d24_4,d34_4,
- d14_1,d24_2,d34_3,d14,d24,d34,d124_4,d134_4,d124_2,d134_3,d234_4,d124_1,d234_3,d134_1,d234_2,
- d1234_4,d1234_3,d124,d1234_2,d134,d1234_1,d234,d1234:single;
- begin
- result:=false;
- case State.SimplexSize of
- 1:begin
- State.Lambda[State.Permutation[0]]:=1.0;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- 2:begin
- // 1 12
- // 2
- Row0:=@State.Simplices[State.Permutation[0]];
- Row1:=@State.Simplices[State.Permutation[1]];
- y1:=@Row0^[0];
- y2:=@Row1^[0];
- d12_1:=Vector3Dot(Vector3Sub(y2^,y1^),y2^);
- d12_2:=Vector3Dot(Vector3Sub(y1^,y2^),y1^);
- // y1 (no permutation needed)
- if d12_2<=0.0 then begin
- State.Lambda[State.Permutation[0]]:=1.0;
- State.SimplexSize:=1;
- result:=false;
- exit;
- end;
- //y2 (2,1)
- if d12_1<=0.0 then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- State.Lambda[State.Permutation[0]]:=1.0;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- d12:=d12_1+d12_2;
- // terminate on affinely dependent points in the set (if d12 is zero, we can never use point y2)
- if abs(d12)<=EPSILON then begin
- State.SimplexSize:=1;
- result:=false;
- exit;
- end;
- if (d12_1>0.0) and (d12_2>0.0) then begin
- //y1, y2 (no permutation)
- State.Lambda[State.Permutation[0]]:=d12_1/d12;
- State.Lambda[State.Permutation[1]]:=d12_2/d12;
- result:=true;
- exit;
- end else begin
- State.SimplexSize:=1;
- result:=false;
- exit;
- end;
- end;
- 3:begin
- // 1 12 123
- // 2 13
- // 3 23
- Row0:=@State.Simplices[State.Permutation[0]];
- Row1:=@State.Simplices[State.Permutation[1]];
- Row2:=@State.Simplices[State.Permutation[2]];
- y1:=@Row0^[0];
- y2:=@Row1^[0];
- y3:=@Row2^[0];
- //y1, (no permutation)
- d13_3:=Vector3Dot(Vector3Sub(y1^,y3^),y1^);
- d12_2:=Vector3Dot(Vector3Sub(y1^,y2^),y1^);
- if (d12_2<=0.0) and (d13_3<=0.0) then begin
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- //y2 (2,1)
- d12_1:=Vector3Dot(Vector3Sub(y2^,y1^),y2^);
- d23_3:=Vector3Dot(Vector3Sub(y2^,y3^),y2^);
- if (d12_1<=0.0) and (d23_3<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- //y3 (3,1)
- d13_1:=Vector3Dot(Vector3Sub(y3^,y1^),y3^);
- d23_2:=Vector3Dot(Vector3Sub(y3^,y2^),y3^);
- if (d23_2<=0.0) and (d13_1<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[2];
- State.Permutation[2]:=t;
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- d23:=d23_2+d23_3;
- d13:=d13_1+d13_3;
- d12:=d12_1+d12_2;
- // y2,y3 (2,1) (3,2)
- d123_1:=(d23_2*Vector3Dot(Vector3Sub(y2^,y1^),y2^))+(d23_3*Vector3Dot(Vector3Sub(y2^,y1^),y3^));
- if (d123_1<=0.0) and (d23_2>0.0) and (d23_3>0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[2];
- State.Permutation[2]:=t;
- State.Lambda[State.Permutation[0]]:=d23_2/d23;
- State.Lambda[State.Permutation[1]]:=d23_3/d23;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- //y1,y3 (3,2)
- d123_2:=(d13_1*Vector3Dot(Vector3Sub(y1^,y2^),y1^))+(d13_3*Vector3Dot(Vector3Sub(y1^,y2^),y3^));
- if (d123_2<=0.0) and (d13_1>0.0) and (d13_3>0.0) then begin
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[2];
- State.Permutation[2]:=t;
- State.Lambda[State.Permutation[0]]:=d13_1/d13;
- State.Lambda[State.Permutation[1]]:=d13_3/d13;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- //y1,y2 (no permutation)
- d123_3:=(d12_1*Vector3Dot(Vector3Sub(y1^,y3^),y1^))+(d12_2*Vector3Dot(Vector3Sub(y1^,y3^),y2^));
- if (d123_3<=0.0) and (d12_1>0.0) and (d12_2>0.0) then begin
- State.Lambda[State.Permutation[0]]:=d12_1/d12;
- State.Lambda[State.Permutation[1]]:=d12_2/d12;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- //y1, y2, y3 (no permutation)
- d123:=d123_1+d123_2+d123_3;
- if (d123_1>0.0) and (d123_2>0.0) and (d123_3>0.0) then begin
- State.Lambda[State.Permutation[0]]:=d123_1/d123;
- State.Lambda[State.Permutation[1]]:=d123_2/d123;
- State.Lambda[State.Permutation[2]]:=d123_3/d123;
- State.SimplexSize:=3;
- result:=true;
- exit;
- end else begin
- State.Lambda[State.Permutation[0]]:=d12_1/d12;
- State.Lambda[State.Permutation[1]]:=d12_2/d12;
- State.SimplexSize:=2;
- result:=false;
- exit;
- end;
- end;
- 4:begin
- // 1 12 123 1234
- // 2 13 124
- // 3 14 134
- // 4 23 234
- // 24
- // 34
- Row0:=@State.Simplices[State.Permutation[0]];
- Row1:=@State.Simplices[State.Permutation[1]];
- Row2:=@State.Simplices[State.Permutation[2]];
- Row3:=@State.Simplices[State.Permutation[3]];
- y1:=@Row0^[0];
- y2:=@Row1^[0];
- y3:=@Row2^[0];
- y4:=@Row3^[0];
- // y1 (no permutation)
- d13_3:=Vector3Dot(Vector3Sub(y1^,y3^),y1^);
- d12_2:=Vector3Dot(Vector3Sub(y1^,y2^),y1^);
- d14_4:=Vector3Dot(Vector3Sub(y1^,y4^),y1^);
- if (d12_2<=0.0) and (d13_3<=0.0) and (d14_4<=0.0) then begin
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- // y2^ (2,1)
- d12_1:=Vector3Dot(Vector3Sub(y2^,y1^),y2^);
- d23_3:=Vector3Dot(Vector3Sub(y2^,y3^),y2^);
- d24_4:=Vector3Dot(Vector3Sub(y2^,y4^),y2^);
- if (d12_1<=0.0) and (d23_3<=0.0) and (d24_4<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- // y3^ (3,1)
- d13_1:=Vector3Dot(Vector3Sub(y3^,y1^),y3^);
- d23_2:=Vector3Dot(Vector3Sub(y3^,y2^),y3^);
- d34_4:=Vector3Dot(Vector3Sub(y3^,y4^),y3^);
- if (d23_2<=0.0) and (d13_1<=0.0) and (d34_4<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[2];
- State.Permutation[2]:=t;
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- // y4^ (4,1)
- d14_1:=Vector3Dot(Vector3Sub(y4^,y1^),y4^);
- d24_2:=Vector3Dot(Vector3Sub(y4^,y2^),y4^);
- d34_3:=Vector3Dot(Vector3Sub(y4^,y3^),y4^);
- if (d14_1<=0.0) and (d24_2<=0.0) and (d34_3<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- d12:=d12_1+d12_2;
- d13:=d13_1+d13_3;
- d14:=d14_1+d14_4;
- d23:=d23_2+d23_3;
- d24:=d24_2+d24_4;
- d34:=d34_3+d34_4;
- // y1^,y2^ (no permutation)
- d123_3:=(d12_1*Vector3Dot(Vector3Sub(y1^,y3^),y1^))+(d12_2*Vector3Dot(Vector3Sub(y1^,y3^),y2^));
- d124_4:=(d12_1*Vector3Dot(Vector3Sub(y1^,y4^),y1^))+(d12_2*Vector3Dot(Vector3Sub(y1^,y4^),y2^));
- if (d12_1>0.0) and (d12_2>0.0) and (d123_3<=0.0) and (d124_4<=0.0) then begin
- State.Lambda[State.Permutation[0]]:=d12_1/d12;
- State.Lambda[State.Permutation[1]]:=d12_2/d12;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- // y1^, y3^ (3,2)
- d123_2:=(d13_1*Vector3Dot(Vector3Sub(y1^,y2^),y1^))+(d13_3*Vector3Dot(Vector3Sub(y1^,y2^),y3^));
- d134_4:=(d13_1*Vector3Dot(Vector3Sub(y1^,y4^),y1^))+(d13_3*Vector3Dot(Vector3Sub(y1^,y4^),y3^));
- if (d13_1>0.0) and (d13_3>0.0) and (d123_2<=0.0) and (d134_4<=0.0) then begin
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[2];
- State.Permutation[2]:=t;
- State.Lambda[State.Permutation[0]]:=d13_1/d13;
- State.Lambda[State.Permutation[1]]:=d13_3/d13;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- // y1^, y4^ (4,2)
- d124_2:=(d14_1*Vector3Dot(Vector3Sub(y1^,y2^),y1^))+(d14_4*Vector3Dot(Vector3Sub(y1^,y2^),y4^));
- d134_3:=(d14_1*Vector3Dot(Vector3Sub(y1^,y3^),y1^))+(d14_4*Vector3Dot(Vector3Sub(y1^,y3^),y4^));
- if (d14_1>0.0) and (d14_4>0.0) and (d124_2<=0.0) and (d134_3<=0.0) then begin
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d14_1/d14;
- State.Lambda[State.Permutation[1]]:=d14_4/d14;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- // y2^,y3^ (2,1) (3,2)
- d123_1:=(d23_2*Vector3Dot(Vector3Sub(y2^,y1^),y2^))+(d23_3*Vector3Dot(Vector3Sub(y2^,y1^),y3^));
- d234_4:=(d23_2*Vector3Dot(Vector3Sub(y2^,y4^),y2^))+(d23_3*Vector3Dot(Vector3Sub(y2^,y4^),y3^));
- if (d23_2>0.0) and (d23_3>0.0) and (d123_1<=0.0) and (d234_4<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d23_2/d23;
- State.Lambda[State.Permutation[1]]:=d23_3/d23;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- // y2^,y4^ (2,1) (4,2)
- d124_1:=(d24_2*Vector3Dot(Vector3Sub(y2^,y1^),y2^))+(d24_4*Vector3Dot(Vector3Sub(y2^,y1^),y4^));
- d234_3:=(d24_2*Vector3Dot(Vector3Sub(y2^,y3^),y2^))+(d24_4*Vector3Dot(Vector3Sub(y2^,y3^),y4^));
- if (d24_2>0.0) and (d24_4>0.0) and (d124_1<=0.0) and (d234_3<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d24_2/d24;
- State.Lambda[State.Permutation[1]]:=d24_4/d24;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- // y3^,y4^ (3,1) (2,4)
- d134_1:=(d34_3*Vector3Dot(Vector3Sub(y3^,y1^),y3^))+(d34_4*Vector3Dot(Vector3Sub(y3^,y1^),y4^));
- d234_2:=(d34_3*Vector3Dot(Vector3Sub(y3^,y2^),y3^))+(d34_4*Vector3Dot(Vector3Sub(y3^,y2^),y4^));
- if (d34_3>0.0) and (d34_4>0.0) and (d134_1<=0.0) and (d234_2<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[2];
- State.Permutation[2]:=t;
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d34_3/d34;
- State.Lambda[State.Permutation[1]]:=d34_4/d34;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- // y1^,y2^,y3^ (no permutation)
- d1234_4:=(d123_1*Vector3Dot(Vector3Sub(y1^,y4^),y1^))+(d123_2*Vector3Dot(Vector3Sub(y1^,y4^),y2^))+(d123_3*Vector3Dot(Vector3Sub(y1^,y4^),y3^));
- if (d123_1>0.0) and (d123_2>0.0) and (d123_3>0.0) and (d1234_4<=0.0) then begin
- d123:=d123_1+d123_2+d123_3;
- State.Lambda[State.Permutation[0]]:=d123_1/d123;
- State.Lambda[State.Permutation[1]]:=d123_2/d123;
- State.Lambda[State.Permutation[2]]:=d123_3/d123;
- State.SimplexSize:=3;
- result:=false;
- exit;
- end;
- // y1^,y2^,y4^ (4,3)
- d1234_3:=(d124_1*Vector3Dot(Vector3Sub(y1^,y3^),y1^))+(d124_2*Vector3Dot(Vector3Sub(y1^,y3^),y2^))+(d124_4*Vector3Dot(Vector3Sub(y1^,y3^),y4^));
- if (d124_1>0.0) and (d124_2>0.0) and (d124_4>0.0) and (d1234_3<=0.0) then begin
- d124:=d124_1+d124_2+d124_4;
- t:=State.Permutation[2];
- State.Permutation[2]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d124_1/d124;
- State.Lambda[State.Permutation[1]]:=d124_2/d124;
- State.Lambda[State.Permutation[2]]:=d124_4/d124;
- State.SimplexSize:=3;
- result:=true;
- exit;
- end;
- // y1^,y3^,y4^ (3,2) (4,3)
- d1234_2:=(d134_1*Vector3Dot(Vector3Sub(y1^,y2^),y1^))+(d134_3*Vector3Dot(Vector3Sub(y1^,y2^),y3^))+(d134_4*Vector3Dot(Vector3Sub(y1^,y2^),y4^));
- if (d134_1>0.0) and (d134_3>0.0) and (d134_4>0.0) and (d1234_2<=0.0) then begin
- d134:=d134_1+d134_3+d134_4;
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[2];
- State.Permutation[2]:=t;
- t:=State.Permutation[2];
- State.Permutation[2]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d134_1/d134;
- State.Lambda[State.Permutation[1]]:=d134_3/d134;
- State.Lambda[State.Permutation[2]]:=d134_4/d134;
- State.SimplexSize:=3;
- result:=true;
- exit;
- end;
- // y2^,y3^,y4^ (2,1)(3,2)(4,3)
- d1234_1:=(d234_2*Vector3Dot(Vector3Sub(y2^,y1^),y2^))+(d234_3*Vector3Dot(Vector3Sub(y2^,y1^),y3^))+(d234_4*Vector3Dot(Vector3Sub(y2^,y1^),y4^));
- if (d234_2>0.0) and (d234_3>0.0) and (d234_4>0.0) and (d1234_1<=0.0) then begin
- d234:=d234_2+d234_3+d234_4;
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[2];
- State.Permutation[2]:=t;
- t:=State.Permutation[2];
- State.Permutation[2]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d234_2/d234;
- State.Lambda[State.Permutation[1]]:=d234_3/d234;
- State.Lambda[State.Permutation[2]]:=d234_4/d234;
- State.SimplexSize:=3;
- result:=true;
- exit;
- end;
- // y1^,y2^,y3^,y4^ (no permutation)
- d1234:=d1234_1+d1234_2+d1234_3+d1234_4;
- if (d1234_1>0.0) and (d1234_2>0.0) and (d1234_3>0.0) and (d1234_4>0.0) then begin
- // GJK penetrating State
- // check for the accuracy, v should be the zero vector
- if Vector3Length(Vector3Add(Vector3Add(Vector3Add(Vector3ScalarMul(y1^,d1234_1/d1234),Vector3ScalarMul(y2^,d1234_2/d1234)),Vector3ScalarMul(y3^,d1234_3/d1234)),Vector3ScalarMul(y4^,d1234_4/d1234)))>1.0 then begin
- // result is bad, terminate with last good subset {y1^,y2^,y3^}
- State.SimplexSize:=3;
- result:=false;
- end else begin
- State.Lambda[State.Permutation[0]]:=d1234_1/d1234;
- State.Lambda[State.Permutation[1]]:=d1234_2/d1234;
- State.Lambda[State.Permutation[2]]:=d1234_3/d1234;
- State.Lambda[State.Permutation[3]]:=d1234_4/d1234;
- State.SimplexSize:=4;
- result:=true;
- end;
- end else begin
- // The algorithm was unable to determine the subset. return the last best known subset:
- d123:=d123_1+d123_2+d123_3;
- State.Lambda[State.Permutation[0]]:=d123_1/d123;
- State.Lambda[State.Permutation[1]]:=d123_2/d123;
- State.Lambda[State.Permutation[2]]:=d123_3/d123;
- State.SimplexSize:=3;
- result:=false;
- end;
- end;
- end;
- end;
- procedure GetSupport(const State:TEnginePhysicsGJKState;const Direction:TVector3;out svA,svB:TVector3);
- begin
- svA:=Vector3TermMatrixMul(State.Shapes[0].GetLocalFullSupport(Vector3TermMatrixMulTransposedBasis(Vector3Neg(Direction),State.Transforms[0]^)),State.Transforms[0]^);
- svB:=Vector3TermMatrixMul(State.Shapes[1].GetLocalFullSupport(Vector3TermMatrixMulTransposedBasis(Direction,State.Transforms[1]^)),State.Transforms[1]^);
- end;
- var Index,SupportVertexIndexA,SupportVertexIndexB:longint;
- Found:boolean;
- n,SupportA,SupportB:TVector3;
- Row:PEnginePhysicsFeatureGJKStateSimplexRow;
- VertexIndexRow:PEnginePhysicsFeatureGJKStateVertexIndexSimplexRow;
- begin
- if (not State.Initialized) or (Vector3LengthSquared(State.v)<GJKTolerance) then begin
- if Vector3LengthSquared(State.v)<GJKTolerance then begin
- State.v:=Vector3XAxis;
- end;
- GetSupport(State,State.v,SupportA,SupportB);
- State.v:=Vector3ScalarMul(Vector3Norm(Vector3Sub(SupportA,SupportB)),65536.0);
- end;
- State.Iterations:=0;
- State.Failed:=false;
- if State.SimplexSize>0 then begin
- for Index:=0 to State.SimplexSize-1 do begin
- Row:=@State.Simplices[State.Permutation[Index]];
- GetSupport(State,State.Simplices[Index,3],Row^[1],Row^[2]);
- Row^[0]:=Vector3Sub(Row^[1],Row^[2]);
- end;
- ReduceSimplex(State);
- State.v.x:=0.0;
- State.v.y:=0.0;
- State.v.z:=0.0;
- for Index:=0 to State.SimplexSize-1 do begin
- State.v:=Vector3Add(State.v,Vector3ScalarMul(State.Simplices[State.Permutation[Index],0],State.Lambda[State.Permutation[Index]]));
- end;
- end;
- State.OldSimplexSize:=0;
- repeat
- inc(State.Iterations);
- // store points of convex objects a and b, and A-B
- n:=Vector3Norm(State.v);
- GetSupport(State,Vector3Norm(State.v),SupportA,SupportB);
- State.w:=Vector3Sub(SupportA,SupportB);
- // main termination condition, check for duplicate support points
- Found:=false;
- for Index:=0 to State.OldSimplexSize-1 do begin
- Row:=@State.Simplices[State.OldPermutation[Index]];
- if Vector3Compare(Row^[1],SupportA) and Vector3Compare(Row^[2],SupportB) then begin
- Found:=true;
- break;
- end;
- end;
- if Found then begin
- break;
- end;
- // termination condition
- // ||v||2 -v.w is an upper bound for ||vk-v(A-B)||2 which converges towards zero as k goes large
- if (abs(Vector3LengthSquared(State.v)-abs(Vector3Dot(State.v,Vector3Norm(State.w))))<sqr(GJKTolerance)) or
- (State.Iterations>GJKMaximumIterations) or (State.simplexSize>3) then begin
- break;
- end;
- // add w to the simplices
- Row:=@State.Simplices[State.Permutation[State.SimplexSize]];
- Row^[0]:=State.w;
- Row^[1]:=SupportA;
- Row^[2]:=SupportB;
- Row^[3]:=State.v;
- inc(State.SimplexSize);
- State.OldPermutation:=State.Permutation;
- State.OldSimplexSize:=State.SimplexSize;
- if not ReduceSimplex(State) then begin
- // latest w vector was rejected, we consequently terminate (simplex cannot chance from here on)
- break;
- end;
- // Calculate the vectors v and p using lambda values
- case State.SimplexSize of
- 1:begin
- State.v:=Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]);
- end;
- 2:begin
- State.v:=Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],0],State.Lambda[State.Permutation[1]]));
- end;
- 3:begin
- State.v:=Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],0],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],0],State.Lambda[State.Permutation[2]]));
- end;
- 4:begin
- State.v:=Vector3Add(Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],0],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],0],State.Lambda[State.Permutation[2]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[3],0],State.Lambda[State.Permutation[3]]));
- end;
- else begin
- Assert(false);
- end;
- end;
- // Check for a penetrating state
- if (Vector3LengthSquared(State.v)<sqr(GJKTolerance)) or (State.SimplexSize>3) then begin
- break;
- end;
- until false;
- //writeln(State.Iterations);
- // Computing d, v, p, and q, closest points of A and B
- case State.SimplexSize of
- 1:begin
- State.v:=Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]);
- State.p:=Vector3ScalarMul(State.Simplices[State.Permutation[0],1],State.Lambda[State.Permutation[0]]);
- State.q:=Vector3ScalarMul(State.Simplices[State.Permutation[0],2],State.Lambda[State.Permutation[0]]);
- end;
- 2:begin
- State.v:=Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],0],State.Lambda[State.Permutation[1]]));
- State.p:=Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],1],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],1],State.Lambda[State.Permutation[1]]));
- State.q:=Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],2],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],2],State.Lambda[State.Permutation[1]]));
- end;
- 3:begin
- State.v:=Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],0],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],0],State.Lambda[State.Permutation[2]]));
- State.p:=Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],1],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],1],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],1],State.Lambda[State.Permutation[2]]));
- State.q:=Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],2],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],2],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],2],State.Lambda[State.Permutation[2]]));
- end;
- 4:begin
- State.v:=Vector3Add(Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],0],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],0],State.Lambda[State.Permutation[2]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[3],0],State.Lambda[State.Permutation[3]]));
- State.p:=Vector3Add(Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],1],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],1],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],1],State.Lambda[State.Permutation[2]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[3],1],State.Lambda[State.Permutation[3]]));
- State.q:=Vector3Add(Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],2],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],2],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],2],State.Lambda[State.Permutation[2]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[3],2],State.Lambda[State.Permutation[3]]));
- end;
- else begin
- State.Failed:=true;
- end;
- end;
- State.Distance:=Vector3NormalizeEx(State.v);
- // check for intersection
- if (Vector3Dist(State.p,State.q)<GJKTolerance) or ((State.SimplexSize<1) or (State.SimplexSize>3)) then begin
- State.Failed:=true;
- end;
- State.Initialized:=true;
- if State.Failed then begin
- State.Initialized:=false;
- result:=false;
- end else begin
- State.Initialized:=true;
- result:=true;
- end;
- end;
- procedure ClearFeatureGJKState(var State:TEnginePhysicsFeatureGJKState);
- const EmptyFeatureGJKState:TEnginePhysicsFeatureGJKState=(
- v:(x:1.0;y:0.0;z:0.0);
- w:(x:0.0;y:0.0;z:0.0);
- p:(x:0.0;y:0.0;z:0.0);
- q:(x:0.0;y:0.0;z:0.0);
- Distance:0.0;
- Simplices:(((x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0)),
- ((x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0)),
- ((x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0)),
- ((x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0),(x:0.0;y:0.0;z:0.0)));
- VertexIndexSimplices:((-1,-2),
- (-3,-4),
- (-5,-6),
- (-7,-8));
- Lambda:(1.0,0.0,0.0,0.0);
- Permutation:(0,1,2,3);
- OldPermutation:(0,1,2,3);
- SimplexSize:0;
- OldSimplexSize:0;
- Iterations:0;
- UseRadii:false;
- Failed:false;
- Initialized:false;
- Shapes:(nil,nil);
- Transforms:(nil,nil);
- );
- begin
- State:=EmptyFeatureGJKState;
- end;
- function FeatureGJKRun(var State:TEnginePhysicsFeatureGJKState;const ClosestDistance:PSingle=nil;const ClosestPointA:PVector3=nil;const ClosestPointB:PVector3=nil):boolean;
- function ReduceSimplex(var State:TEnginePhysicsFeatureGJKState):boolean;
- const EPSILON=1e-6;
- var t:longint;
- Row0,Row1,Row2,Row3:PEnginePhysicsFeatureGJKStateSimplexRow;
- y1,y2,y3,y4:PVector3;
- d12_1,d12_2,d12,d13_3,d23_3,d13_1,d23_2,d23,d13,d123_1,d123_2,d123_3,d123,d14_4,d24_4,d34_4,
- d14_1,d24_2,d34_3,d14,d24,d34,d124_4,d134_4,d124_2,d134_3,d234_4,d124_1,d234_3,d134_1,d234_2,
- d1234_4,d1234_3,d124,d1234_2,d134,d1234_1,d234,d1234:single;
- begin
- result:=false;
- case State.SimplexSize of
- 1:begin
- State.Lambda[State.Permutation[0]]:=1.0;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- 2:begin
- // 1 12
- // 2
- Row0:=@State.Simplices[State.Permutation[0]];
- Row1:=@State.Simplices[State.Permutation[1]];
- y1:=@Row0^[0];
- y2:=@Row1^[0];
- d12_1:=Vector3Dot(Vector3Sub(y2^,y1^),y2^);
- d12_2:=Vector3Dot(Vector3Sub(y1^,y2^),y1^);
- // y1 (no permutation needed)
- if d12_2<=0.0 then begin
- State.Lambda[State.Permutation[0]]:=1.0;
- State.SimplexSize:=1;
- result:=false;
- exit;
- end;
- //y2 (2,1)
- if d12_1<=0.0 then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- State.Lambda[State.Permutation[0]]:=1.0;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- d12:=d12_1+d12_2;
- // terminate on affinely dependent points in the set (if d12 is zero, we can never use point y2)
- if abs(d12)<=EPSILON then begin
- State.SimplexSize:=1;
- result:=false;
- exit;
- end;
- if (d12_1>0.0) and (d12_2>0.0) then begin
- //y1, y2 (no permutation)
- State.Lambda[State.Permutation[0]]:=d12_1/d12;
- State.Lambda[State.Permutation[1]]:=d12_2/d12;
- result:=true;
- exit;
- end else begin
- State.SimplexSize:=1;
- result:=false;
- exit;
- end;
- end;
- 3:begin
- // 1 12 123
- // 2 13
- // 3 23
- Row0:=@State.Simplices[State.Permutation[0]];
- Row1:=@State.Simplices[State.Permutation[1]];
- Row2:=@State.Simplices[State.Permutation[2]];
- y1:=@Row0^[0];
- y2:=@Row1^[0];
- y3:=@Row2^[0];
- //y1, (no permutation)
- d13_3:=Vector3Dot(Vector3Sub(y1^,y3^),y1^);
- d12_2:=Vector3Dot(Vector3Sub(y1^,y2^),y1^);
- if (d12_2<=0.0) and (d13_3<=0.0) then begin
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- //y2 (2,1)
- d12_1:=Vector3Dot(Vector3Sub(y2^,y1^),y2^);
- d23_3:=Vector3Dot(Vector3Sub(y2^,y3^),y2^);
- if (d12_1<=0.0) and (d23_3<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- //y3 (3,1)
- d13_1:=Vector3Dot(Vector3Sub(y3^,y1^),y3^);
- d23_2:=Vector3Dot(Vector3Sub(y3^,y2^),y3^);
- if (d23_2<=0.0) and (d13_1<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[2];
- State.Permutation[2]:=t;
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- d23:=d23_2+d23_3;
- d13:=d13_1+d13_3;
- d12:=d12_1+d12_2;
- // y2,y3 (2,1) (3,2)
- d123_1:=(d23_2*Vector3Dot(Vector3Sub(y2^,y1^),y2^))+(d23_3*Vector3Dot(Vector3Sub(y2^,y1^),y3^));
- if (d123_1<=0.0) and (d23_2>0.0) and (d23_3>0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[2];
- State.Permutation[2]:=t;
- State.Lambda[State.Permutation[0]]:=d23_2/d23;
- State.Lambda[State.Permutation[1]]:=d23_3/d23;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- //y1,y3 (3,2)
- d123_2:=(d13_1*Vector3Dot(Vector3Sub(y1^,y2^),y1^))+(d13_3*Vector3Dot(Vector3Sub(y1^,y2^),y3^));
- if (d123_2<=0.0) and (d13_1>0.0) and (d13_3>0.0) then begin
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[2];
- State.Permutation[2]:=t;
- State.Lambda[State.Permutation[0]]:=d13_1/d13;
- State.Lambda[State.Permutation[1]]:=d13_3/d13;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- //y1,y2 (no permutation)
- d123_3:=(d12_1*Vector3Dot(Vector3Sub(y1^,y3^),y1^))+(d12_2*Vector3Dot(Vector3Sub(y1^,y3^),y2^));
- if (d123_3<=0.0) and (d12_1>0.0) and (d12_2>0.0) then begin
- State.Lambda[State.Permutation[0]]:=d12_1/d12;
- State.Lambda[State.Permutation[1]]:=d12_2/d12;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- //y1, y2, y3 (no permutation)
- d123:=d123_1+d123_2+d123_3;
- if (d123_1>0.0) and (d123_2>0.0) and (d123_3>0.0) then begin
- State.Lambda[State.Permutation[0]]:=d123_1/d123;
- State.Lambda[State.Permutation[1]]:=d123_2/d123;
- State.Lambda[State.Permutation[2]]:=d123_3/d123;
- State.SimplexSize:=3;
- result:=true;
- exit;
- end else begin
- State.Lambda[State.Permutation[0]]:=d12_1/d12;
- State.Lambda[State.Permutation[1]]:=d12_2/d12;
- State.SimplexSize:=2;
- result:=false;
- exit;
- end;
- end;
- 4:begin
- // 1 12 123 1234
- // 2 13 124
- // 3 14 134
- // 4 23 234
- // 24
- // 34
- Row0:=@State.Simplices[State.Permutation[0]];
- Row1:=@State.Simplices[State.Permutation[1]];
- Row2:=@State.Simplices[State.Permutation[2]];
- Row3:=@State.Simplices[State.Permutation[3]];
- y1:=@Row0^[0];
- y2:=@Row1^[0];
- y3:=@Row2^[0];
- y4:=@Row3^[0];
- // y1 (no permutation)
- d13_3:=Vector3Dot(Vector3Sub(y1^,y3^),y1^);
- d12_2:=Vector3Dot(Vector3Sub(y1^,y2^),y1^);
- d14_4:=Vector3Dot(Vector3Sub(y1^,y4^),y1^);
- if (d12_2<=0.0) and (d13_3<=0.0) and (d14_4<=0.0) then begin
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- // y2^ (2,1)
- d12_1:=Vector3Dot(Vector3Sub(y2^,y1^),y2^);
- d23_3:=Vector3Dot(Vector3Sub(y2^,y3^),y2^);
- d24_4:=Vector3Dot(Vector3Sub(y2^,y4^),y2^);
- if (d12_1<=0.0) and (d23_3<=0.0) and (d24_4<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- // y3^ (3,1)
- d13_1:=Vector3Dot(Vector3Sub(y3^,y1^),y3^);
- d23_2:=Vector3Dot(Vector3Sub(y3^,y2^),y3^);
- d34_4:=Vector3Dot(Vector3Sub(y3^,y4^),y3^);
- if (d23_2<=0.0) and (d13_1<=0.0) and (d34_4<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[2];
- State.Permutation[2]:=t;
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- // y4^ (4,1)
- d14_1:=Vector3Dot(Vector3Sub(y4^,y1^),y4^);
- d24_2:=Vector3Dot(Vector3Sub(y4^,y2^),y4^);
- d34_3:=Vector3Dot(Vector3Sub(y4^,y3^),y4^);
- if (d14_1<=0.0) and (d24_2<=0.0) and (d34_3<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=1;
- State.SimplexSize:=1;
- result:=true;
- exit;
- end;
- d12:=d12_1+d12_2;
- d13:=d13_1+d13_3;
- d14:=d14_1+d14_4;
- d23:=d23_2+d23_3;
- d24:=d24_2+d24_4;
- d34:=d34_3+d34_4;
- // y1^,y2^ (no permutation)
- d123_3:=(d12_1*Vector3Dot(Vector3Sub(y1^,y3^),y1^))+(d12_2*Vector3Dot(Vector3Sub(y1^,y3^),y2^));
- d124_4:=(d12_1*Vector3Dot(Vector3Sub(y1^,y4^),y1^))+(d12_2*Vector3Dot(Vector3Sub(y1^,y4^),y2^));
- if (d12_1>0.0) and (d12_2>0.0) and (d123_3<=0.0) and (d124_4<=0.0) then begin
- State.Lambda[State.Permutation[0]]:=d12_1/d12;
- State.Lambda[State.Permutation[1]]:=d12_2/d12;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- // y1^, y3^ (3,2)
- d123_2:=(d13_1*Vector3Dot(Vector3Sub(y1^,y2^),y1^))+(d13_3*Vector3Dot(Vector3Sub(y1^,y2^),y3^));
- d134_4:=(d13_1*Vector3Dot(Vector3Sub(y1^,y4^),y1^))+(d13_3*Vector3Dot(Vector3Sub(y1^,y4^),y3^));
- if (d13_1>0.0) and (d13_3>0.0) and (d123_2<=0.0) and (d134_4<=0.0) then begin
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[2];
- State.Permutation[2]:=t;
- State.Lambda[State.Permutation[0]]:=d13_1/d13;
- State.Lambda[State.Permutation[1]]:=d13_3/d13;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- // y1^, y4^ (4,2)
- d124_2:=(d14_1*Vector3Dot(Vector3Sub(y1^,y2^),y1^))+(d14_4*Vector3Dot(Vector3Sub(y1^,y2^),y4^));
- d134_3:=(d14_1*Vector3Dot(Vector3Sub(y1^,y3^),y1^))+(d14_4*Vector3Dot(Vector3Sub(y1^,y3^),y4^));
- if (d14_1>0.0) and (d14_4>0.0) and (d124_2<=0.0) and (d134_3<=0.0) then begin
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d14_1/d14;
- State.Lambda[State.Permutation[1]]:=d14_4/d14;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- // y2^,y3^ (2,1) (3,2)
- d123_1:=(d23_2*Vector3Dot(Vector3Sub(y2^,y1^),y2^))+(d23_3*Vector3Dot(Vector3Sub(y2^,y1^),y3^));
- d234_4:=(d23_2*Vector3Dot(Vector3Sub(y2^,y4^),y2^))+(d23_3*Vector3Dot(Vector3Sub(y2^,y4^),y3^));
- if (d23_2>0.0) and (d23_3>0.0) and (d123_1<=0.0) and (d234_4<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d23_2/d23;
- State.Lambda[State.Permutation[1]]:=d23_3/d23;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- // y2^,y4^ (2,1) (4,2)
- d124_1:=(d24_2*Vector3Dot(Vector3Sub(y2^,y1^),y2^))+(d24_4*Vector3Dot(Vector3Sub(y2^,y1^),y4^));
- d234_3:=(d24_2*Vector3Dot(Vector3Sub(y2^,y3^),y2^))+(d24_4*Vector3Dot(Vector3Sub(y2^,y3^),y4^));
- if (d24_2>0.0) and (d24_4>0.0) and (d124_1<=0.0) and (d234_3<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d24_2/d24;
- State.Lambda[State.Permutation[1]]:=d24_4/d24;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- // y3^,y4^ (3,1) (2,4)
- d134_1:=(d34_3*Vector3Dot(Vector3Sub(y3^,y1^),y3^))+(d34_4*Vector3Dot(Vector3Sub(y3^,y1^),y4^));
- d234_2:=(d34_3*Vector3Dot(Vector3Sub(y3^,y2^),y3^))+(d34_4*Vector3Dot(Vector3Sub(y3^,y2^),y4^));
- if (d34_3>0.0) and (d34_4>0.0) and (d134_1<=0.0) and (d234_2<=0.0) then begin
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[2];
- State.Permutation[2]:=t;
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d34_3/d34;
- State.Lambda[State.Permutation[1]]:=d34_4/d34;
- State.SimplexSize:=2;
- result:=true;
- exit;
- end;
- // y1^,y2^,y3^ (no permutation)
- d1234_4:=(d123_1*Vector3Dot(Vector3Sub(y1^,y4^),y1^))+(d123_2*Vector3Dot(Vector3Sub(y1^,y4^),y2^))+(d123_3*Vector3Dot(Vector3Sub(y1^,y4^),y3^));
- if (d123_1>0.0) and (d123_2>0.0) and (d123_3>0.0) and (d1234_4<=0.0) then begin
- d123:=d123_1+d123_2+d123_3;
- State.Lambda[State.Permutation[0]]:=d123_1/d123;
- State.Lambda[State.Permutation[1]]:=d123_2/d123;
- State.Lambda[State.Permutation[2]]:=d123_3/d123;
- State.SimplexSize:=3;
- result:=false;
- exit;
- end;
- // y1^,y2^,y4^ (4,3)
- d1234_3:=(d124_1*Vector3Dot(Vector3Sub(y1^,y3^),y1^))+(d124_2*Vector3Dot(Vector3Sub(y1^,y3^),y2^))+(d124_4*Vector3Dot(Vector3Sub(y1^,y3^),y4^));
- if (d124_1>0.0) and (d124_2>0.0) and (d124_4>0.0) and (d1234_3<=0.0) then begin
- d124:=d124_1+d124_2+d124_4;
- t:=State.Permutation[2];
- State.Permutation[2]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d124_1/d124;
- State.Lambda[State.Permutation[1]]:=d124_2/d124;
- State.Lambda[State.Permutation[2]]:=d124_4/d124;
- State.SimplexSize:=3;
- result:=true;
- exit;
- end;
- // y1^,y3^,y4^ (3,2) (4,3)
- d1234_2:=(d134_1*Vector3Dot(Vector3Sub(y1^,y2^),y1^))+(d134_3*Vector3Dot(Vector3Sub(y1^,y2^),y3^))+(d134_4*Vector3Dot(Vector3Sub(y1^,y2^),y4^));
- if (d134_1>0.0) and (d134_3>0.0) and (d134_4>0.0) and (d1234_2<=0.0) then begin
- d134:=d134_1+d134_3+d134_4;
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[2];
- State.Permutation[2]:=t;
- t:=State.Permutation[2];
- State.Permutation[2]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d134_1/d134;
- State.Lambda[State.Permutation[1]]:=d134_3/d134;
- State.Lambda[State.Permutation[2]]:=d134_4/d134;
- State.SimplexSize:=3;
- result:=true;
- exit;
- end;
- // y2^,y3^,y4^ (2,1)(3,2)(4,3)
- d1234_1:=(d234_2*Vector3Dot(Vector3Sub(y2^,y1^),y2^))+(d234_3*Vector3Dot(Vector3Sub(y2^,y1^),y3^))+(d234_4*Vector3Dot(Vector3Sub(y2^,y1^),y4^));
- if (d234_2>0.0) and (d234_3>0.0) and (d234_4>0.0) and (d1234_1<=0.0) then begin
- d234:=d234_2+d234_3+d234_4;
- t:=State.Permutation[0];
- State.Permutation[0]:=State.Permutation[1];
- State.Permutation[1]:=t;
- t:=State.Permutation[1];
- State.Permutation[1]:=State.Permutation[2];
- State.Permutation[2]:=t;
- t:=State.Permutation[2];
- State.Permutation[2]:=State.Permutation[3];
- State.Permutation[3]:=t;
- State.Lambda[State.Permutation[0]]:=d234_2/d234;
- State.Lambda[State.Permutation[1]]:=d234_3/d234;
- State.Lambda[State.Permutation[2]]:=d234_4/d234;
- State.SimplexSize:=3;
- result:=true;
- exit;
- end;
- // y1^,y2^,y3^,y4^ (no permutation)
- d1234:=d1234_1+d1234_2+d1234_3+d1234_4;
- if (d1234_1>0.0) and (d1234_2>0.0) and (d1234_3>0.0) and (d1234_4>0.0) then begin
- // FeatureGJK penetrating State
- // check for the accuracy, v should be the zero vector
- if Vector3Length(Vector3Add(Vector3Add(Vector3Add(Vector3ScalarMul(y1^,d1234_1/d1234),Vector3ScalarMul(y2^,d1234_2/d1234)),Vector3ScalarMul(y3^,d1234_3/d1234)),Vector3ScalarMul(y4^,d1234_4/d1234)))>1.0 then begin
- // result is bad, terminate with last good subset {y1^,y2^,y3^}
- State.SimplexSize:=3;
- result:=false;
- end else begin
- State.Lambda[State.Permutation[0]]:=d1234_1/d1234;
- State.Lambda[State.Permutation[1]]:=d1234_2/d1234;
- State.Lambda[State.Permutation[2]]:=d1234_3/d1234;
- State.Lambda[State.Permutation[3]]:=d1234_4/d1234;
- State.SimplexSize:=4;
- result:=true;
- end;
- end else begin
- // The algorithm was unable to determine the subset. return the last best known subset:
- d123:=d123_1+d123_2+d123_3;
- State.Lambda[State.Permutation[0]]:=d123_1/d123;
- State.Lambda[State.Permutation[1]]:=d123_2/d123;
- State.Lambda[State.Permutation[2]]:=d123_3/d123;
- State.SimplexSize:=3;
- result:=false;
- end;
- end;
- end;
- end;
- procedure GetSupport(const State:TEnginePhysicsFeatureGJKState;const Direction:TVector3;out svA,svB:TVector3;out siA,siB:longint);
- begin
- siA:=State.Shapes[0].GetLocalFeatureSupportIndex(Vector3TermMatrixMulTransposedBasis(Vector3Neg(Direction),State.Transforms[0]^));
- siB:=State.Shapes[1].GetLocalFeatureSupportIndex(Vector3TermMatrixMulTransposedBasis(Direction,State.Transforms[1]^));
- svA:=Vector3TermMatrixMul(State.Shapes[0].GetLocalFeatureSupportVertex(siA),State.Transforms[0]^);
- svB:=Vector3TermMatrixMul(State.Shapes[1].GetLocalFeatureSupportVertex(siB),State.Transforms[1]^);
- end;
- var Index,SupportVertexIndexA,SupportVertexIndexB:longint;
- Found:boolean;
- n,SupportVertexVectorA,SupportVertexVectorB:TVector3;
- Row:PEnginePhysicsFeatureGJKStateSimplexRow;
- VertexIndexRow:PEnginePhysicsFeatureGJKStateVertexIndexSimplexRow;
- begin
- if (not State.Initialized) or (Vector3LengthSquared(State.v)<GJKTolerance) then begin
- if Vector3LengthSquared(State.v)<GJKTolerance then begin
- State.v:=Vector3XAxis;
- end;
- GetSupport(State,State.v,SupportVertexVectorA,SupportVertexVectorB,SupportVertexIndexA,SupportVertexIndexB);
- State.v:=Vector3ScalarMul(Vector3Norm(Vector3Sub(SupportVertexVectorA,SupportVertexVectorB)),65536.0);
- end;
- State.Iterations:=0;
- State.Failed:=false;
- if State.SimplexSize>0 then begin
- for Index:=0 to State.SimplexSize-1 do begin
- Row:=@State.Simplices[State.Permutation[Index]];
- VertexIndexRow:=@State.VertexIndexSimplices[State.Permutation[Index]];
- GetSupport(State,State.Simplices[Index,3],Row^[1],Row^[2],VertexIndexRow^[0],VertexIndexRow^[1]);
- Row^[0]:=Vector3Sub(Row^[1],Row^[2]);
- end;
- ReduceSimplex(State);
- State.v.x:=0.0;
- State.v.y:=0.0;
- State.v.z:=0.0;
- for Index:=0 to State.SimplexSize-1 do begin
- State.v:=Vector3Add(State.v,Vector3ScalarMul(State.Simplices[State.Permutation[Index],0],State.Lambda[State.Permutation[Index]]));
- end;
- end;
- State.OldSimplexSize:=0;
- repeat
- inc(State.Iterations);
- // store points of convex objects a and b, and A-B
- GetSupport(State,Vector3Norm(State.v),SupportVertexVectorA,SupportVertexVectorB,SupportVertexIndexA,SupportVertexIndexB);
- State.w:=Vector3Sub(SupportVertexVectorA,SupportVertexVectorB);
- // main termination condition, check for duplicate support points
- Found:=false;
- for Index:=0 to State.OldSimplexSize-1 do begin
- VertexIndexRow:=@State.VertexIndexSimplices[State.Permutation[Index]];
- if (VertexIndexRow^[0]=SupportVertexIndexA) and (VertexIndexRow^[1]=SupportVertexIndexB) then begin
- Found:=true;
- break;
- end;
- end;
- if Found then begin
- break;
- end;
- // termination condition
- // ||v||2 -v.w is an upper bound for ||vk-v(A-B)||2 which converges towards zero as k goes large
- if (abs(Vector3LengthSquared(State.v)-abs(Vector3Dot(State.v,Vector3Norm(State.w))))<sqr(GJKTolerance)) or
- (State.Iterations>GJKMaximumIterations) or (State.SimplexSize>3) then begin
- break;
- end;
- // add w to the simplices
- Row:=@State.Simplices[State.Permutation[State.SimplexSize]];
- Row^[0]:=State.w;
- Row^[1]:=SupportVertexVectorA;
- Row^[2]:=SupportVertexVectorB;
- Row^[3]:=State.v;
- VertexIndexRow:=@State.VertexIndexSimplices[State.Permutation[State.SimplexSize]];
- VertexIndexRow^[0]:=SupportVertexIndexA;
- VertexIndexRow^[1]:=SupportVertexIndexB;
- inc(State.SimplexSize);
- State.OldPermutation:=State.Permutation;
- State.OldSimplexSize:=State.SimplexSize;
- if not ReduceSimplex(State) then begin
- // latest w vector was rejected, we consequently terminate (simplex cannot chance from here on)
- State.Failed:=true;
- break;
- end;
- // Calculate the vectors v and p using lambda values
- case State.SimplexSize of
- 1:begin
- State.v:=Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]);
- end;
- 2:begin
- State.v:=Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],0],State.Lambda[State.Permutation[1]]));
- end;
- 3:begin
- State.v:=Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],0],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],0],State.Lambda[State.Permutation[2]]));
- end;
- 4:begin
- State.v:=Vector3Add(Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],0],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],0],State.Lambda[State.Permutation[2]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[3],0],State.Lambda[State.Permutation[3]]));
- end;
- else begin
- Assert(false);
- end;
- end;
- // Check for a penetrating state
- if (Vector3LengthSquared(State.v)<sqr(GJKTolerance)) or (State.SimplexSize>3) then begin
- break;
- end;
- until false;
- // Computing d, v, p, and q, closest points of A and B
- case State.SimplexSize of
- 1:begin
- State.v:=Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]);
- State.p:=Vector3ScalarMul(State.Simplices[State.Permutation[0],1],State.Lambda[State.Permutation[0]]);
- State.q:=Vector3ScalarMul(State.Simplices[State.Permutation[0],2],State.Lambda[State.Permutation[0]]);
- end;
- 2:begin
- State.v:=Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],0],State.Lambda[State.Permutation[1]]));
- State.p:=Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],1],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],1],State.Lambda[State.Permutation[1]]));
- State.q:=Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],2],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],2],State.Lambda[State.Permutation[1]]));
- end;
- 3:begin
- State.v:=Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],0],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],0],State.Lambda[State.Permutation[2]]));
- State.p:=Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],1],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],1],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],1],State.Lambda[State.Permutation[2]]));
- State.q:=Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],2],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],2],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],2],State.Lambda[State.Permutation[2]]));
- end;
- 4:begin
- State.v:=Vector3Add(Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],0],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],0],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],0],State.Lambda[State.Permutation[2]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[3],0],State.Lambda[State.Permutation[3]]));
- State.p:=Vector3Add(Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],1],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],1],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],1],State.Lambda[State.Permutation[2]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[3],1],State.Lambda[State.Permutation[3]]));
- State.q:=Vector3Add(Vector3Add(Vector3Add(Vector3ScalarMul(State.Simplices[State.Permutation[0],2],State.Lambda[State.Permutation[0]]),
- Vector3ScalarMul(State.Simplices[State.Permutation[1],2],State.Lambda[State.Permutation[1]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[2],2],State.Lambda[State.Permutation[2]])),
- Vector3ScalarMul(State.Simplices[State.Permutation[3],2],State.Lambda[State.Permutation[3]]));
- end;
- else begin
- State.Failed:=true;
- end;
- end;
- State.Distance:=Vector3NormalizeEx(State.v);
- // check for intersection
- if (Vector3Dist(State.p,State.q)<GJKTolerance) or ((State.SimplexSize<1) or (State.SimplexSize>3)) then begin
- State.Failed:=true;
- end;
- if State.UseRadii then begin
- if (State.Distance>(State.Shapes[0].FeatureRadius+State.Shapes[1].FeatureRadius)) and (State.Distance>EPSILON) then begin
- if assigned(ClosestDistance) then begin
- ClosestDistance^:=State.Distance-(State.Shapes[0].FeatureRadius+State.Shapes[1].FeatureRadius);
- end;
- if assigned(ClosestPointA) then begin
- ClosestPointA^:=Vector3Add(State.p,Vector3ScalarMul(State.v,State.Shapes[0].FeatureRadius));
- end;
- if assigned(ClosestPointB) then begin
- ClosestPointB^:=Vector3Sub(State.q,Vector3ScalarMul(State.v,State.Shapes[1].FeatureRadius));
- end;
- end else begin
- if assigned(ClosestDistance) then begin
- ClosestDistance^:=0.0;
- end;
- if assigned(ClosestPointA) then begin
- ClosestPointA^:=Vector3Avg(State.p,State.q);
- end;
- if assigned(ClosestPointB) then begin
- ClosestPointB^:=Vector3Avg(State.p,State.q);
- end;
- end;
- end else begin
- if assigned(ClosestDistance) then begin
- ClosestDistance^:=State.Distance;
- end;
- if assigned(ClosestPointA) then begin
- ClosestPointA^:=State.p;
- end;
- if assigned(ClosestPointB) then begin
- ClosestPointB^:=State.q;
- end;
- end;
- if State.Failed then begin
- State.Initialized:=false;
- result:=false;
- end else begin
- State.Initialized:=true;
- result:=true;
- end;
- end;
Advertisement
Add Comment
Please, Sign In to add comment