Simplify laser reflection/refraction

This commit is contained in:
2025-10-27 19:41:52 +00:00
parent 7c40db7153
commit 20042fcf8d
3 changed files with 27 additions and 40 deletions
+2 -2
View File
@@ -13,8 +13,8 @@ wlIsSeeThrough wl = case _wlOpacity wl of
SeeThrough -> True SeeThrough -> True
_ -> False _ -> False
reflDirWall :: Point2 -> Point2 -> Wall -> Float reflWall :: Point2 -> Point2 -> Wall -> Float
reflDirWall sp ep wl = argV (reflectIn (uncurry (-.-) (_wlLine wl)) (ep -.- sp)) reflWall sp ep wl = argV (reflectIn (uncurry (-) (_wlLine wl)) (ep - sp))
-- point free nonsense. 0 for no damping, 1 for full damping -- point free nonsense. 0 for no damping, 1 for full damping
reflVelWallDamp :: Float -> Wall -> Point2 -> Point2 reflVelWallDamp :: Float -> Wall -> Point2 -> Point2
+19 -30
View File
@@ -1,17 +1,19 @@
{-# LANGUAGE LambdaCase #-} {-# LANGUAGE LambdaCase #-}
module Dodge.Item.Weapon.LaserPath ( module Dodge.Item.Weapon.LaserPath (
reflectLaserAlong, reflectLaserAlong,
reflectPulseLaserAlong, reflectPulseLaserAlong,
) where ) where
import Control.Lens
import Dodge.Data.Object
import Data.Bifunctor import Data.Bifunctor
import Data.Tuple import Data.Tuple
import Dodge.Base.Wall import Dodge.Base.Wall
import Dodge.Data.Object
import Dodge.Data.World import Dodge.Data.World
import Dodge.WorldEvent import Dodge.WorldEvent
import Geometry import Geometry
import LensHelp
import Linear
-- this needs to be tested with both reflections and refractions -- this needs to be tested with both reflections and refractions
reflectLaserAlong :: reflectLaserAlong ::
@@ -24,28 +26,22 @@ reflectLaserAlong ::
reflectLaserAlong phasev sp ep w = case thingHitFilt (const True) _wlUnshadowed sp ep w of reflectLaserAlong phasev sp ep w = case thingHitFilt (const True) _wlUnshadowed sp ep w of
Just (p, Right wl) Just (p, Right wl)
| Metal <- wl ^. wlMaterial -> | Metal <- wl ^. wlMaterial ->
second (p :) $ f
reflectLaserAlong p
phasev (p + angle (reflWall sp p wl))
(p +.+ unitVectorAtAngle (reflDirWall sp p wl)) (p + distance p ep *^ angle (reflWall sp p wl))
(p +.+ dist p ep *.* unitVectorAtAngle (reflDirWall sp p wl))
w
| wlIsSeeThrough wl -> | wlIsSeeThrough wl ->
second (p :) $ f p (p + signorm (refract phasev sp ep wl p)) (refract phasev sp ep wl p)
reflectLaserAlong
phasev
(p +.+ normalizeV (refract phasev sp ep wl p))
(refract phasev sp ep wl p)
w
| otherwise -> (Just (p, Right wl), [p])
Just (p, obj) -> (Just (p, obj), [p]) Just (p, obj) -> (Just (p, obj), [p])
Nothing -> (Nothing, [ep]) Nothing -> (Nothing, [ep])
where
f p a b = reflectLaserAlong phasev a b w & _2 .:~ p
refract :: Float -> Point2 -> Point2 -> Wall -> Point2 -> Point2 refract :: Float -> Point2 -> Point2 -> Wall -> Point2 -> Point2
{-# INLINE refract #-} {-# INLINE refract #-}
refract phasev x y wl p refract phasev x y wl p
| isEntering = p +.+ rotateV angleRef (normalDist wlNormal) | isEntering = p + rotateV angleRef (normalDist wlNormal)
| otherwise = p +.+ rotateV angleRef' (normalDist wlNormal') | otherwise = p + rotateV angleRef' (normalDist wlNormal')
where where
wlNormal = vNormal $ uncurry (-.-) $ swap (_wlLine wl) wlNormal = vNormal $ uncurry (-.-) $ swap (_wlLine wl)
wlNormal' = vNormal $ uncurry (-.-) (_wlLine wl) wlNormal' = vNormal $ uncurry (-.-) (_wlLine wl)
@@ -74,22 +70,15 @@ reflectPulseLaserAlong phasev sp ep w = f $ filter (isunshad . snd) $ crWlPbHit
f = \case f = \case
((p, OWall wl) : _) ((p, OWall wl) : _)
| Metal <- wl ^. wlMaterial -> | Metal <- wl ^. wlMaterial ->
second (p :) $ g
reflectPulseLaserAlong p
phasev (p + angle (reflWall sp p wl))
(p +.+ unitVectorAtAngle (reflDirWall sp p wl)) (p + distance p ep *.* angle (reflWall sp p wl))
(p +.+ dist p ep *.* unitVectorAtAngle (reflDirWall sp p wl))
w
| wlIsSeeThrough wl -> | wlIsSeeThrough wl ->
second (p :) $ g p (p + signorm (refract phasev sp ep wl p)) (refract phasev sp ep wl p)
reflectPulseLaserAlong
phasev
(p +.+ normalizeV (refract phasev sp ep wl p))
(refract phasev sp ep wl p)
w
| otherwise -> ([(p, OWall wl)], [p])
(x@(_, OPulseBall _) : ps) -> first (x :) $ f ps (x@(_, OPulseBall _) : ps) -> first (x :) $ f ps
((p, obj) : _) -> ([(p, obj)], [p]) ((p, obj) : _) -> ([(p, obj)], [p])
[] -> ([], [ep]) [] -> ([], [ep])
isunshad (OWall wl) = _wlUnshadowed wl isunshad (OWall wl) = _wlUnshadowed wl
isunshad _ = True isunshad _ = True
g p a b = reflectPulseLaserAlong phasev a b w & _2 .:~ p
+3 -5
View File
@@ -48,7 +48,7 @@ tutAnoTree = do
foldMTRS foldMTRS
[ tToBTree "TutStartRez" . return . cleatOnward <$> tutRezBox [ tToBTree "TutStartRez" . return . cleatOnward <$> tutRezBox
, corDoor , corDoor
, tToBTree "cor" . return . cleatOnward <$> (zChasm 25) , tToBTree "cor" . return . cleatOnward <$> polyChasmC 6 120
-- , tToBTree "x" . return . cleatOnward <$> airlockSimple -- , tToBTree "x" . return . cleatOnward <$> airlockSimple
-- , tToBTree "lastun" . return . cleatOnward <$> tanksRoom [] [] -- , tToBTree "lastun" . return . cleatOnward <$> tanksRoom [] []
, return $ tToBTree "cor" $ return $ cleatOnward corridor , return $ tToBTree "cor" $ return $ cleatOnward corridor
@@ -158,10 +158,8 @@ lChasm = do
-- the Float is the width of the bridge -- the Float is the width of the bridge
zChasm :: Float -> State LayoutVars Room zChasm :: Float -> State LayoutVars Room
zChasm z = do zChasm z = do
-- x <- state $ randomR (150, 300) x <- state $ randomR (150, 300)
-- y <- state $ randomR (150, 300) y <- state $ randomR (150, 300)
x <- return 250
y <- return 250
roomRectAutoLinks x y roomRectAutoLinks x y
<&> rmLinks %~ setOutLinks (isCornerLink NorthWest) <&> rmLinks %~ setOutLinks (isCornerLink NorthWest)
<&> rmLinks %~ setInLinks (isCornerLink SouthEast) <&> rmLinks %~ setInLinks (isCornerLink SouthEast)