我有这个 Haskell 代码来测试形状之间的碰撞(它取决于线性和镜头包)
import Linear hiding (trace)
import Control.Lens.Getter ((^.))
type Vec3 = V3 Float
data Tri = Tri Vec3 Vec3 Vec3
data Box = Box Vec3 Vec3
-- | Any primitive collidable in 3D
class Collide a where
axes :: a -> [Vec3] -- | return all potentially separating axes, normalized
-- | project the shape onto the normalized axis, giving a 1D line segment
project :: a -> Vec3 -> (Float, Float)
intersects :: (Collide a, Collide b) => a -> b -> Bool
intersects a b = isOverlap `all` axs
where axs = axes a ++ axes b
--do the line segments overlap?
overlaps (l, r) (l', r') = l' <= r && r' >= l
isOverlap ax = project a ax `overlaps` project b ax
{-# SPECIALIZE intersects :: Box -> Tri -> Bool #-}
instance Collide Tri where
--face normal, and edge normals
{-# INLINE axes #-}
axes (Tri q r s) = map normalize (face : edges)
where face = (q ^-^ r) `cross` (s ^-^ r)
edges = map (face `cross`) [q ^-^ r, r ^-^ s, s ^-^ q]
{-# INLINE project #-}
project (Tri q r s) ax = (minimum projs, maximum projs)
where projs = map (dot ax) [q, r, s]
instance Collide Box where
{-# INLINE axes #-}
axes _ = basis --it's axis aligned!
{-# INLINE project #-}
project (Box a b) ax@(V3 x y z) = (min l r, max l r)
--there are 4 possible pairs of point depending on the direction of ax
--partially apply just x and y to the constructor in c' and d'
where (c', d') | x*y > 0 = (V3 (a^._x) (a^._y), V3 (b^._x) (b^._y)) --same x and y
| otherwise = (V3 (a^._x) (b^._y), V3 (b^._x) (a^._y)) --different x and y
(c, d) | x*z > 0 = (c' (a^._z), d' (b^._z)) --same x and z
| otherwise = (c' (b^._z), d' (a^._z)) --different x and z
(l, r) = (c `dot` ax, d `dot` ax)
调用intersects :: Box -> Tri -> Bool
减慢了我的应用程序,但我无法让它运行得更快。我查看了分析器、堆配置文件和 的输出-ddump-simpl
,但它们没有提供任何线索。我错过了什么?