aztecs-transform 0.2.0.0 → 0.3.0
raw patch · 4 files changed
+166/−64 lines, 4 filesdep +containersdep −aztecs-hierarchydep −mtldep ~aztecsPVP ok
version bump matches the API change (PVP)
Dependencies added: containers
Dependencies removed: aztecs-hierarchy, mtl
Dependency ranges changed: aztecs
API changes (from Hackage documentation)
- Data.Aztecs.Transform: Size :: V2 Int -> Size
- Data.Aztecs.Transform: Transform :: !V2 Int -> !Float -> !V2 Int -> Transform
- Data.Aztecs.Transform: [transformPosition] :: Transform -> !V2 Int
- Data.Aztecs.Transform: [transformRotation] :: Transform -> !Float
- Data.Aztecs.Transform: [transformScale] :: Transform -> !V2 Int
- Data.Aztecs.Transform: [unSize] :: Size -> V2 Int
- Data.Aztecs.Transform: data Transform
- Data.Aztecs.Transform: instance Data.Aztecs.Component.Component Data.Aztecs.Transform.Size
- Data.Aztecs.Transform: instance Data.Aztecs.Component.Component Data.Aztecs.Transform.Transform
- Data.Aztecs.Transform: instance GHC.Classes.Eq Data.Aztecs.Transform.Transform
- Data.Aztecs.Transform: instance GHC.Show.Show Data.Aztecs.Transform.Transform
- Data.Aztecs.Transform: newtype Size
- Data.Aztecs.Transform: transform :: Transform
+ Aztecs.Transform: GlobalTransform :: Transform t s r -> GlobalTransform t s r
+ Aztecs.Transform: Size :: a -> Size a
+ Aztecs.Transform: Transform :: t -> s -> r -> Transform t s r
+ Aztecs.Transform: [transformRotation] :: Transform t s r -> r
+ Aztecs.Transform: [transformScale] :: Transform t s r -> s
+ Aztecs.Transform: [transformTranslation] :: Transform t s r -> t
+ Aztecs.Transform: [unGlobalTransform] :: GlobalTransform t s r -> Transform t s r
+ Aztecs.Transform: [unSize] :: Size a -> a
+ Aztecs.Transform: data Transform t s r
+ Aztecs.Transform: instance (GHC.Base.Monad m, Data.Typeable.Internal.Typeable a) => Aztecs.ECS.Component.Component m (Aztecs.Transform.Size a)
+ Aztecs.Transform: instance (GHC.Base.Monad m, Data.Typeable.Internal.Typeable t, Data.Typeable.Internal.Typeable s, Data.Typeable.Internal.Typeable r) => Aztecs.ECS.Component.Component m (Aztecs.Transform.GlobalTransform t s r)
+ Aztecs.Transform: instance (GHC.Base.Monad m, Data.Typeable.Internal.Typeable t, Data.Typeable.Internal.Typeable s, Data.Typeable.Internal.Typeable r, GHC.Num.Num t, GHC.Num.Num s, GHC.Num.Num r) => Aztecs.ECS.Component.Component m (Aztecs.Transform.Transform t s r)
+ Aztecs.Transform: instance (GHC.Num.Num t, GHC.Num.Num s, GHC.Num.Num r) => GHC.Base.Monoid (Aztecs.Transform.Transform t s r)
+ Aztecs.Transform: instance (GHC.Num.Num t, GHC.Num.Num s, GHC.Num.Num r) => GHC.Base.Semigroup (Aztecs.Transform.Transform t s r)
+ Aztecs.Transform: instance (GHC.Show.Show t, GHC.Show.Show s, GHC.Show.Show r) => GHC.Show.Show (Aztecs.Transform.GlobalTransform t s r)
+ Aztecs.Transform: instance (GHC.Show.Show t, GHC.Show.Show s, GHC.Show.Show r) => GHC.Show.Show (Aztecs.Transform.Transform t s r)
+ Aztecs.Transform: instance GHC.Show.Show a => GHC.Show.Show (Aztecs.Transform.Size a)
+ Aztecs.Transform: newtype GlobalTransform t s r
+ Aztecs.Transform: newtype Size a
+ Aztecs.Transform: transform :: (Num t, Num s, Num r) => Transform t s r
+ Aztecs.Transform: transform2d :: Transform2D
+ Aztecs.Transform: type GlobalTransform2D = GlobalTransform V2 Int V2 Float Float
+ Aztecs.Transform: type Size2D = Size V2 Float
+ Aztecs.Transform: type Transform2D = Transform V2 Int V2 Float Float
Files
- LICENSE +28/−28
- aztecs-transform.cabal +8/−15
- src/Aztecs/Transform.hs +130/−0
- src/Data/Aztecs/Transform.hs +0/−21
LICENSE view
@@ -1,29 +1,29 @@-Copyright (c) 2024, Matt Hunzinger---Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions are met:-- * Redistributions of source code must retain the above copyright- notice, this list of conditions and the following disclaimer.-- * Redistributions in binary form must reproduce the above- copyright notice, this list of conditions and the following- disclaimer in the documentation and/or other materials provided- with the distribution.-- * Neither the name of the copyright holder nor the names of its- contributors may be used to endorse or promote products derived- from this software without specific prior written permission.--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+Copyright (c) 2024, Matt Hunzinger + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
aztecs-transform.cabal view
@@ -1,33 +1,26 @@ cabal-version: 2.4 name: aztecs-transform-version: 0.2.0.0+version: 0.3.0 license: BSD-3-Clause license-file: LICENSE maintainer: matt@hunzinger.me author: Matt Hunzinger-synopsis: A type-safe and friendly Entity-Component-System (ECS) for Haskell-description: The Entity-Component-System (ECS) pattern is commonly used in video game develop to represent world objects.- .- ECS follows the principal of composition over inheritence. Each type of- object (e.g. sword, monster, etc), in the game has a unique EntityId. Each- entity has various Components associated with it (material, weight, damage, etc).- Systems act on entities which have the required Components. homepage: https://github.com/matthunz/aztecs+synopsis: Transform components for Aztecs+description: Transform components for the Aztecs game engine and ECS category: Game Engine source-repository head type: git- location: https://github.com/matthunz/aztecs.git+ location: https://github.com/matthunz/aztecs-transform.git library- exposed-modules:- Data.Aztecs.Transform+ exposed-modules: Aztecs.Transform hs-source-dirs: src default-language: Haskell2010 ghc-options: -Wall build-depends: base >=4.6 && <5,- aztecs >= 0.5,- aztecs-hierarchy >= 0.1,- mtl >=2,- linear >= 1+ aztecs >=0.16 && <0.17,+ containers >=0.6 && <0.9,+ linear >=1
+ src/Aztecs/Transform.hs view
@@ -0,0 +1,130 @@+{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} + +-- | +-- Module : Aztecs.Transform +-- Copyright : (c) Matt Hunzinger, 2025 +-- License : BSD-style (see the LICENSE file in the distribution) +-- +-- Maintainer : matt@hunzinger.me +-- Stability : provisional +-- Portability : non-portable (GHC extensions) +module Aztecs.Transform + ( -- * Components + + -- ** 2D + Transform2D, + transform2d, + GlobalTransform2D, + Size2D, + + -- ** Generic + Transform (..), + GlobalTransform (..), + transform, + Size (..), + + module Linear + ) +where + +import Aztecs.ECS +import Aztecs.Hierarchy +import Control.Monad +import Data.Data (Typeable) +import qualified Data.Set as Set +import Linear +import Prelude hiding (lookup) + +type GlobalTransform2D = GlobalTransform (V2 Int) (V2 Float) Float + +newtype GlobalTransform t s r = GlobalTransform {unGlobalTransform :: Transform t s r} + deriving (Show) + +instance + (Monad m, Typeable t, Typeable s, Typeable r) => + Component m (GlobalTransform t s r) + +type Size2D = Size (V2 Float) + +newtype Size a = Size {unSize :: a} + deriving (Show) + +instance (Monad m, Typeable a) => Component m (Size a) + +type Transform2D = Transform (V2 Int) (V2 Float) Float + +data Transform t s r = Transform + { transformTranslation :: t, + transformScale :: s, + transformRotation :: r + } + deriving (Show) + +instance (Num t, Num s, Num r) => Semigroup (Transform t s r) where + Transform t1 s1 r1 <> Transform t2 s2 r2 = Transform (t1 + t2) (s1 * s2) (r1 + r2) + +instance (Num t, Num s, Num r) => Monoid (Transform t s r) where + mempty = Transform 0 1 0 + +instance + (Monad m, Typeable t, Typeable s, Typeable r, Num t, Num s, Num r) => + Component m (Transform t s r) + where + componentOnInsert e localT = do + globalT <- computeGlobalTransform e localT + insertUntracked e . bundle $ GlobalTransform @t @s @r globalT + propagateToChildren e globalT + + componentOnChange e _ newLocalT = do + globalT <- computeGlobalTransform e newLocalT + insertUntracked e . bundle $ GlobalTransform @t @s @r globalT + propagateToChildren e globalT + + componentOnRemove e _ = void $ remove @_ @(GlobalTransform t s r) e + +-- | Propagate a global transform to all children of an entity. +propagateToChildren :: + forall m t s r. + (Monad m, Typeable t, Typeable s, Typeable r, Num t, Num s, Num r) => + EntityID -> + Transform t s r -> + Access m () +propagateToChildren parentE parentGlobal = do + maybeChildren <- lookup @_ @Children parentE + case maybeChildren of + Nothing -> return () + Just children -> mapM_ propagateToChild (Set.toList $ unChildren children) + where + propagateToChild :: EntityID -> Access m () + propagateToChild childE = do + maybeLocalT <- lookup @_ @(Transform t s r) childE + case maybeLocalT of + Nothing -> return () + Just localT -> do + let childGlobal = localT <> parentGlobal + insertUntracked childE . bundle $ GlobalTransform @t @s @r childGlobal + propagateToChildren childE childGlobal + +-- | Compute the global transform for an entity based on its local transform and parent. +computeGlobalTransform :: + forall m t s r. + (Monad m, Typeable t, Typeable s, Typeable r, Num t, Num s, Num r) => + EntityID -> + Transform t s r -> + Access m (Transform t s r) +computeGlobalTransform e localT = do + maybeParent <- lookup @_ @Parent e + case maybeParent of + Nothing -> return localT + Just (Parent parentE) -> do + maybeParentGlobal <- lookup @_ @(GlobalTransform t s r) parentE + return $ localT <> maybe mempty unGlobalTransform maybeParentGlobal + +transform2d :: Transform2D +transform2d = transform + +transform :: (Num t, Num s, Num r) => Transform t s r +transform = mempty
− src/Data/Aztecs/Transform.hs
@@ -1,21 +0,0 @@-module Data.Aztecs.Transform where--import Data.Aztecs-import Linear (V2 (..))--data Transform = Transform- { transformPosition :: !(V2 Int),- transformRotation :: !Float,- transformScale :: !(V2 Int)- }- deriving (Eq, Show)--transform :: Transform-transform = Transform (V2 0 0) 0 (V2 1 1)--instance Component Transform---newtype Size = Size {unSize :: V2 Int}--instance Component Size