immutaball-core-0.1.0.5.1: Immutaball/Share/Level/Utils.hs
{-# OPTIONS_GHC -fno-warn-tabs #-} -- Support tab indentation better, for a better default of no warning if tabs are used: https://dmitryfrank.com/articles/indent_with_tabs_align_with_spaces .
-- Enable warnings:
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
-- Level/Utils.hs.
{-# LANGUAGE Haskell2010 #-}
module Immutaball.Share.Level.Utils
(
postprocessSol,
miscProcessSol,
transformSol,
restoreSolTransformation,
restoreSolTransformationSimple,
mapcSolTransformationSimple,
solErp,
solErpdn
) where
import Prelude ()
import Immutaball.Prelude
import Control.Lens
import Immutaball.Share.Level.Base
import Immutaball.Share.Math
import Immutaball.Share.Utils
-- | ‘transformSol’ and ‘miscProcessSol’.
postprocessSol :: Mat4 Double -> Sol -> Sol
postprocessSol m sol = miscProcessSol . transformSol m $ sol
-- | Replace ‘default’ with ‘mtrl/invisible’ for all mtrl paths.
miscProcessSol :: Sol -> Sol
miscProcessSol sol = sol &
(solMv %~ fmap (mtrlF %~ (\p -> if' (p /= "default") p "mtrl/invisible")))
-- | Apply a transformation to all positions in a Sol.
--
-- TODO: apply transformation to path E orientation, which is a quaternion.
transformSol :: Mat4 Double -> Sol -> Sol
transformSol m sol = sol &
(solVv %~ fmap (vertP %~ m4v3 m)) &
(solPv %~ fmap (pathP %~ m4v3 m)) &
-- TODO:
--(solPv %~ fmap (pathE %~ (\q -> (\v -> (qasv4.~v) & q) . TODO . mv4 m . rotate3 . qToSr . (^.qasv4) $ q))) & -- Convert quaternion rotation to rotation matrix, mat mul, then convert back to quaternion.
(solHv %~ fmap (itemP %~ m4v3 m)) &
(solZv %~ fmap (goalP %~ m4v3 m)) &
(solJv %~ fmap (jumpP %~ m4v3 m)) &
(solJv %~ fmap (jumpQ %~ m4v3 m)) &
(solXv %~ fmap (swchP %~ m4v3 m)) &
(solUv %~ fmap (ballP %~ m4v3 m)) &
(solWv %~ fmap (viewP %~ m4v3 m)) &
(solWv %~ fmap (viewQ %~ m4v3 m)) &
id
-- | Invert mapc's swapping of y and z axes and negation to in terms I like to
-- think of in more; glFrustrum can be combined with a transformation.
restoreSolTransformation :: Mat4 Double
restoreSolTransformation = m3to4 $ restoreSolTransformationSimple
-- | Invert 'mapcSolTransformationSimple'.
--
-- This does not include the scaling by 1/64, which is preserved.
restoreSolTransformationSimple :: Mat3 Double
restoreSolTransformationSimple = Mat3 $ Vec3
(Vec3 1.0 0.0 0.0 )
(Vec3 0.0 0.0 (-1.0))
(Vec3 0.0 1.0 0.0 )
mapcSolTransformationSimple :: Mat3 Double
mapcSolTransformationSimple = Mat3 $ Vec3
(Vec3 1.0 0.0 0.0)
(Vec3 0.0 0.0 1.0)
(Vec3 0.0 (-1.0) 0.0)
-- | Convert a linear parameter (e.g. from 0 to 1) to a parameter that reflects
-- the sol ‘erp’ interpolation formula, for smooth paths.
solErp :: (Fractional a) => a -> a
solErp t = -2.0*t*t*t + 3.0*t*t
-- | Variant of 'solErp' that calculates derivatives an arbitrary number of times.
solErpdn :: (Fractional a) => Integer -> a -> a
solErpdn 0 t = -2.0*t*t*t + 3.0*t*t -- -2t^3 + 3t^2
solErpdn 1 t = -6.0*t*t + 6.0*t -- -6t^2 + 6t
solErpdn 2 t = -12.0*t + 6.0 -- -12t + 6
solErpdn 3 _t = -12.0 -- -12
solErpdn _ _t = 0