packages feed

apecs-physics 0.2.0.0 → 0.3.0

raw patch · 9 files changed

+174/−184 lines, 9 filesdep ~apecsPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: apecs

API changes (from Hackage documentation)

- Apecs.Physics: ConstraintExtend :: Entity -> Entity -> ConstraintType -> Constraint
- Apecs.Physics: ConstraintRead :: Constraint
- Apecs.Physics: ShapeExtend :: Entity -> Convex -> Shape
+ Apecs.Physics: Bitmask :: CUInt -> Bitmask
+ Apecs.Physics: ConstraintList :: [Entity] -> ConstraintList
+ Apecs.Physics: ShapeList :: [Entity] -> ShapeList
+ Apecs.Physics: newtype Bitmask
+ Apecs.Physics: newtype ConstraintList
+ Apecs.Physics: newtype ShapeList
+ Apecs.Physics: type BVec = Vec
+ Apecs.Physics: type WVec = Vec
- Apecs.Physics: Constraint :: Entity -> ConstraintType -> Constraint
+ Apecs.Physics: Constraint :: Entity -> Entity -> ConstraintType -> Constraint
- Apecs.Physics: Shape :: Convex -> Shape
+ Apecs.Physics: Shape :: Entity -> Convex -> Shape

Files

Chipmunk2D/src/cpSpace.c view
@@ -123,8 +123,8 @@ #ifndef NDEBUG 	static cpBool done = cpFalse; 	if(!done){-		printf("phycs: Initializing new Space, Chipmunk v%s (Debug Enabled)\n", cpVersionString);-		printf("phycs: Compile with the -frelease (cabal) or --flag phycs:release (stack) to disable debug mode and runtime assertion checks\n");+		printf("apecs-physics: Initializing new Space, Chipmunk v%s (Debug Enabled)\n", cpVersionString);+		printf("apecs-physics: Compile with the -frelease (cabal) or --flag apecs-physics:release (stack) to disable debug mode and runtime assertion checks\n"); 		done = cpTrue; 	} #endif
README.md view
@@ -1,16 +1,16 @@-# apecs-physics [![Build Status](https://travis-ci.org/jonascarpay/apecs-physics.svg?branch=master)](https://travis-ci.org/jonascarpay/apecs-physics)+# apecs-physics  2D physics library for apecs.-Uses [Chipmunk](https://github.com/slembcke/Chipmunk2D) for C-speed physics.-The [apecs-physics-gloss](https://github.com/jonascarpay/apecs-physics/tree/master/apecs-physics-gloss) package provides a simple optional [gloss](https://github.com/benl23x5/gloss)-based renderer.+Uses the [Chipmunk](https://github.com/slembcke/Chipmunk2D) physics engine.+The [apecs-gloss](../apecs-gloss) package provides a simple optional [gloss](https://github.com/benl23x5/gloss)-based renderer.  Feel free to create an issue or PR for suggestions/questions/requests/critiques/spelling fixes/etc.-See [TODO.md](https://github.com/jonascarpay/apecs-physics/blob/master/TODO.md) for suggestions if you want to help out with the code.+See [TODO.md](TODO.md) for suggestions if you want to help out with the code.  The examples directory contains a number of examples, each can be run with `stack build && stack <examplename>`:  ### helloworld-![Screenshot](https://raw.githubusercontent.com/jonascarpay/apecs-physics/master/examples/helloworld.png)+![Screenshot](helloworld.png)  ```haskell makeWorld "World" [''Physics, ''BodyPicture, ''Camera]@@ -22,11 +22,11 @@  ```haskell initialize = do-  setGlobal ( Camera (V2 0 1) 60-            , earthGravity )+  set global ( Camera (V2 0 1) 60+             , earthGravity ) ```-`setGlobal` comes from apecs, and is pretty straightforward.-`earthGravity = V2 0 (-9.81)`, normal earth surface gravity if we assume units to be mks.+Globals can be set with any entity argument, `global` is just an alias for -1.+`earthGravity = V2 0 (-9.81)`, normal earth surface gravity if we assume normal MKS units. Note that the positive y-axis points upwards.  ```haskell@@ -75,13 +75,13 @@ You can find its definition in `Apecs.Physics.Gloss`, in case you want to change the rendering behavior.  ### tumbler-![Screenshot](https://raw.githubusercontent.com/jonascarpay/apecs-physics/master/examples/tumbler.png)+![Screenshot](tumbler.png)  ```haskell initialize :: System World () initialize = do-  setGlobal ( Camera 0 50-            , earthGravity )+  set global ( Camera 0 50+             , earthGravity )    let sides = toEdges $ cRectangle 5   tumbler <- newEntity ( KinematicBody@@ -134,7 +134,7 @@ Finally, we randomly add a bunch of balls.  ### constraints-![Screenshot](https://raw.githubusercontent.com/jonascarpay/apecs-physics/master/examples/constraints.png)+![Screenshot](constraints.png)  The final example is a gallery of (some of) the available constraints. Drag shapes around with the left mouse button, create a new box with the right.
apecs-physics.cabal view
@@ -1,5 +1,5 @@ name:                apecs-physics-version:             0.2.0.0+version:             0.3.0 synopsis:            2D physics for apecs description:         2D physics for apecs. Uses Chipmunk physics library under the hood. homepage:            https://github.com/jonascarpay/apecs-physics#readme@@ -45,9 +45,6 @@   Chipmunk2D/include/chipmunk/cpPolyShape.h,   Chipmunk2D/include/chipmunk/cpPivotJoint.h --- source-repository HEAD   type:     git   location: git://github.com/jonascarpay/apecs.git@@ -80,7 +77,7 @@     Apecs.Physics.Query   build-depends:     base >= 4.7 && < 4.13,-    apecs >= 0.5.0.0,+    apecs,     containers,     inline-c,     linear,@@ -88,7 +85,7 @@     vector   ghc-options:     -Wall-    -O2+    -- -O2     -Wno-orphans     -Wno-unused-do-bind     -Wno-name-shadowing
src/Apecs/Physics.hs view
@@ -12,12 +12,12 @@    -- * Body   Body (..), Position (..), Velocity (..), Angle (..), AngularVelocity (..), Force (..),-  BodyMass (..), Moment (..), CenterOfGravity (..), Torque (..),+  BodyMass (..), Moment (..), CenterOfGravity (..), Torque (..), ShapeList (..), ConstraintList (..),    -- * Shape-  Convex (..), Shape (Shape, ShapeExtend),+  Convex (..), Shape (..),   Mass (..), Density (..), Sensor (..), Friction (..), Elasticity (..), SurfaceVelocity (..), CollisionFilter (..),-  maskAll, maskNone, maskList, defaultFilter, boxShape,+  Bitmask (..), maskAll, maskNone, maskList, defaultFilter, boxShape,    -- * Constraint   Constraint (..), ConstraintType (..), MaxForce (..), MaxBias (..), ErrorBias (..), CollideBodies (..),@@ -33,6 +33,7 @@    -- * Geometry   module Apecs.Physics.Geometry,+  BVec, WVec,    module Apecs,   module Linear.V2,
src/Apecs/Physics/Body.hs view
@@ -56,9 +56,6 @@   cpSpaceRemoveBody($(cpSpace* space), body);   cpBodyFree(body); }|] -fromBodyPtr :: Ptr Body -> BodyRecord-fromBodyPtr ptr = BodyRecord ptr mempty mempty- instance Component Body where   type Storage Body = Space Body @@ -69,10 +66,12 @@   explSet (Space bMap _ _ _ spcPtr) ety btype = do     rd <- M.lookup ety <$> readIORef bMap     bdyPtr <- case rd of-                Just (BodyRecord bdyPtr _ _) -> return bdyPtr+                Just (BodyRecord bdyPtr _ _ _) -> return bdyPtr                 Nothing -> do                   bdyPtr <- newBody spcPtr ety-                  modifyIORef' bMap (M.insert ety $ fromBodyPtr bdyPtr)+                  bsMap <- newIORef mempty+                  bcMap <- newIORef mempty+                  modifyIORef' bMap (M.insert ety $ BodyRecord bdyPtr btype bsMap bcMap)                   return bdyPtr     setBodyType bdyPtr btype @@ -80,9 +79,9 @@   explDestroy sp@(Space bMap _ _ _ spc) ety = do     rd <- M.lookup ety <$> readIORef bMap     modifyIORef' bMap (M.delete ety)-    forM_ rd $ \(BodyRecord bPtr shapes constraints) -> do-      forM_ (S.toList shapes) $ \s -> explDestroy (cast sp :: Space Shape) s-      forM_ (S.toList constraints) $ \s -> explDestroy (cast sp :: Space Constraint) s+    forM_ rd $ \(BodyRecord bPtr _ shapes constraints) -> do+      readIORef shapes      >>= mapM_ (explDestroy (cast sp :: Space Shape))      . S.toList+      readIORef constraints >>= mapM_ (explDestroy (cast sp :: Space Constraint)) . S.toList       destroyBody spc bPtr  instance ExplMembers IO (Space Body) where@@ -90,10 +89,9 @@  instance ExplGet IO (Space Body) where   explExists (Space bMap _ _ _ _) ety = M.member ety <$> readIORef bMap-   explGet (Space bMap _ _ _ _) ety = do-    Just (BodyRecord b _ _) <- M.lookup ety <$> readIORef bMap-    getBodyType b+    Just (BodyRecord _ b _ _) <- M.lookup ety <$> readIORef bMap+    return b  -- Position getPosition :: Ptr Body -> IO (V2 Double)@@ -123,12 +121,12 @@ instance ExplSet IO (Space Position) where   explSet (Space bMap _ _ _ _) ety (Position pos) = do     rd <- M.lookup ety <$> readIORef bMap-    forM_ rd$ \(BodyRecord b _ _) -> setPosition b pos+    forM_ rd$ \(BodyRecord b _ _ _) -> setPosition b pos  instance ExplGet IO (Space Position) where   explExists s ety = explExists (cast s :: Space Body) ety   explGet (Space bMap _ _ _ _) ety = do-    Just (BodyRecord b _ _) <- M.lookup ety <$> readIORef bMap+    Just (BodyRecord b _ _ _) <- M.lookup ety <$> readIORef bMap     Position <$> getPosition b  -- Velocity@@ -156,12 +154,12 @@ instance ExplSet IO (Space Velocity) where   explSet (Space bMap _ _ _ _) ety (Velocity vel) = do     rd <- M.lookup ety <$> readIORef bMap-    forM_ rd$ \(BodyRecord b _ _) -> setVelocity b vel+    forM_ rd$ \(BodyRecord b _ _ _) -> setVelocity b vel  instance ExplGet IO (Space Velocity) where   explExists s ety = explExists (cast s :: Space Body) ety   explGet (Space bMap _ _ _ _) ety = do-    Just (BodyRecord b _ _) <- M.lookup ety <$> readIORef bMap+    Just (BodyRecord b _ _ _) <- M.lookup ety <$> readIORef bMap     Velocity <$> getVelocity b  -- Angle@@ -191,12 +189,12 @@ instance ExplSet IO (Space Angle) where   explSet (Space bMap _ _ _ _) ety (Angle angle) = do     rd <- M.lookup ety <$> readIORef bMap-    forM_ rd $ \(BodyRecord b _ _) -> setAngle b angle+    forM_ rd $ \(BodyRecord b _ _ _) -> setAngle b angle  instance ExplGet IO (Space Angle) where   explExists s ety = explExists (cast s :: Space Body) ety   explGet (Space bMap _ _ _ _) ety = do-    Just (BodyRecord b _ _) <- M.lookup ety <$> readIORef bMap+    Just (BodyRecord b _ _ _) <- M.lookup ety <$> readIORef bMap     Angle <$> getAngle b  -- AngularVelocity@@ -226,12 +224,12 @@ instance ExplSet IO (Space AngularVelocity) where   explSet (Space bMap _ _ _ _) ety (AngularVelocity angle) = do     rd <- M.lookup ety <$> readIORef bMap-    forM_ rd $ \(BodyRecord b _ _) -> setAngularVelocity b angle+    forM_ rd $ \(BodyRecord b _ _ _) -> setAngularVelocity b angle  instance ExplGet IO (Space AngularVelocity) where   explExists s ety = explExists (cast s :: Space Body) ety   explGet (Space bMap _ _ _ _) ety = do-    Just (BodyRecord b _ _) <- M.lookup ety <$> readIORef bMap+    Just (BodyRecord b _ _ _) <- M.lookup ety <$> readIORef bMap     AngularVelocity <$> getAngularVelocity b  -- Force@@ -259,12 +257,12 @@ instance ExplSet IO (Space Force) where   explSet (Space bMap _ _ _ _) ety (Force frc) = do     rd <- M.lookup ety <$> readIORef bMap-    forM_ rd$ \(BodyRecord b _ _) -> setForce b frc+    forM_ rd$ \(BodyRecord b _ _ _) -> setForce b frc  instance ExplGet IO (Space Force) where   explExists s ety = explExists (cast s :: Space Body) ety   explGet (Space bMap _ _ _ _) ety = do-    Just (BodyRecord b _ _) <- M.lookup ety <$> readIORef bMap+    Just (BodyRecord b _ _ _) <- M.lookup ety <$> readIORef bMap     Force <$> getForce b  -- BodyMass@@ -294,12 +292,12 @@ instance ExplSet IO (Space BodyMass) where   explSet (Space bMap _ _ _ _) ety (BodyMass angle) = do     rd <- M.lookup ety <$> readIORef bMap-    forM_ rd $ \(BodyRecord b _ _) -> setBodyMass b angle+    forM_ rd $ \(BodyRecord b _ _ _) -> setBodyMass b angle  instance ExplGet IO (Space BodyMass) where   explExists s ety = explExists (cast s :: Space Body) ety   explGet (Space bMap _ _ _ _) ety = do-    Just (BodyRecord b _ _) <- M.lookup ety <$> readIORef bMap+    Just (BodyRecord b _ _ _) <- M.lookup ety <$> readIORef bMap     BodyMass <$> getBodyMass b  -- Moment@@ -329,12 +327,12 @@ instance ExplSet IO (Space Moment) where   explSet (Space bMap _ _ _ _) ety (Moment angle) = do     rd <- M.lookup ety <$> readIORef bMap-    forM_ rd $ \(BodyRecord b _ _) -> setMoment b angle+    forM_ rd $ \(BodyRecord b _ _ _) -> setMoment b angle  instance ExplGet IO (Space Moment) where   explExists s ety = explExists (cast s :: Space Body) ety   explGet (Space bMap _ _ _ _) ety = do-    Just (BodyRecord b _ _) <- M.lookup ety <$> readIORef bMap+    Just (BodyRecord b _ _ _) <- M.lookup ety <$> readIORef bMap     Moment <$> getMoment b  -- Torque@@ -364,12 +362,12 @@ instance ExplSet IO (Space Torque) where   explSet (Space bMap _ _ _ _) ety (Torque angle) = do     rd <- M.lookup ety <$> readIORef bMap-    forM_ rd $ \(BodyRecord b _ _) -> setTorque b angle+    forM_ rd $ \(BodyRecord b _ _ _) -> setTorque b angle  instance ExplGet IO (Space Torque) where   explExists s ety = explExists (cast s :: Space Body) ety   explGet (Space bMap _ _ _ _) ety = do-    Just (BodyRecord b _ _) <- M.lookup ety <$> readIORef bMap+    Just (BodyRecord b _ _ _) <- M.lookup ety <$> readIORef bMap     Torque <$> getTorque b  -- CenterOfGravity@@ -397,11 +395,42 @@ instance ExplSet IO (Space CenterOfGravity) where   explSet (Space bMap _ _ _ _) ety (CenterOfGravity vel) = do     rd <- M.lookup ety <$> readIORef bMap-    forM_ rd$ \(BodyRecord b _ _) -> setCenterOfGravity b vel+    forM_ rd$ \(BodyRecord b _ _ _) -> setCenterOfGravity b vel  instance ExplGet IO (Space CenterOfGravity) where   explExists s ety = explExists (cast s :: Space Body) ety   explGet (Space bMap _ _ _ _) ety = do-    Just (BodyRecord b _ _) <- M.lookup ety <$> readIORef bMap+    Just (BodyRecord b _ _ _) <- M.lookup ety <$> readIORef bMap     CenterOfGravity <$> getCenterOfGravity b +-- ShapeList+instance Component ShapeList where+  type Storage ShapeList = Space ShapeList++instance Has w IO Physics => Has w IO ShapeList where+  getStore = (cast :: Space Physics -> Space ShapeList) <$> getStore++instance ExplMembers IO (Space ShapeList) where+  explMembers s = explMembers (cast s :: Space Body)++instance ExplGet IO (Space ShapeList) where+  explExists s ety = explExists (cast s :: Space Body) ety+  explGet (Space bMap _ _ _ _) ety = do+    Just (BodyRecord _ _ sPtr _) <- M.lookup ety <$> readIORef bMap+    ShapeList . fmap Entity . S.toList <$> readIORef sPtr++-- ConstraintList+instance Component ConstraintList where+  type Storage ConstraintList = Space ConstraintList++instance Has w IO Physics => Has w IO ConstraintList where+  getStore = (cast :: Space Physics -> Space ConstraintList) <$> getStore++instance ExplMembers IO (Space ConstraintList) where+  explMembers s = explMembers (cast s :: Space Body)++instance ExplGet IO (Space ConstraintList) where+  explExists s ety = explExists (cast s :: Space Body) ety+  explGet (Space bMap _ _ _ _) ety = do+    Just (BodyRecord _ _ sPtr _) <- M.lookup ety <$> readIORef bMap+    ConstraintList . fmap Entity . S.toList <$> readIORef sPtr
src/Apecs/Physics/Collision.hs view
@@ -115,17 +115,19 @@   explSet sp@(Space _ _ _ hMap spcPtr) ety handler = do     explDestroy sp ety     hPtr <- newCollisionHandler spcPtr handler ety-    modifyIORef' hMap (M.insert ety hPtr)+    modifyIORef' hMap (M.insert ety (Record hPtr handler))  instance ExplDestroy IO (Space CollisionHandler) where   explDestroy (Space _ _ _ hMap _) ety = do     rd <- M.lookup ety <$> readIORef hMap-    forM_ rd$ \c -> destroyCollisionHandler c >> modifyIORef' hMap (M.delete ety)+    forM_ rd$ \(Record c _) -> destroyCollisionHandler c >> modifyIORef' hMap (M.delete ety)  instance ExplMembers IO (Space CollisionHandler) where   explMembers (Space _ _ _ hMap _) = U.fromList . M.keys <$> readIORef hMap  instance ExplGet IO (Space CollisionHandler) where   explExists (Space _ _ _ hMap _) ety = M.member ety <$> readIORef hMap-  explGet _ _ = return (error "CollisionHandler is a write-only component")+  explGet (Space _ _ _ hMap _) ety = do+    Just (Record _ handler) <- M.lookup ety <$> readIORef hMap+    return handler 
src/Apecs/Physics/Constraint.hs view
@@ -148,10 +148,7 @@   getStore = (cast :: Space Physics -> Space Constraint) <$> getStore  instance ExplSet IO (Space Constraint) where--  explSet _ _ ConstraintRead = return ()-  explSet s ety (Constraint b ctype) = explSet s ety (ConstraintExtend (Entity ety) b ctype)-  explSet sp@(Space bMap _ cMap _ spcPtr) cEty (ConstraintExtend (Entity bEtyA) (Entity bEtyB) ctype) = do+  explSet sp@(Space bMap _ cMap _ spcPtr) cEty cons@(Constraint (Entity bEtyA) (Entity bEtyB) ctype) = do     explDestroy sp cEty     mBrA <- M.lookup bEtyA <$> readIORef bMap     mBrB <- M.lookup bEtyB <$> readIORef bMap@@ -159,30 +156,21 @@       (Just brA, Just brB) -> do         cPtr <- newConstraint spcPtr (brPtr brA) (brPtr brB) cEty ctype -        let brConstraintsA' = S.insert cEty (brConstraints brA)-            brConstraintsB' = S.insert cEty (brConstraints brB)+        modifyIORef' cMap (M.insert cEty (Record cPtr cons))+        modifyIORef' (brConstraints brA) (S.insert cEty)+        modifyIORef' (brConstraints brB) (S.insert cEty) -        modifyIORef' cMap (M.insert cEty cPtr)-        modifyIORef' bMap ( M.insert bEtyA (brA {brConstraints = brConstraintsA'})-                          . M.insert bEtyB (brB {brConstraints = brConstraintsB'}) )       _ -> return ()  instance ExplDestroy IO (Space Constraint) where   explDestroy (Space bMap _ cMap _ spc) cEty = do     rd <- M.lookup cEty <$> readIORef cMap-    forM_ rd $ \cPtr -> do-      bEtyA <- getBodyA cPtr-      bEtyB <- getBodyB cPtr-      bMapRd <- readIORef bMap--      let Just bRecA = M.lookup bEtyA bMapRd-          Just bRecB = M.lookup bEtyB bMapRd-          brConstraintsA' = S.delete cEty (brConstraints bRecA)-          brConstraintsB' = S.delete cEty (brConstraints bRecB)--      modifyIORef' cMap (M.delete cEty)-      modifyIORef' bMap ( M.insert bEtyA (bRecA {brConstraints = brConstraintsA'})-                        . M.insert bEtyB (bRecB {brConstraints = brConstraintsB'}) )+    forM_ rd $ \(Record cPtr (Constraint (Entity bEtyA) (Entity bEtyB) _)) -> do+      bMap' <- readIORef bMap+      let rmConstraint ref = modifyIORef' (brConstraints ref) (S.delete cEty)+      mapM_ rmConstraint (M.lookup bEtyA bMap')+      mapM_ rmConstraint (M.lookup bEtyB bMap')+      modifyIORef' cMap $ M.delete cEty       destroyConstraint spc cPtr  instance ExplMembers IO (Space Constraint) where@@ -190,23 +178,13 @@  instance ExplGet IO (Space Constraint) where   explExists (Space _ _ cMap _ _) ety = M.member ety <$> readIORef cMap--  explGet _ _ = return ConstraintRead---- BodyAB-getBodyA :: Ptr Constraint -> IO Int-getBodyA c = fromIntegral <$> [C.exp| intptr_t {-  (intptr_t) cpBodyGetUserData(cpConstraintGetBodyA($(cpConstraint* c))) }|]--getBodyB :: Ptr Constraint -> IO Int-getBodyB c = fromIntegral <$> [C.exp| intptr_t {-  (intptr_t) cpBodyGetUserData(cpConstraintGetBodyB($(cpConstraint* c))) }|]+  explGet    (Space _ _ cMap _ _) ety = do+    Just (Record _ cons)  <- M.lookup ety <$> readIORef cMap+    return cons  -- MaxForce getMaxForce :: Ptr Constraint -> IO Double-getMaxForce c = do-  maxForce <- [C.exp| double { cpConstraintGetMaxForce ($(cpConstraint* c)) } |]-  return (realToFrac maxForce)+getMaxForce c = realToFrac <$> [C.exp| double { cpConstraintGetMaxForce ($(cpConstraint* c)) } |]  setMaxForce :: Ptr Constraint -> Double -> IO () setMaxForce c (realToFrac -> maxForce) = [C.exp| void { cpConstraintSetMaxForce($(cpConstraint* c), $(double maxForce)); } |]@@ -225,12 +203,12 @@     rd <- M.lookup ety <$> readIORef cMap     case rd of       Nothing -> return ()-      Just c  -> setMaxForce c vec+      Just (Record c _) -> setMaxForce c vec  instance ExplGet IO (Space MaxForce) where   explExists s ety = explExists (cast s :: Space Constraint) ety   explGet (Space _ _ cMap _ _) ety = do-    Just c <- M.lookup ety <$> readIORef cMap+    Just (Record c _) <- M.lookup ety <$> readIORef cMap     MaxForce <$> getMaxForce c  -- MaxBias@@ -256,11 +234,11 @@     rd <- M.lookup ety <$> readIORef cMap     case rd of       Nothing -> return ()-      Just c  -> setMaxBias c vec+      Just (Record c _) -> setMaxBias c vec  instance ExplGet IO (Space MaxBias) where   explGet (Space _ _ cMap _ _) ety = do-    Just c <- M.lookup ety <$> readIORef cMap+    Just (Record c _) <- M.lookup ety <$> readIORef cMap     MaxBias <$> getMaxBias c   explExists s ety = explExists (cast s :: Space Constraint) ety @@ -287,12 +265,12 @@     rd <- M.lookup ety <$> readIORef cMap     case rd of       Nothing -> return ()-      Just c  -> setErrorBias c vec+      Just (Record c _) -> setErrorBias c vec  instance ExplGet IO (Space ErrorBias) where   explExists s ety = explExists (cast s :: Space Constraint) ety   explGet (Space _ _ cMap _ _) ety = do-    Just c <- M.lookup ety <$> readIORef cMap+    Just (Record c _) <- M.lookup ety <$> readIORef cMap     ErrorBias <$> getErrorBias c  -- CollideBodies@@ -318,10 +296,10 @@     rd <- M.lookup ety <$> readIORef cMap     case rd of       Nothing -> return ()-      Just c  -> setCollideBodies c vec+      Just (Record c _) -> setCollideBodies c vec  instance ExplGet IO (Space CollideBodies) where   explExists s ety = explExists (cast s :: Space Constraint) ety   explGet (Space _ _ cMap _ _) ety = do-    Just c <- M.lookup ety <$> readIORef cMap+    Just (Record c _) <- M.lookup ety <$> readIORef cMap     CollideBodies <$> getCollideBodies c
src/Apecs/Physics/Shape.hs view
@@ -35,6 +35,7 @@ maskAll, maskNone :: Bitmask maskAll  = complement zeroBits maskNone = zeroBits+-- | Makes a bitmask from a list of indices maskList :: [Int] -> Bitmask maskList = foldr (flip setBit) maskNone @@ -63,31 +64,25 @@ instance ExplDestroy IO (Space Shape) where   explDestroy (Space bMap sMap _ _ spc) sEty = do     rd <- M.lookup sEty <$> readIORef sMap-    forM_ rd $ \sPtr -> do-      bEty <- fromIntegral <$> getShapeBody sPtr--      Just bRec <- M.lookup bEty <$> readIORef bMap-      let brShapes' = S.delete sEty (brShapes bRec)-+    forM_ rd $ \(Record sPtr (Shape (Entity bEty) _)) -> do+      rd <- M.lookup bEty <$> readIORef bMap+      forM_ rd $ \bRec -> modifyIORef' (brShapes bRec) (S.delete sEty)       modifyIORef' sMap (M.delete sEty)-      modifyIORef' bMap (M.insert bEty (bRec {brShapes = brShapes'}))       destroyShape spc sPtr  instance ExplSet IO (Space Shape) where-  explSet _ _ ShapeRead = return ()-  explSet sp ety (Shape sh) = explSet sp ety (ShapeExtend (Entity ety) sh)--  explSet sp@(Space bMap sMap _ _ spcPtr) sEty (ShapeExtend (Entity bEty) sh) = do+  explSet sp@(Space bMap sMap _ _ spcPtr) sEty shape@(Shape (Entity bEty) sh) = do     explDestroy sp sEty     rd <- M.lookup bEty <$> readIORef bMap     forM_ rd $ \bRec -> do-      s <- newShape spcPtr (brPtr bRec) sh sEty-      let brShapes' = S.insert sEty (brShapes bRec)-      modifyIORef' bMap (M.insert bEty (bRec {brShapes = brShapes'}))-      modifyIORef' sMap (M.insert sEty s)+      shPtr <- newShape spcPtr (brPtr bRec) sh sEty+      modifyIORef' (brShapes bRec) (S.insert sEty)+      modifyIORef' sMap (M.insert sEty (Record shPtr shape))  instance ExplGet IO (Space Shape) where-  explGet _ _ = return ShapeRead+  explGet    (Space _ sMap _ _ _) ety = do+    Just (Record _ s) <- M.lookup ety <$> readIORef sMap+    return s   explExists (Space _ sMap _ _ _) ety = M.member ety <$> readIORef sMap  newShape :: SpacePtr -> Ptr Body -> Convex -> Int -> IO (Ptr Shape)@@ -146,12 +141,12 @@ instance ExplSet IO (Space Sensor) where   explSet (Space _ sMap _ _ _) ety (Sensor vec) = do     rd <- M.lookup ety <$> readIORef sMap-    forM_ rd$ \s -> setSensor s vec+    forM_ rd$ \(Record s _) -> setSensor s vec  instance ExplGet IO (Space Sensor) where   explExists s ety = explExists (cast s :: Space Shape) ety   explGet (Space _ sMap _ _ _) ety = do-    Just s <- M.lookup ety <$> readIORef sMap+    Just (Record s _) <- M.lookup ety <$> readIORef sMap     Sensor <$> getSensor s  -- Elasticity@@ -174,12 +169,12 @@ instance ExplSet IO (Space Elasticity) where   explSet (Space _ sMap _ _ _) ety (Elasticity vec) = do     rd <- M.lookup ety <$> readIORef sMap-    forM_ rd$ \s -> setElasticity s vec+    forM_ rd$ \(Record s _) -> setElasticity s vec  instance ExplGet IO (Space Elasticity) where   explExists s ety = explExists (cast s :: Space Shape) ety   explGet (Space _ sMap _ _ _) ety = do-    Just s <- M.lookup ety <$> readIORef sMap+    Just (Record s _) <- M.lookup ety <$> readIORef sMap     Elasticity <$> getElasticity s  -- Mass@@ -202,12 +197,12 @@ instance ExplSet IO (Space Mass) where   explSet (Space _ sMap _ _ _) ety (Mass vec) = do     rd <- M.lookup ety <$> readIORef sMap-    forM_ rd$ \s -> setMass s vec+    forM_ rd$ \(Record s _) -> setMass s vec  instance ExplGet IO (Space Mass) where   explExists s ety = explExists (cast s :: Space Shape) ety   explGet (Space _ sMap _ _ _) ety = do-    Just s <- M.lookup ety <$> readIORef sMap+    Just (Record s _) <- M.lookup ety <$> readIORef sMap     Mass <$> getMass s  -- Density@@ -230,12 +225,12 @@ instance ExplSet IO (Space Density) where   explSet (Space _ sMap _ _ _) ety (Density vec) = do     rd <- M.lookup ety <$> readIORef sMap-    forM_ rd$ \s -> setDensity s vec+    forM_ rd$ \(Record s _) -> setDensity s vec  instance ExplGet IO (Space Density) where   explExists s ety = explExists (cast s :: Space Shape) ety   explGet (Space _ sMap _ _ _) ety = do-    Just s <- M.lookup ety <$> readIORef sMap+    Just (Record s _) <- M.lookup ety <$> readIORef sMap     Density <$> getDensity s  -- Friction@@ -258,12 +253,12 @@ instance ExplSet IO (Space Friction) where   explSet (Space _ sMap _ _ _) ety (Friction vec) = do     rd <- M.lookup ety <$> readIORef sMap-    forM_ rd$ \s -> setFriction s vec+    forM_ rd$ \(Record s _) -> setFriction s vec  instance ExplGet IO (Space Friction) where   explExists s ety = explExists (cast s :: Space Shape) ety   explGet (Space _ sMap _ _ _) ety = do-    Just s <- M.lookup ety <$> readIORef sMap+    Just (Record s _) <- M.lookup ety <$> readIORef sMap     Friction <$> getFriction s  -- SurfaceVelocity@@ -290,12 +285,12 @@ instance ExplSet IO (Space SurfaceVelocity) where   explSet (Space _ sMap _ _ _) ety (SurfaceVelocity vec) = do     rd <- M.lookup ety <$> readIORef sMap-    forM_ rd$ \s -> setSurfaceVelocity s vec+    forM_ rd$ \(Record s _) -> setSurfaceVelocity s vec  instance ExplGet IO (Space SurfaceVelocity) where   explExists s ety = explExists (cast s :: Space Shape) ety   explGet (Space _ sMap _ _ _) ety = do-    Just s <- M.lookup ety <$> readIORef sMap+    Just (Record s _) <- M.lookup ety <$> readIORef sMap     SurfaceVelocity <$> getSurfaceVelocity s  -- CollisionFilter@@ -326,12 +321,12 @@ instance ExplSet IO (Space CollisionFilter) where   explSet (Space _ sMap _ _ _) ety cfilter = do     rd <- M.lookup ety <$> readIORef sMap-    forM_ rd$ \s -> setFilter s cfilter+    forM_ rd$ \(Record s _) -> setFilter s cfilter  instance ExplGet IO (Space CollisionFilter) where   explExists s ety = explExists (cast s :: Space Shape) ety   explGet (Space _ sMap _ _ _) ety = do-    Just s <- M.lookup ety <$> readIORef sMap+    Just (Record s _) <- M.lookup ety <$> readIORef sMap     getFilter s  -- CollisionType@@ -354,29 +349,10 @@ instance ExplSet IO (Space CollisionType) where   explSet (Space _ sMap _ _ _) ety (CollisionType vec) = do     rd <- M.lookup ety <$> readIORef sMap-    forM_ rd$ \s -> setCollisionType s vec+    forM_ rd$ \(Record s _) -> setCollisionType s vec  instance ExplGet IO (Space CollisionType) where   explExists s ety = explExists (cast s :: Space Shape) ety   explGet (Space _ sMap _ _ _) ety = do-    Just s <- M.lookup ety <$> readIORef sMap+    Just (Record s _) <- M.lookup ety <$> readIORef sMap     CollisionType <$> getCollisionType s---- ShapeBody-getShapeBody :: Ptr Shape -> IO C.CUIntPtr-getShapeBody shape = [C.exp| uintptr_t {-  (intptr_t) cpBodyGetUserData(cpShapeGetBody($(cpShape* shape))) }|]--instance Component ShapeBody where-  type Storage ShapeBody = Space ShapeBody-instance Has w IO Physics => Has w IO ShapeBody where-  getStore = (cast :: Space Physics -> Space ShapeBody) <$> getStore--instance ExplMembers IO (Space ShapeBody) where-  explMembers s = explMembers (cast s :: Space Shape)--instance ExplGet IO (Space ShapeBody) where-  explExists s ety = explExists (cast s :: Space Shape) ety-  explGet (Space _ sMap _ _ _) ety = do-    Just s <- M.lookup ety <$> readIORef sMap-    ShapeBody . Entity . fromIntegral <$> getShapeBody s
src/Apecs/Physics/Types.hs view
@@ -49,7 +49,7 @@   , (C.TypeName "cpSpace",            [t| FrnSpace         |])   ] --- | Uninhabited data type for constructing a world with a chipmunk space.+-- | Uninhabited, should be added to the world as a component to add a physics space. data Physics  -- | Vector type used by the library@@ -75,11 +75,14 @@ newtype AngularVelocity = AngularVelocity Double newtype CenterOfGravity = CenterOfGravity BVec +-- | The @Shape@s belonging to a body. Read-only.+newtype ShapeList = ShapeList [Entity]+-- | The @Constraint@s belonging to a body. Read-only.+newtype ConstraintList = ConstraintList [Entity]+ -- | Shape component. --   Adding a shape to an entity that has no @Body@ is a noop.-data Shape = Shape Convex-           | ShapeExtend Entity Convex-           | ShapeRead -- ^ Shapes are write-only, this is returned when you attempt to read+data Shape = Shape Entity Convex  -- | A convex polygon. --   Consists of a list of vertices, and a radius.@@ -92,7 +95,6 @@ newtype Friction        = Friction        Double     deriving (Eq, Show) newtype SurfaceVelocity = SurfaceVelocity Vec        deriving (Eq, Show) newtype CollisionType   = CollisionType   C.CUIntPtr deriving (Eq, Show)-newtype ShapeBody       = ShapeBody       Entity     deriving (Eq, Show)  type CollisionGroup = CUInt @@ -102,18 +104,19 @@   , filterMask       :: Bitmask   } deriving (Eq, Show) +-- | A bitmask used for collision handling newtype Bitmask = Bitmask CUInt deriving (Eq, Bits) instance Show Bitmask where-  show (Bitmask mask) = "Bitmask " ++ showIntAtBase 2 intToDigit mask ""+  show (Bitmask mask) = "Bitmask 0b" ++ showIntAtBase 2 intToDigit mask ""  data FrnSpace data FrnVec  data Space c = Space   { spBodies      :: IOMap BodyRecord-  , spShapes      :: PtrMap Shape-  , spConstraints :: PtrMap Constraint-  , spHandlers    :: PtrMap CollisionHandler+  , spShapes      :: IOMap (Record Shape)+  , spConstraints :: IOMap (Record Constraint)+  , spHandlers    :: IOMap (Record CollisionHandler)   , spacePtr      :: SpacePtr   } @@ -121,54 +124,59 @@  data BodyRecord = BodyRecord   { brPtr         :: Ptr Body-  , brShapes      :: S.IntSet-  , brConstraints :: S.IntSet+  , brBody        :: Body+  , brShapes      :: IORef S.IntSet+  , brConstraints :: IORef S.IntSet   } +data Record a = Record+  { recPtr :: Ptr a+  , recVal :: a+  }+ type IOMap a = IORef (M.IntMap a) type PtrMap a = IOMap (Ptr a) type SpacePtr = ForeignPtr FrnSpace  -- | Number of iterations per step, global value-newtype Iterations = Iterations Int+newtype Iterations = Iterations Int deriving (Eq, Show) -- | Gravity force vector, global value newtype Gravity = Gravity Vec deriving (Eq, Show) -- | Daming factor, global value-newtype Damping = Damping Double+newtype Damping = Damping Double deriving (Eq, Show) -- | Speed threshold to be considered idle, and a candidate for being put to sleep. Global value-newtype IdleSpeedThreshold = IdleSpeedThreshold Double+newtype IdleSpeedThreshold = IdleSpeedThreshold Double deriving (Eq, Show) -- | Sleep idle time threshold, global value-newtype SleepIdleTime = SleepIdleTime Double+newtype SleepIdleTime = SleepIdleTime Double deriving (Eq, Show) -- | Collision parameter, global value-newtype CollisionSlop = CollisionSlop Double+newtype CollisionSlop = CollisionSlop Double deriving (Eq, Show) -- | Collision parameter, global value-newtype CollisionBias = CollisionBias Double+newtype CollisionBias = CollisionBias Double deriving (Eq, Show)  cast :: Space a -> Space b cast (Space b s c h w) = Space b s c h w  -- Constraint subcomponents-newtype MaxForce      = MaxForce      Double-newtype MaxBias       = MaxBias       Double-newtype ErrorBias     = ErrorBias     Double-newtype CollideBodies = CollideBodies Bool+newtype MaxForce      = MaxForce      Double deriving (Eq, Show)+newtype MaxBias       = MaxBias       Double deriving (Eq, Show)+newtype ErrorBias     = ErrorBias     Double deriving (Eq, Show)+newtype CollideBodies = CollideBodies Bool   deriving (Eq, Show) -data Constraint = Constraint Entity ConstraintType-                | ConstraintExtend Entity Entity ConstraintType-                | ConstraintRead+data Constraint = Constraint Entity Entity ConstraintType deriving (Eq, Show)  data ConstraintType   = PinJoint BVec BVec -- ^ Maintains a fixed distance between two anchor points-  | SlideJoint BVec BVec Double Double -- offsetA offsetB min max+  | SlideJoint BVec BVec Double Double -- ^ A @PinJoint@ with minimum and maximum distance   | PivotJoint WVec -- ^ Creates a pivot point at the given world coordinate   | PivotJoint2 BVec BVec -- ^ Creates a pivot point at the given body coordinates-  | GrooveJoint BVec BVec BVec-  | DampedSpring BVec BVec Double Double Double -- offA offB restlength stiffness damping-  | DampedRotarySpring Double Double Double -- restAngle stiffness damping-  | RotaryLimitJoint Double Double -- min max-  | RatchetJoint Double Double -- phase ratchet-  | GearJoint Double Double -- phase ratio-  | SimpleMotor Double -- rate+  | GrooveJoint BVec BVec BVec -- ^ The first two vectors are the start and end of the groove on body A, the third argument is the anchor point on body B.+  | DampedSpring BVec BVec Double Double Double -- ^ Spring between two anchor points, with given rest length, stiffness, and damping.+  | DampedRotarySpring Double Double Double -- ^ Rotary sping, with given rest angle, stiffness, and damping.+  | RotaryLimitJoint Double Double -- ^ Joint with minimum and maximum angle+  | RatchetJoint Double Double -- ^ Rathet joint with given phase and ratchet (distance between clicks).+  | GearJoint Double Double -- Keeps angular velocity ratio constant. The first argument is phase, the initial offset, the second argument is the ratio+  | SimpleMotor Double -- ^ Keeps relative angular velocity constant+  deriving (Eq, Show)  -- TODO -- getConstraintImpulse@@ -225,4 +233,3 @@   , pqDistance :: Double   , pqGradient :: Double   } deriving (Eq, Show)-