packages feed

keid-geometry 0.1.1.1 → 0.1.1.2

raw patch · 5 files changed

+284/−19 lines, 5 filesdep ~keid-corePVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

Dependency ranges changed: keid-core

API changes (from Hackage documentation)

+ Geometry.Quad: indices :: Num a => Quad a
+ Geometry.Quad: indicesQuad :: Num a => [a]
+ Geometry.Quad: indicesWire :: Num a => [a]
+ Geometry.Quad: instance GHC.Generics.Generic1 Geometry.Quad.Quad
+ Geometry.Tile.Microblob: Microblob :: a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> Microblob a
+ Geometry.Tile.Microblob: [$sel:bbEdgeHorizontal:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: [$sel:blCornerInner:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: [$sel:blCornerOuter:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: [$sel:brCornerInner:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: [$sel:brCornerOuter:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: [$sel:full:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: [$sel:llEdgeVertical:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: [$sel:rrEdgeVertical:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: [$sel:tlCornerInner:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: [$sel:tlCornerOuter:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: [$sel:trCornerInner:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: [$sel:trCornerOuter:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: [$sel:ttEdgeHorizontal:Microblob] :: Microblob a -> a
+ Geometry.Tile.Microblob: data Microblob a
+ Geometry.Tile.Microblob: genSets :: Neighbors Int -> (Set Int, Map Int Int)
+ Geometry.Tile.Microblob: indices :: Microblob Int
+ Geometry.Tile.Microblob: instance Data.Foldable.Foldable Geometry.Tile.Microblob.Microblob
+ Geometry.Tile.Microblob: instance Data.Traversable.Traversable Geometry.Tile.Microblob.Microblob
+ Geometry.Tile.Microblob: instance GHC.Base.Applicative Geometry.Tile.Microblob.Microblob
+ Geometry.Tile.Microblob: instance GHC.Base.Functor Geometry.Tile.Microblob.Microblob
+ Geometry.Tile.Microblob: instance GHC.Classes.Eq a => GHC.Classes.Eq (Geometry.Tile.Microblob.Microblob a)
+ Geometry.Tile.Microblob: instance GHC.Classes.Ord a => GHC.Classes.Ord (Geometry.Tile.Microblob.Microblob a)
+ Geometry.Tile.Microblob: instance GHC.Generics.Generic1 Geometry.Tile.Microblob.Microblob
+ Geometry.Tile.Microblob: instance GHC.Show.Show a => GHC.Show.Show (Geometry.Tile.Microblob.Microblob a)
+ Geometry.Tile.Microblob: names :: Microblob Text
+ Geometry.Tile.Microblob: quad :: Neighbors Int -> Microblob a -> Int -> Quad a
+ Geometry.Tile.Neighbors: Neighbors :: a -> a -> a -> a -> a -> a -> a -> a -> Neighbors a
+ Geometry.Tile.Neighbors: [$sel:east:Neighbors] :: Neighbors a -> a
+ Geometry.Tile.Neighbors: [$sel:north:Neighbors] :: Neighbors a -> a
+ Geometry.Tile.Neighbors: [$sel:northEast:Neighbors] :: Neighbors a -> a
+ Geometry.Tile.Neighbors: [$sel:northWest:Neighbors] :: Neighbors a -> a
+ Geometry.Tile.Neighbors: [$sel:south:Neighbors] :: Neighbors a -> a
+ Geometry.Tile.Neighbors: [$sel:southEast:Neighbors] :: Neighbors a -> a
+ Geometry.Tile.Neighbors: [$sel:southWest:Neighbors] :: Neighbors a -> a
+ Geometry.Tile.Neighbors: [$sel:west:Neighbors] :: Neighbors a -> a
+ Geometry.Tile.Neighbors: bitsNW :: Neighbors Int
+ Geometry.Tile.Neighbors: data Neighbors a
+ Geometry.Tile.Neighbors: directionsWith :: Num a => (a -> a -> b) -> Neighbors b
+ Geometry.Tile.Neighbors: everyone :: Neighbors Bool
+ Geometry.Tile.Neighbors: fromBitsNW :: Bits a => a -> Neighbors Bool
+ Geometry.Tile.Neighbors: instance Data.Foldable.Foldable Geometry.Tile.Neighbors.Neighbors
+ Geometry.Tile.Neighbors: instance Data.Traversable.Traversable Geometry.Tile.Neighbors.Neighbors
+ Geometry.Tile.Neighbors: instance GHC.Base.Applicative Geometry.Tile.Neighbors.Neighbors
+ Geometry.Tile.Neighbors: instance GHC.Base.Functor Geometry.Tile.Neighbors.Neighbors
+ Geometry.Tile.Neighbors: instance GHC.Classes.Eq a => GHC.Classes.Eq (Geometry.Tile.Neighbors.Neighbors a)
+ Geometry.Tile.Neighbors: instance GHC.Classes.Ord a => GHC.Classes.Ord (Geometry.Tile.Neighbors.Neighbors a)
+ Geometry.Tile.Neighbors: instance GHC.Generics.Generic1 Geometry.Tile.Neighbors.Neighbors
+ Geometry.Tile.Neighbors: instance GHC.Show.Show a => GHC.Show.Show (Geometry.Tile.Neighbors.Neighbors a)
+ Geometry.Tile.Neighbors: isCorner :: Neighbors Bool
+ Geometry.Tile.Neighbors: names :: IsString a => Neighbors a
+ Geometry.Tile.Neighbors: nobody :: Neighbors Bool
+ Geometry.Tile.Neighbors: testBitsNW :: Bits a => Neighbors (a -> Bool)
+ Geometry.Tile.Neighbors: toBitsNW :: Neighbors Bool -> Int

Files

ChangeLog.md view
@@ -1,5 +1,10 @@ # Changelog for keid-geometry +## 0.1.1.2++- Added `Geometry.Tile.Neighbors` collection and bitset-based adjacency tests.+- Added `Geometry.Tile.Microblob` collection for sub-grid synthesis of "blob" tileset.+ ## 0.1.1.1  - Added ray-plane intersection and related types.
keid-geometry.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           keid-geometry-version:        0.1.1.1+version:        0.1.1.2 synopsis:       Geometry primitives for Keid engine. category:       Game Engine author:         IC Rainbow@@ -33,6 +33,8 @@       Geometry.Plane       Geometry.Quad       Geometry.Ray+      Geometry.Tile.Microblob+      Geometry.Tile.Neighbors   other-modules:       Paths_keid_geometry   hs-source-dirs:@@ -98,7 +100,7 @@   build-depends:       base >=4.7 && <5     , geomancy-    , keid-core+    , keid-core >=0.1.6.1     , mtl     , rio >=0.1.12.0     , vector
src/Geometry/Quad.hs view
@@ -6,6 +6,10 @@   , toVertices   , toVertices2 +  , indicesQuad+  , indicesWire+  , indices+   , quadPositions   , quadUV   , quadNormals@@ -17,6 +21,7 @@ import Geomancy.Vec3 qualified as Vec3  import Resource.Model (Vertex(..))+import Resource.Collection (Generic1, Generically1(..), enumerate)  data Quad a = Quad   { quadLT :: a@@ -24,23 +29,8 @@   , quadLB :: a   , quadRB :: a   }-  deriving (Eq, Ord, Show, Functor, Foldable, Traversable)--instance Applicative Quad where-  {-# INLINE pure #-}-  pure x = Quad-    { quadLT = x-    , quadRT = x-    , quadLB = x-    , quadRB = x-    }--  funcs <*> args = Quad-    { quadLT = quadLT funcs $ quadLT args-    , quadRT = quadRT funcs $ quadRT args-    , quadLB = quadLB funcs $ quadLB args-    , quadRB = quadRB funcs $ quadRB args-    }+  deriving (Eq, Ord, Show, Functor, Foldable, Traversable, Generic1)+  deriving Applicative via Generically1 Quad  -- | 2 clockwise ordered triangles toVertices :: Quad (Vertex pos attrs) -> [Vertex pos attrs]@@ -53,6 +43,31 @@ toVertices2 q = vertices <> reverse vertices   where     vertices = toVertices q++{-# SPECIALIZE indicesQuad :: [Word32] #-}+indicesQuad :: Num a => [a]+indicesQuad =+  [ quadLT, quadRT, quadLB+  , quadLB, quadRT, quadRB+  ]+  where+    Quad{..} = indices++{-# SPECIALIZE indicesWire :: [Word32] #-}+indicesWire :: Num a => [a]+indicesWire =+  [ quadLT, quadRT+  , quadRT, quadRB+  , quadRB, quadLB+  , quadLB, quadLT+  ]+  where+    Quad{..} = indices++{-# SPECIALIZE indices :: Quad Int #-}+{-# SPECIALIZE indices :: Quad Word32 #-}+indices :: Num a => Quad a+indices = fmap fst . enumerate $ pure ()  coloredQuad :: Vec4 -> Quad (Vertex Vec3.Packed Vec4) coloredQuad color = Vertex <$> quadPositions <*> pure color
+ src/Geometry/Tile/Microblob.hs view
@@ -0,0 +1,144 @@+module Geometry.Tile.Microblob+  ( Microblob(..)+  , indices+  , names+  , quad++  , genSets+  ) where++import RIO++import Data.Bits+import Geometry.Quad (Quad(..))+import Geometry.Tile.Neighbors (Neighbors(..))+import Resource.Collection (Generic1, Generically1(..), enumerate)+import RIO.Map qualified as Map+import RIO.Set qualified as Set++data Microblob a = Microblob+  { brCornerInner    :: a+  , blCornerInner    :: a+  , trCornerInner    :: a+  , tlCornerInner    :: a+  , tlCornerOuter    :: a+  , ttEdgeHorizontal :: a+  , trCornerOuter    :: a+  , llEdgeVertical   :: a+  , full             :: a+  , rrEdgeVertical   :: a+  , blCornerOuter    :: a+  , bbEdgeHorizontal :: a+  , brCornerOuter    :: a+  }+  deriving stock (Eq, Ord, Show, Functor, Foldable, Traversable, Generic1)+  deriving Applicative via Generically1 Microblob++indices :: Microblob Int+indices = fmap fst . enumerate $ pure ()++names :: Microblob Text+names = Microblob+  { brCornerInner    = "brCornerInner"+  , blCornerInner    = "blCornerInner"+  , trCornerInner    = "trCornerInner"+  , tlCornerInner    = "tlCornerInner"+  , tlCornerOuter    = "tlCornerOuter"+  , ttEdgeHorizontal = "ttEdgeHorizontal"+  , trCornerOuter    = "trCornerOuter"+  , llEdgeVertical   = "llEdgeVertical"+  , full             = "full"+  , rrEdgeVertical   = "rrEdgeVertical"+  , blCornerOuter    = "blCornerOuter"+  , bbEdgeHorizontal = "bbEdgeHorizontal"+  , brCornerOuter    = "brCornerOuter"+  }++quad :: Neighbors Int -> Microblob a -> Int -> Quad a+quad Neighbors{..} Microblob{..} index = Quad+  { quadLT =+      if iNorth && iWest then+        if testBit index northWest then+          full+        else+          tlCornerInner+      else+        if iNorth then+          llEdgeVertical+        else+          if iWest then+            ttEdgeHorizontal+          else+            tlCornerOuter++  , quadRT =+      if iNorth && iEast then+        if testBit index northEast then+          full+        else+          trCornerInner+      else+        if iNorth then+          rrEdgeVertical+        else+          if iEast then+            ttEdgeHorizontal+          else+            trCornerOuter++  , quadLB =+      if iSouth && iWest then+        if testBit index southWest then+          full+        else+          blCornerInner+      else+        if iSouth then+          llEdgeVertical+        else+          if iWest then+            bbEdgeHorizontal+          else+            blCornerOuter++  , quadRB =+      if iSouth && iEast then+        if testBit index southEast then+          full+        else+          brCornerInner+      else+        if iSouth then+          rrEdgeVertical+        else+          if iEast then+            bbEdgeHorizontal+          else+            brCornerOuter+  }+  where+    iNorth = testBit index north+    iWest  = testBit index west+    iEast  = testBit index east+    iSouth = testBit index south++genSets :: Neighbors Int -> (Set Int, Map Int Int)+genSets bits = foldl' @[] f (Set.empty, Map.empty) [0..255]+  where+    Neighbors{..} = bits++    f (uniq, dups) i =+      ( Set.insert index uniq+      , Map.insert i index dups+      )+      where+        index = i+          & bool (clearBit northWest) id (iNorth && iWest)+          & bool (clearBit northEast) id (iNorth && iEast)+          & bool (clearBit southWest) id (iSouth && iWest)+          & bool (clearBit southEast) id (iSouth && iEast)++        iNorth = testBit i north+        iWest  = testBit i west+        iEast  = testBit i east+        iSouth = testBit i south
+ src/Geometry/Tile/Neighbors.hs view
@@ -0,0 +1,99 @@+module Geometry.Tile.Neighbors+  ( Neighbors(..)+  , nobody+  , everyone++  , bitsNW+  , testBitsNW+  , fromBitsNW+  , toBitsNW++  , directionsWith+  , isCorner+  , names+  ) where++import RIO++import Data.Bits+import Resource.Collection (Generic1, Generically1(..), enumerate)++nobody :: Neighbors Bool+nobody = pure False++everyone :: Neighbors Bool+everyone = pure True++data Neighbors a = Neighbors+  { northWest :: a+  , north     :: a+  , northEast :: a+  , east      :: a+  , southEast :: a+  , south     :: a+  , southWest :: a+  , west      :: a+  }+  deriving stock (Eq, Ord, Show, Functor, Foldable, Traversable, Generic1)+  deriving Applicative via Generically1 Neighbors++bitsNW :: Neighbors Int+bitsNW = fmap fst . enumerate $ pure ()++{-# INLINE testBitsNW #-}+testBitsNW :: Bits a => Neighbors (a -> Bool)+testBitsNW =+  bitsNW <&> \i packed ->+    testBit packed i++{-# INLINE fromBitsNW #-}+fromBitsNW :: Bits a => a -> Neighbors Bool+fromBitsNW packed =+  testBitsNW <&> \test ->+    test packed++{-# INLINE toBitsNW #-}+toBitsNW :: Neighbors Bool -> Int+toBitsNW = toBits bitsNW++{-# INLINE toBits #-}+toBits :: Neighbors Int -> Neighbors Bool -> Int+toBits bits = foldl' (flip (.|.)) zeroBits . liftA2 toBit bits+  where+    toBit i = bool zeroBits (bit i)++directionsWith :: (Num a) => (a -> a -> b) -> Neighbors b+directionsWith f = Neighbors+  { northWest = f (-1) (-1)+  , north     = f   0  (-1)+  , northEast = f   1  (-1)+  , east      = f   1    0+  , southEast = f   1    1+  , south     = f   0    1+  , southWest = f (-1)   1+  , west      = f (-1)   0+  }++isCorner :: Neighbors Bool+isCorner = Neighbors+  { northWest = True+  , north     = False+  , northEast = True+  , east      = False+  , southEast = True+  , south     = False+  , southWest = True+  , west      = False+  }++names :: IsString a => Neighbors a+names = Neighbors+  { northWest = "nw"+  , north     = "n"+  , northEast = "ne"+  , east      = "e"+  , southEast = "se"+  , south     = "s"+  , southWest = "sw"+  , west      = "w"+  }