44
55# Collision detection algorithm based on the MPR algorithm
66
7- mutable struct SupportPoint
8- p:: SVector{3,Float64 } # support point
9- n:: SVector{3,Float64 } # support normal unit vector
10- a:: SVector{3,Float64 } # point on shapeA
11- b:: SVector{3,Float64 } # point on shapeB
12- function SupportPoint (p:: SVector{3,Float64 } ,n:: SVector{3,Float64 } ,a:: SVector{3,Float64 } ,b:: SVector{3,Float64} )
7+ mutable struct SupportPoint{T}
8+ p:: SVector{3,T } # support point
9+ n:: SVector{3,T } # support normal unit vector
10+ a:: SVector{3,T } # point on shapeA
11+ b:: SVector{3,T } # point on shapeB
12+ function SupportPoint {T} (p:: SVector{3,T } ,n:: SVector{3,T } ,a:: SVector{3,T } ,b:: SVector{3,T} ) where {T}
1313 new (p,n,a,b)
1414 end
1515end
1616
1717
18- function getSupportPoint (shapeA:: Modia3D.Composition.Object3D , shapeB:: Composition.Object3D , n:: SVector{3,Float64 } ; scale:: Float64 = 1.0 )
18+ function getSupportPoint (shapeA:: Modia3D.Composition.Object3D , shapeB:: Composition.Object3D , n:: SVector{3,T } ; scale:: T = T ( 1.0 )) where {T}
1919 a = Modia3D. supportPoint (shapeA, n)
2020 b = Modia3D. supportPoint (shapeB, - n)
21- return SupportPoint ((a- b). * scale,n,a,b)
21+ return SupportPoint {T} ((a- b). * scale,n,a,b)
2222end
2323
2424
6060
6161
6262# ########## Phase 1, Minkowski Portal Refinement ###################
63- @inline getCentroid (obj:: Composition.Object3D ) = (obj. r_abs + obj. R_abs' * obj. centroid)
63+ @inline getCentroid (obj:: Composition.Object3D ) = SVector {3,Modia3D.MPRFloatType} (obj. r_abs + obj. R_abs' * obj. centroid)
6464
6565
6666# checks if centers of shapeA and shapeB are overlapping
6767# belongs to construction of r0
68- function checkCentersOfShapesOverlapp (r0:: SupportPoint , neps:: Float64 , shapeA:: Composition.Object3D , shapeB:: Composition.Object3D )
68+ function checkCentersOfShapesOverlapp (r0:: SupportPoint , neps:: T , shapeA:: Composition.Object3D , shapeB:: Composition.Object3D ) where {T}
6969 if norm (r0. p) <= neps
7070 error (" MPR: Too large penetration (prerequisite of MPR violated). Centers are overlapping. Look at $(Modia3D. fullName (shapeA)) and $(Modia3D. fullName (shapeB)) ." )
7171 end
7272end
7373
7474
75- function checkIfShapesArePlanar (r0:: SupportPoint ,r1:: SupportPoint ,r2:: SupportPoint ,n2:: SVector{3,Float64 } , neps:: Float64 ,
76- shapeA:: Composition.Object3D ,shapeB:: Composition.Object3D )
75+ function checkIfShapesArePlanar (r0:: SupportPoint ,r1:: SupportPoint ,r2:: SupportPoint ,n2:: SVector{3,T } , neps:: T ,
76+ shapeA:: Composition.Object3D ,shapeB:: Composition.Object3D ) where {T}
7777 # r3 is in the direction of plane normal that contains triangle r0-r1-r2
7878 n3 = cross (r1. p- r0. p, r2. p- r0. p)
7979 # the triangle r0-r1-r2 has degenerated into a line segment
@@ -120,12 +120,12 @@ end
120120# Der Ursprung muss nicht enthalten sein!!!
121121function tetrahedronEncloseOrigin (r0:: SupportPoint , r1:: SupportPoint ,
122122 r2:: SupportPoint , r3:: SupportPoint ,
123- neps:: Float64 , niter_max:: Int64 ,
124- shapeA:: Composition.Object3D , shapeB:: Composition.Object3D , scale:: Float64 )
123+ neps:: T , niter_max:: Int64 ,
124+ shapeA:: Composition.Object3D , shapeB:: Composition.Object3D , scale:: T ) where {T}
125125 r1org = r1
126126 r2org = r2
127127 r3org = r3
128- aux = Modia3D. ZeroVector3D
128+ aux = SVector {3, T} ( Modia3D. ZeroVector3D)
129129 success = false
130130 for i in 1 : niter_max
131131 aux = cross (r1. p- r0. p,r3. p- r0. p)
158158# ########## Phase 3, Minkowski Portal Refinement ###################
159159# construction of r4
160160function constructR4 (r0:: SupportPoint ,r1:: SupportPoint ,r2:: SupportPoint ,r3:: SupportPoint ,
161- neps:: Float64 , shapeA:: Composition.Object3D ,shapeB:: Composition.Object3D , scale:: Float64 )
161+ neps:: T , shapeA:: Composition.Object3D ,shapeB:: Composition.Object3D , scale:: T ) where {T}
162162 n4 = cross (r2. p- r1. p, r3. p- r1. p)
163163 if norm (n4) <= neps
164164 r3 = getSupportPoint (shapeA, shapeB, - r3. n, scale= scale) # change search direction
@@ -244,11 +244,11 @@ function finalTC3(r0::SupportPoint, r1::SupportPoint, r2::SupportPoint, r3::Supp
244244end
245245
246246
247- function phase3 (r0:: SupportPoint , r1:: SupportPoint , r2:: SupportPoint , r3:: SupportPoint , neps:: Float64 , niter_max:: Int64 ,tol_rel:: Float64 , shapeA:: Composition.Object3D ,shapeB:: Composition.Object3D , scale:: Float64 )
247+ function phase3 (r0:: SupportPoint , r1:: SupportPoint , r2:: SupportPoint , r3:: SupportPoint , neps:: T , niter_max:: Int64 , tol_rel:: T , shapeA:: Composition.Object3D , shapeB:: Composition.Object3D , scale:: T ) where {T}
248248 r1org = r1
249249 r2org = r2
250250 r3org = r3
251- new_tol = 42.0
251+ new_tol = T ( 42.0 )
252252 isTC2 = false
253253 isTC3 = false
254254 r1_new:: SupportPoint = r0
@@ -269,12 +269,12 @@ function phase3(r0::SupportPoint, r1::SupportPoint, r2::SupportPoint, r3::Suppor
269269 # # TERMINATION CONDITION 2 ##
270270 if TC2 < tol_rel
271271 (distance,r1,r2,r3,r4) = finalTC2 (r1,r2,r3,r4)
272- return ( distance, r4 . a, r4 . b, r4 . n, true , r1 . a, r1 . b, r2 . a, r2 . b, r3 . a, r3 . b)
272+ return distance, r1, r2, r3, r4
273273
274274 # # TERMINATION CONDITION 3 ##
275275 elseif TC3 < tol_rel
276276 (distance,r1,r2,r3,r4) = finalTC3 (r0, r1, r2, r3, r4)
277- return ( distance, r4 . a, r4 . b, r4 . n, true , r1 . a, r1 . b, r2 . a, r2 . b, r3 . a, r3 . b)
277+ return distance, r1, r2, r3, r4
278278 else
279279 if TC2 < new_tol
280280 new_tol = TC2
@@ -304,11 +304,11 @@ function phase3(r0::SupportPoint, r1::SupportPoint, r2::SupportPoint, r3::Suppor
304304 @warn (" MPR (phase 3): Numerical issues with distance computation between $(Modia3D. fullName (shapeA)) and $(Modia3D. fullName (shapeB)) . tol_rel increased locally for this computation to $new_tol ." )
305305 if isTC2
306306 (distance,r1,r2,r3,r4) = finalTC2 (r1_new,r2_new,r3_new,r4_new)
307- return ( distance, r4 . a, r4 . b, r4 . n, true , r1 . a, r1 . b, r2 . a, r2 . b, r3 . a, r3 . b)
307+ return distance, r1, r2, r3, r4
308308 end
309309 if isTC3
310310 (distance,r1,r2,r3,r4) = finalTC3 (r0, r1_new, r2_new, r3_new, r4_new)
311- return ( distance, r4 . a, r4 . b, r4 . n, true , r1 . a, r1 . b, r2 . a, r2 . b, r3 . a, r3 . b)
311+ return distance, r1, r2, r3, r4
312312 end
313313 end
314314 end
@@ -319,13 +319,15 @@ function phase3(r0::SupportPoint, r1::SupportPoint, r2::SupportPoint, r3::Suppor
319319 @warn (" MPR (phase 3): Max. number of iterations (= $niter_max ) is reached and $niter_max > 100, look at $(Modia3D. fullName (shapeA)) and $(Modia3D. fullName (shapeB)) . tol_rel increased locally for this computation to $new_tol ." )
320320 if isTC2
321321 (distance,r1,r2,r3,r4) = finalTC2 (r1_new,r2_new,r3_new,r4_new)
322- return ( distance, r4 . a, r4 . b, r4 . n, true , r1 . a, r1 . b, r2 . a, r2 . b, r3 . a, r3 . b)
322+ return distance, r1, r2, r3, r4
323323 end
324324 if isTC3
325325 (distance,r1,r2,r3,r4) = finalTC3 (r0, r1_new, r2_new, r3_new, r4_new)
326- return ( distance, r4 . a, r4 . b, r4 . n, true , r1 . a, r1 . b, r2 . a, r2 . b, r3 . a, r3 . b)
326+ return distance, r1, r2, r3, r4
327327 end
328328 end
329+ @error (" passiert das?!?!?" )
330+ return distance, r1, r2, r3, r4 # needed for a unique return type
329331end
330332
331333# MPR - Minkowski Portal Refinement algorithm
352354# Termination Condition 2
353355# Termination Condition 3
354356# Phase 3.3: construct baby tetrahedrons with r1,r2,r3,r4 and create a new portal
355- function mprGeneral (ch:: Composition.ContactDetectionMPR_handler , shapeA:: Composition.Object3D , shapeB:: Modia3D.Composition.Object3D )
357+ function mprGeneral (ch:: Composition.ContactDetectionMPR_handler{T} , shapeA:: Composition.Object3D , shapeB:: Modia3D.Composition.Object3D ) where {T}
356358 tol_rel = ch. tol_rel
357359 niter_max = ch. niter_max
358360 neps = ch. neps
@@ -365,7 +367,7 @@ function mprGeneral(ch::Composition.ContactDetectionMPR_handler, shapeA::Composi
365367 # the direction of the origin ray r0 is -r0.p
366368 centroidA = getCentroid (shapeA)
367369 centroidB = getCentroid (shapeB)
368- r0 = SupportPoint (centroidA- centroidB, - (centroidA- centroidB), SVector {3,Float64 } (0.0 ,0.0 ,0.0 ), SVector {3,Float64 } (0.0 ,0.0 ,0.0 ))
370+ r0 = SupportPoint {T} (centroidA- centroidB, - (centroidA- centroidB), SVector {3,T } (0.0 ,0.0 ,0.0 ), SVector {3,T } (0.0 ,0.0 ,0.0 ))
369371 # check if centers of shapes are overlapping
370372 checkCentersOfShapesOverlapp (r0, neps, shapeA, shapeB)
371373
@@ -386,7 +388,7 @@ function mprGeneral(ch::Composition.ContactDetectionMPR_handler, shapeA::Composi
386388 # e.g. any collision/or distance between two spheres
387389 # println("TC 1")
388390 distance = dot (r1. p,normalize (r0. p))
389- return (distance, r1. a, r1. b, r1. n, false , Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D)
391+ return (Float64 ( distance), SVector {3,Float64} ( r1. a), SVector {3,Float64} ( r1. b), SVector {3,Float64} ( r1. n) , false , Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D)
390392 else
391393 # normalize n2
392394 n2 = n2/ n2abs
@@ -407,15 +409,16 @@ function mprGeneral(ch::Composition.ContactDetectionMPR_handler, shapeA::Composi
407409
408410
409411 # ########## Phase 3, Minkowski Portal Refinement ###################
410- phase3 (r0, r1, r2, r3, neps, niter_max, tol_rel, shapeA, shapeB, scale)
412+ (distance, r1, r2, r3, r4) = phase3 (r0, r1, r2, r3, neps, niter_max, tol_rel, shapeA, shapeB, scale)
413+ return (Float64 (distance), SVector {3,Float64} (r4. a), SVector {3,Float64} (r4. b), SVector {3,Float64} (r4. n), true , SVector {3,Float64} (r1. a), SVector {3,Float64} (r1. b), SVector {3,Float64} (r2. a), SVector {3,Float64} (r2. b), SVector {3,Float64} (r3. a), SVector {3,Float64} (r3. b) )
411414end
412415
413416
414- function mprTwoSpheres (ch:: Composition.ContactDetectionMPR_handler , shapeA:: Composition.Object3D , shapeB:: Modia3D.Composition.Object3D ,
415- sphereA:: Shapes.Sphere , sphereB:: Shapes.Sphere )
417+ function mprTwoSpheres (ch:: Composition.ContactDetectionMPR_handler{T} , shapeA:: Composition.Object3D , shapeB:: Modia3D.Composition.Object3D ,
418+ sphereA:: Shapes.Sphere , sphereB:: Shapes.Sphere ) where {T}
416419 neps = ch. neps
417- radiusA = sphereA. diameter* 0.5
418- radiusB = sphereB. diameter* 0.5
420+ radiusA = T ( sphereA. diameter* 0.5 )
421+ radiusB = T ( sphereB. diameter* 0.5 )
419422 centroidSphereA = getCentroid (shapeA)
420423 centroidSphereB = getCentroid (shapeB)
421424 n = centroidSphereB - centroidSphereA
@@ -428,11 +431,11 @@ function mprTwoSpheres(ch::Composition.ContactDetectionMPR_handler, shapeA::Comp
428431 distance = distanceCentroids - radiusA - radiusB
429432 contactPointShapeA = centroidSphereA + normal* radiusA
430433 contactPointShapeB = centroidSphereB - normal* radiusB
431- return (distance, contactPointShapeA, contactPointShapeB, normal, false , Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D)
434+ return (Float64 ( distance), SVector {3,Float64} ( contactPointShapeA), SVector {3,Float64} ( contactPointShapeB), SVector {3,Float64} ( normal) , false , Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D, Modia3D. ZeroVector3D)
432435end
433436
434437
435- function mpr (ch:: Composition.ContactDetectionMPR_handler , shapeA:: Composition.Object3D , shapeB:: Modia3D.Composition.Object3D )
438+ function mpr (ch:: Composition.ContactDetectionMPR_handler{T} , shapeA:: Composition.Object3D , shapeB:: Modia3D.Composition.Object3D ) where {T}
436439 shapeKindA = shapeA. shapeKind
437440 shapeKindB = shapeB. shapeKind
438441
@@ -449,7 +452,7 @@ function mpr(ch::Composition.ContactDetectionMPR_handler, shapeA::Composition.Ob
449452 support1A, support1B, support2A, support2B, support3A, support3B) = mprGeneral (ch, shapeA, shapeB)
450453
451454 if shapeKindA == Modia3D. SphereKind
452- centroidSphere = getCentroid (shapeA)
455+ centroidSphere = SVector {3,Float64} ( getCentroid (shapeA) )
453456 sphereA1:: Shapes.Sphere = shapeA. shape
454457 radius = sphereA1. diameter* 0.5
455458 contactPointSphere = centroidSphere + radius* normal
@@ -458,7 +461,7 @@ function mpr(ch::Composition.ContactDetectionMPR_handler, shapeA::Composition.Ob
458461 contactPoint2 = contactPointOtherShape
459462 elseif shapeKindB == Modia3D. SphereKind
460463 normalLocal = - normal
461- centroidSphere = getCentroid (shapeB)
464+ centroidSphere = SVector {3,Float64} ( getCentroid (shapeB) )
462465 sphereB1:: Shapes.Sphere = shapeB. shape
463466 radius = sphereB1. diameter* 0.5
464467 contactPointSphere = centroidSphere + radius* normalLocal
0 commit comments