Allow shadow fidelity option, fix bug in rendering box shadows
This commit is contained in:
+189
-81
@@ -1,36 +1,52 @@
|
||||
{-# LANGUAGE BangPatterns #-}
|
||||
module Shape
|
||||
( module Shape.Data
|
||||
, translateSH
|
||||
, upperPrismPoly
|
||||
, upperPrismPolyHalf
|
||||
, prismPoly
|
||||
, polyCirc
|
||||
, upperBox
|
||||
, translateSHz
|
||||
, translateSHxy
|
||||
, rotateSH
|
||||
, rotateSHx
|
||||
, rotateSHq
|
||||
, polyCircx
|
||||
, scaleSH
|
||||
, colorSH
|
||||
, overColSH
|
||||
, overPosSH
|
||||
, upperCylinder
|
||||
, upperRounded
|
||||
, xCylinder
|
||||
, xCylinder'
|
||||
) where
|
||||
import Geometry
|
||||
import Shape.Data
|
||||
{-# LANGUAGE BangPatterns #-}
|
||||
|
||||
module Shape (
|
||||
module Shape.Data,
|
||||
translateSH,
|
||||
upperPrismPoly,
|
||||
upperPrismPolyMT,
|
||||
upperPrismPolySE,
|
||||
upperPrismPolyST,
|
||||
upperPrismPolySI,
|
||||
upperPrismPolySU,
|
||||
upperPrismPolyTS,
|
||||
upperBoxMT,
|
||||
upperBoxST,
|
||||
upperBoxSU,
|
||||
upperBoxHalf,
|
||||
upperPrismPolyHalf,
|
||||
upperPrismPolyHalfMI,
|
||||
upperPrismPolyHalfST,
|
||||
xCylinderST,
|
||||
prismPoly,
|
||||
prismBox,
|
||||
cylinderPoly,
|
||||
polyCirc,
|
||||
upperBox,
|
||||
translateSHz,
|
||||
translateSHxy,
|
||||
rotateSH,
|
||||
rotateSHx,
|
||||
rotateSHq,
|
||||
polyCircx,
|
||||
scaleSH,
|
||||
colorSH,
|
||||
overColSH,
|
||||
overPosSH,
|
||||
upperCylinder,
|
||||
upperRounded,
|
||||
xCylinder',
|
||||
) where
|
||||
|
||||
import Color
|
||||
import Geometry
|
||||
import qualified Quaternion as Q
|
||||
import Shape.Data
|
||||
|
||||
-- - approximate a circle by a polygon with n*2 points of radius x
|
||||
polyCirc :: Int -> Float -> [Point2]
|
||||
{-# INLINE polyCirc #-}
|
||||
polyCirc n x = map (\a -> rotateV a (V2 x 0)) $ take (n*2) [0,pi/fromIntegral n..]
|
||||
polyCirc n x = map (\a -> rotateV a (V2 x 0)) $ take (n * 2) [0, pi / fromIntegral n ..]
|
||||
|
||||
-- - approximate a circle around the x axis by a polygon with n*2 points of radius r
|
||||
polyCircx :: Int -> Float -> [Point3]
|
||||
@@ -40,83 +56,175 @@ polyCircx n = map (vNormaly . addZ 0) . polyCirc n
|
||||
-- length of polys must be the same
|
||||
-- points should be correctly ordered so that
|
||||
-- polys form a prism-like object with quad faces between them
|
||||
prismPoly
|
||||
:: [Point3]
|
||||
-> [Point3]
|
||||
-> Shape
|
||||
prismPoly ::
|
||||
Size ->
|
||||
Importance ->
|
||||
[Point3] ->
|
||||
[Point3] ->
|
||||
Shape
|
||||
{-# INLINE prismPoly #-}
|
||||
prismPoly upps downps = [Surface (RoundedFaces n) (cp:cp:f upps downps) white FullShadowFidelity]
|
||||
prismPoly size shads upps downps = [Surface (RoundedFaces n) (cp : cp : f upps downps) white shads size]
|
||||
where
|
||||
cp = centroidNum $ upps ++ downps
|
||||
n = length upps
|
||||
f (a:as) (b:bs) = a:b:f as bs
|
||||
f (a : as) (b : bs) = a : b : f as bs
|
||||
f _ _ = []
|
||||
|
||||
upperPrismPoly
|
||||
:: Float -- ^ height, expected to be strictly positive
|
||||
-> [Point2]
|
||||
-> Shape
|
||||
{-# INLINE upperPrismPoly #-}
|
||||
upperPrismPoly h ps = prismPoly (map (addZ h) ps) (map (addZ 0) ps)
|
||||
|
||||
xCylinder :: Int -> Float -> Float -> Shape
|
||||
xCylinder n r x = rotateSHq (V3 0 1 0) (pi/2) . translateSHxy (-r) 0 . upperCylinder x $ polyCirc n r
|
||||
|
||||
xCylinder' :: Float -> Float -> Shape
|
||||
xCylinder' r x = translateSHz r . rotateSHq (V3 0 1 0) (pi/2) . upperCylinder x $
|
||||
[V2 r r
|
||||
,V2 (-r/2) (r/2)
|
||||
,V2 (-r/2) (negate $ r/2)
|
||||
,V2 r (-r)
|
||||
]
|
||||
|
||||
upperBox
|
||||
:: Float -- ^ height, expected to be strictly positive
|
||||
-> [Point2]
|
||||
-> Shape
|
||||
{-# INLINE upperBox #-}
|
||||
upperBox h ps = [Surface (FlatFaces n) (f ps) white FullShadowFidelity]
|
||||
prismBox ::
|
||||
Size ->
|
||||
Importance ->
|
||||
[Point3] ->
|
||||
[Point3] ->
|
||||
Shape
|
||||
{-# INLINE prismBox #-}
|
||||
prismBox size shads upps downps = [Surface (FlatFaces n) (f upps downps) white shads size]
|
||||
where
|
||||
n = length ps
|
||||
g h' (V2 x y) = V3 x y h'
|
||||
f (x:xs) = g h x : g 0 x : f xs
|
||||
f _ = []
|
||||
n = length upps
|
||||
f (a : as) (b : bs) = a : b : f as bs
|
||||
f _ _ = []
|
||||
|
||||
cylinderPoly ::
|
||||
Size ->
|
||||
Importance ->
|
||||
[Point3] ->
|
||||
[Point3] ->
|
||||
Shape
|
||||
{-# INLINE cylinderPoly #-}
|
||||
cylinderPoly size shads upps downps = [Surface (Cylinder n) (cp1 : cp2 : f upps downps) white shads size]
|
||||
where
|
||||
cp1 = centroidNum upps
|
||||
cp2 = centroidNum downps
|
||||
n = length upps
|
||||
f (a : as) (b : bs) = a : b : f as bs
|
||||
f _ _ = []
|
||||
|
||||
upperPrismPolyMT :: Float -> [Point2] -> Shape
|
||||
upperPrismPolyMT = upperPrismPoly Medium Typical
|
||||
|
||||
upperPrismPolySE :: Float -> [Point2] -> Shape
|
||||
upperPrismPolySE = upperPrismPoly Small Essential
|
||||
|
||||
upperPrismPolyST :: Float -> [Point2] -> Shape
|
||||
upperPrismPolyST = upperPrismPoly Small Typical
|
||||
|
||||
upperPrismPolySI :: Float -> [Point2] -> Shape
|
||||
upperPrismPolySI = upperPrismPoly Small Important
|
||||
|
||||
upperPrismPolySU :: Float -> [Point2] -> Shape
|
||||
upperPrismPolySU = upperPrismPoly Small Unimportant
|
||||
|
||||
--upperPrismPolySS :: Float -> [Point2] -> Shape
|
||||
--upperPrismPolySS = upperPrismPoly Small Superfluous
|
||||
|
||||
upperPrismPolyTS :: Float -> [Point2] -> Shape
|
||||
upperPrismPolyTS = upperPrismPoly Tiny Superfluous
|
||||
|
||||
upperPrismPoly ::
|
||||
-- | height, expected to be strictly positive
|
||||
Size ->
|
||||
Importance ->
|
||||
Float ->
|
||||
[Point2] ->
|
||||
Shape
|
||||
{-# INLINE upperPrismPoly #-}
|
||||
upperPrismPoly size shad h ps = prismPoly size shad (map (addZ h) ps) (map (addZ 0) ps)
|
||||
|
||||
xCylinderST :: Float -> Float -> Shape
|
||||
xCylinderST = xCylinder' Small Typical
|
||||
|
||||
xCylinder' :: Size -> Importance -> Float -> Float -> Shape
|
||||
xCylinder' size shad r x =
|
||||
translateSHz r . rotateSHq (V3 0 1 0) (pi / 2) . upperCylinder size shad x $
|
||||
[ V2 r r
|
||||
, V2 (- r / 2) (r / 2)
|
||||
, V2 (- r / 2) (negate $ r / 2)
|
||||
, V2 r (- r)
|
||||
]
|
||||
|
||||
upperBoxMT :: Float -> [Point2] -> Shape
|
||||
upperBoxMT = upperBox Medium Typical
|
||||
|
||||
upperBoxST :: Float -> [Point2] -> Shape
|
||||
upperBoxST = upperBox Small Typical
|
||||
|
||||
upperBoxSU :: Float -> [Point2] -> Shape
|
||||
upperBoxSU = upperBox Small Unimportant
|
||||
|
||||
upperBox ::
|
||||
-- | height, expected to be strictly positive
|
||||
Size ->
|
||||
Importance ->
|
||||
Float ->
|
||||
[Point2] ->
|
||||
Shape
|
||||
{-# INLINE upperBox #-}
|
||||
upperBox size shad h ps = prismBox size shad (map (addZ h) ps) (map (addZ 0) ps)
|
||||
|
||||
rotateSHq :: Point3 -> Float -> Shape -> Shape
|
||||
rotateSHq p = overPosSH . Q.rotate . Q.axisAngle p
|
||||
|
||||
upperCylinder
|
||||
:: Float -- ^ height, expected to be strictly positive
|
||||
-> [Point2]
|
||||
-> Shape
|
||||
upperCylinder ::
|
||||
-- | height, expected to be strictly positive
|
||||
Size ->
|
||||
Importance ->
|
||||
Float ->
|
||||
[Point2] ->
|
||||
Shape
|
||||
{-# INLINE upperCylinder #-}
|
||||
upperCylinder h ps = [Surface (Cylinder n) (addZ (h-0.5) cc:addZ 0.5 cc:f ps) white FullShadowFidelity]
|
||||
upperCylinder size shad h ps = [Surface (Cylinder n) (addZ (h -0.5) cc : addZ 0.5 cc : f ps) white shad size]
|
||||
where
|
||||
cc = V2 0 0
|
||||
n = length ps
|
||||
g h' (V2 x y) = V3 x y h'
|
||||
f (x:xs) = g h x : g 0 x : f xs
|
||||
f (x : xs) = g h x : g 0 x : f xs
|
||||
f _ = []
|
||||
|
||||
upperRounded
|
||||
:: Float -- ^ height, expected to be strictly positive
|
||||
-> [Point2]
|
||||
-> Shape
|
||||
upperRounded ::
|
||||
-- | height, expected to be strictly positive
|
||||
Size ->
|
||||
Importance ->
|
||||
Float ->
|
||||
[Point2] ->
|
||||
Shape
|
||||
{-# INLINE upperRounded #-}
|
||||
upperRounded h ps = [Surface (RoundedFaces n) (addZ h cc:addZ 0 cc:f ps) white FullShadowFidelity]
|
||||
upperRounded size shad h ps = [Surface (RoundedFaces n) (addZ h cc : addZ 0 cc : f ps) white shad size]
|
||||
where
|
||||
cc = centroid ps
|
||||
n = length ps
|
||||
g h' (V2 x y) = V3 x y h'
|
||||
f (x:xs) = g h x : g 0 x : f xs
|
||||
f (x : xs) = g h x : g 0 x : f xs
|
||||
f _ = []
|
||||
|
||||
upperPrismPolyHalf
|
||||
:: Float -- ^ height, expected to be strictly positive
|
||||
-> [Point2]
|
||||
-> Shape
|
||||
upperPrismPolyHalfMI :: Float -> [Point2] -> Shape
|
||||
upperPrismPolyHalfMI = upperPrismPolyHalf Medium Important
|
||||
|
||||
upperPrismPolyHalfST :: Float -> [Point2] -> Shape
|
||||
upperPrismPolyHalfST = upperPrismPolyHalf Small Typical
|
||||
|
||||
upperPrismPolyHalf ::
|
||||
-- | height, expected to be strictly positive
|
||||
Size ->
|
||||
Importance ->
|
||||
Float ->
|
||||
[Point2] ->
|
||||
Shape
|
||||
{-# INLINE upperPrismPolyHalf #-}
|
||||
upperPrismPolyHalf h ps = prismPoly upps downps
|
||||
upperPrismPolyHalf size shad h ps = prismPoly size shad upps downps
|
||||
where
|
||||
upps = map f ps
|
||||
downps = map g ps
|
||||
f (V2 x y) = V3 (0.5 * x) (0.5 * y) h
|
||||
g (V2 x y) = V3 x y 0
|
||||
|
||||
upperBoxHalf ::
|
||||
-- | height, expected to be strictly positive
|
||||
Size ->
|
||||
Importance ->
|
||||
Float ->
|
||||
[Point2] ->
|
||||
Shape
|
||||
{-# INLINE upperBoxHalf #-}
|
||||
upperBoxHalf size shad h ps = prismBox size shad upps downps
|
||||
where
|
||||
upps = map f ps
|
||||
downps = map g ps
|
||||
@@ -157,12 +265,12 @@ rotateSHx = overPosSH . rotate3x
|
||||
|
||||
scaleSH :: Point3 -> Shape -> Shape
|
||||
{-# INLINE scaleSH #-}
|
||||
scaleSH (V3 a b c) = overPosSH (\(V3 x y z) -> V3 (x*a) (y*b) (z*c))
|
||||
scaleSH (V3 a b c) = overPosSH (\(V3 x y z) -> V3 (x * a) (y * b) (z * c))
|
||||
|
||||
overColObj :: (Point4 -> Point4) -> Surface -> Surface
|
||||
{-# INLINE overColObj #-}
|
||||
overColObj f (Surface st vs col sfid) = Surface st vs (f col) sfid
|
||||
overColObj f (Surface st vs col sfid size) = Surface st vs (f col) sfid size
|
||||
|
||||
overPosObj :: (Point3 -> Point3) -> Surface -> Surface
|
||||
{-# INLINE overPosObj #-}
|
||||
overPosObj f (Surface st vs col sfid) = Surface st (map f vs) col sfid
|
||||
overPosObj f (Surface st vs col sfid size) = Surface st (map f vs) col sfid size
|
||||
|
||||
Reference in New Issue
Block a user