{-# LANGUAGE RecordWildCards #-}
module Physics.Constraints.Contact.NonPenetration where
import Physics.Constraint
import Physics.Constraints.Types
import Physics.Constraints.SolutionProcessors
import Physics.Contact.Types
import Physics.Linear
import Utils.Utils
constraintGen :: ContactBehavior
-> Double
-> Flipping Contact'
-> (PhysicalObj, PhysicalObj)
-> Constraint
constraintGen beh dt fContact ab =
flipExtract $ flipMap (toConstraint beh dt) fContact ab
{-# INLINE constraintGen #-}
toConstraint :: ContactBehavior
-> Double
-> Contact'
-> (PhysicalObj, PhysicalObj)
-> Constraint
toConstraint beh dt c ab = Constraint (jacobian c ab) (baumgarte beh dt c)
{-# INLINE toConstraint #-}
jacobian :: Contact'
-> (PhysicalObj, PhysicalObj)
-> V6
jacobian Contact'{..} (a, b) = ja `join3v3` jb
where ja = negateV2 n `append2` ((xa `minusV2` p') `crossV2` n)
jb = n `append2` ((p' `minusV2` xb) `crossV2` n)
xa = _physObjPos a
xb = _physObjPos b
(P2 p') = _contactPenetrator'
n = _contactEdgeNormal'
{-# INLINE jacobian #-}
baumgarte :: ContactBehavior
-> Double
-> Contact'
-> Double
baumgarte beh dt c = if d > slop then (b / dt) * (slop - d) else 0
where b = contactBaumgarte beh
slop = contactPenetrationSlop beh
d = _contactDepth' c
{-# INLINE baumgarte #-}
solutionProcessor :: Lagrangian
-> Lagrangian
-> Processed Lagrangian
solutionProcessor = positive
{-# INLINE solutionProcessor #-}