Box3D-0.1.0.0: src/Box3D/DynamicTree.hsc
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- Produced by boxnd-gen; edit the generator, not this file.
module Box3D.DynamicTree
( TreeStats (..)
, DynamicTree (..)
, TreeNodeChildren (..)
, TreeNodeFlags (..)
, pattern AllocatedNode
, pattern EnlargedNode
, pattern LeafNode
, dynamicTreeByteCount
, create
, destroy
, createProxy
, destroyProxy
, moveProxy
, enlargeProxy
, setCategoryBits
, getCategoryBits
, query
, queryClosest
, rayCast
, boxCast
, boxCastInto
, getHeight
, getAreaRatio
, getRootBounds
, getRootBoundsInto
, getProxyCount
, rebuild
, getByteCount
, validate
, validateNoEnlarged
, save
, load
)
where
import Foreign
import Foreign.C.Types (CBool (..), CInt (..))
import Foreign.C.String (CString)
import Box3D.MathTypes (AABB, Vec3)
import Box3D.Query (BoxCastInput, RayCastInput)
import Box3D.Tags (TreeBoxCastCallbackFcn, TreeNode, TreeQueryCallbackFcn, TreeQueryClosestCallbackFcn, TreeRayCastCallbackFcn)
#include "box3d/box3d.h"
-- | These are performance results returned by dynamic tree queries.
data TreeStats = TreeStats
{ nodeVisits :: CInt
-- ^ Number of internal nodes visited during the query
, leafVisits :: CInt
-- ^ Number of leaf nodes visited during the query
}
deriving (Eq, Show)
instance Storable TreeStats where
sizeOf _ = #{size b3TreeStats}
alignment _ = #{alignment b3TreeStats}
peek p =
TreeStats
<$> #{peek b3TreeStats, nodeVisits} p
<*> #{peek b3TreeStats, leafVisits} p
poke p (TreeStats f1 f2) = do
#{poke b3TreeStats, nodeVisits} p f1
#{poke b3TreeStats, leafVisits} p f2
{- | The dynamic tree structure. This should be considered private data.
It is placed here for performance reasons.
-}
data DynamicTree = DynamicTree
{ version :: Word64
-- ^ The dynamic tree version. Always the first field. Useful
-- if the tree is serialized.
, nodes :: Ptr TreeNode
-- ^ The tree nodes
, root :: CInt
-- ^ The root index
, nodeCount :: CInt
-- ^ The number of nodes
, nodeCapacity :: CInt
-- ^ The allocated node space
, proxyCount :: CInt
-- ^ Number of proxies created
, freeList :: CInt
-- ^ Node free list
, leafIndices :: Ptr ()
-- ^ Leaf indices for rebuild
, leafBoxes :: Ptr AABB
-- ^ Leaf bounding boxes for rebuild
, leafCenters :: Ptr Vec3
-- ^ Leaf bounding box centers for rebuild
, binIndices :: Ptr ()
-- ^ Bins for sorting during rebuild
, rebuildCapacity :: CInt
-- ^ Allocated space for rebuilding
}
deriving (Eq, Show)
instance Storable DynamicTree where
sizeOf _ = #{size b3DynamicTree}
alignment _ = #{alignment b3DynamicTree}
peek p =
DynamicTree
<$> #{peek b3DynamicTree, version} p
<*> #{peek b3DynamicTree, nodes} p
<*> #{peek b3DynamicTree, root} p
<*> #{peek b3DynamicTree, nodeCount} p
<*> #{peek b3DynamicTree, nodeCapacity} p
<*> #{peek b3DynamicTree, proxyCount} p
<*> #{peek b3DynamicTree, freeList} p
<*> #{peek b3DynamicTree, leafIndices} p
<*> #{peek b3DynamicTree, leafBoxes} p
<*> #{peek b3DynamicTree, leafCenters} p
<*> #{peek b3DynamicTree, binIndices} p
<*> #{peek b3DynamicTree, rebuildCapacity} p
poke p (DynamicTree f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12) = do
#{poke b3DynamicTree, version} p f1
#{poke b3DynamicTree, nodes} p f2
#{poke b3DynamicTree, root} p f3
#{poke b3DynamicTree, nodeCount} p f4
#{poke b3DynamicTree, nodeCapacity} p f5
#{poke b3DynamicTree, proxyCount} p f6
#{poke b3DynamicTree, freeList} p f7
#{poke b3DynamicTree, leafIndices} p f8
#{poke b3DynamicTree, leafBoxes} p f9
#{poke b3DynamicTree, leafCenters} p f10
#{poke b3DynamicTree, binIndices} p f11
#{poke b3DynamicTree, rebuildCapacity} p f12
-- | Tree node child indices. For internal usage.
data TreeNodeChildren = TreeNodeChildren
{ child1 :: CInt
-- ^ child node index 1
, child2 :: CInt
-- ^ child node index 2
}
deriving (Eq, Show)
instance Storable TreeNodeChildren where
sizeOf _ = #{size b3TreeNodeChildren}
alignment _ = #{alignment b3TreeNodeChildren}
peek p =
TreeNodeChildren
<$> #{peek b3TreeNodeChildren, child1} p
<*> #{peek b3TreeNodeChildren, child2} p
poke p (TreeNodeChildren f1 f2) = do
#{poke b3TreeNodeChildren, child1} p f1
#{poke b3TreeNodeChildren, child2} p f2
-- | Flags for tree nodes. For internal usage.
newtype TreeNodeFlags = TreeNodeFlags CInt
deriving (Eq, Show, Storable)
pattern AllocatedNode :: TreeNodeFlags
pattern EnlargedNode :: TreeNodeFlags
pattern LeafNode :: TreeNodeFlags
pattern AllocatedNode = TreeNodeFlags #{const b3_allocatedNode}
pattern EnlargedNode = TreeNodeFlags #{const b3_enlargedNode}
pattern LeafNode = TreeNodeFlags #{const b3_leafNode}
dynamicTreeByteCount :: Int
dynamicTreeByteCount = #{size b3DynamicTree}
foreign import ccall unsafe "hsg_b3DynamicTree_Create"
c_b3DynamicTree_Create :: CInt -> Ptr DynamicTree -> IO ()
foreign import ccall unsafe "b3DynamicTree_Destroy"
c_b3DynamicTree_Destroy :: Ptr DynamicTree -> IO ()
foreign import ccall unsafe "hsg_b3DynamicTree_CreateProxy"
c_b3DynamicTree_CreateProxy :: Ptr DynamicTree -> Ptr AABB -> Word64 -> Word64 -> IO CInt
foreign import ccall unsafe "b3DynamicTree_DestroyProxy"
c_b3DynamicTree_DestroyProxy :: Ptr DynamicTree -> CInt -> IO ()
foreign import ccall unsafe "hsg_b3DynamicTree_MoveProxy"
c_b3DynamicTree_MoveProxy :: Ptr DynamicTree -> CInt -> Ptr AABB -> IO ()
foreign import ccall unsafe "hsg_b3DynamicTree_EnlargeProxy"
c_b3DynamicTree_EnlargeProxy :: Ptr DynamicTree -> CInt -> Ptr AABB -> IO ()
foreign import ccall unsafe "b3DynamicTree_SetCategoryBits"
c_b3DynamicTree_SetCategoryBits :: Ptr DynamicTree -> CInt -> Word64 -> IO ()
foreign import ccall unsafe "b3DynamicTree_GetCategoryBits"
c_b3DynamicTree_GetCategoryBits :: Ptr DynamicTree -> CInt -> IO Word64
foreign import ccall safe "hsg_b3DynamicTree_Query"
c_b3DynamicTree_Query :: Ptr DynamicTree -> Ptr AABB -> Word64 -> CBool -> FunPtr TreeQueryCallbackFcn -> Ptr () -> Ptr TreeStats -> IO ()
foreign import ccall safe "hsg_b3DynamicTree_QueryClosest"
c_b3DynamicTree_QueryClosest :: Ptr DynamicTree -> Ptr Vec3 -> Word64 -> CBool -> FunPtr TreeQueryClosestCallbackFcn -> Ptr () -> Ptr Float -> Ptr TreeStats -> IO ()
foreign import ccall safe "hsg_b3DynamicTree_RayCast"
c_b3DynamicTree_RayCast :: Ptr DynamicTree -> Ptr RayCastInput -> Word64 -> CBool -> FunPtr TreeRayCastCallbackFcn -> Ptr () -> Ptr TreeStats -> IO ()
foreign import ccall safe "hsg_b3DynamicTree_BoxCast"
c_b3DynamicTree_BoxCast :: Ptr DynamicTree -> Ptr BoxCastInput -> Word64 -> CBool -> FunPtr TreeBoxCastCallbackFcn -> Ptr () -> Ptr TreeStats -> IO ()
foreign import ccall unsafe "b3DynamicTree_GetHeight"
c_b3DynamicTree_GetHeight :: Ptr DynamicTree -> IO CInt
foreign import ccall unsafe "b3DynamicTree_GetAreaRatio"
c_b3DynamicTree_GetAreaRatio :: Ptr DynamicTree -> IO Float
foreign import ccall unsafe "hsg_b3DynamicTree_GetRootBounds"
c_b3DynamicTree_GetRootBounds :: Ptr DynamicTree -> Ptr AABB -> IO ()
foreign import ccall unsafe "b3DynamicTree_GetProxyCount"
c_b3DynamicTree_GetProxyCount :: Ptr DynamicTree -> IO CInt
foreign import ccall unsafe "b3DynamicTree_Rebuild"
c_b3DynamicTree_Rebuild :: Ptr DynamicTree -> CBool -> IO CInt
foreign import ccall unsafe "b3DynamicTree_GetByteCount"
c_b3DynamicTree_GetByteCount :: Ptr DynamicTree -> IO CInt
foreign import ccall unsafe "b3DynamicTree_Validate"
c_b3DynamicTree_Validate :: Ptr DynamicTree -> IO ()
foreign import ccall unsafe "b3DynamicTree_ValidateNoEnlarged"
c_b3DynamicTree_ValidateNoEnlarged :: Ptr DynamicTree -> IO ()
foreign import ccall unsafe "b3DynamicTree_Save"
c_b3DynamicTree_Save :: Ptr DynamicTree -> CString -> IO ()
foreign import ccall unsafe "hsg_b3DynamicTree_Load"
c_b3DynamicTree_Load :: CString -> Float -> Ptr DynamicTree -> IO ()
{- | Constructing the tree initializes the node pool.
Binds @b3DynamicTree_Create@.
-}
create
:: Int
-- ^ @proxyCapacity@
-> Ptr DynamicTree
-- ^ Result buffer.
-> IO ()
create a0 out =
c_b3DynamicTree_Create (fromIntegral a0) out
{- | Destroy the tree, freeing the node pool.
Binds @b3DynamicTree_Destroy@.
-}
destroy
:: Ptr DynamicTree
-> IO ()
destroy a0 =
c_b3DynamicTree_Destroy a0
{- | Create a proxy. Provide an AABB and a userData value.
Binds @b3DynamicTree_CreateProxy@.
-}
createProxy
:: Ptr DynamicTree
-> AABB
-> Word64
-- ^ @categoryBits@
-> Word64
-- ^ @userData@
-> IO Int
createProxy a0 a1 a2 a3 =
with a1 $ \p1 ->
fromIntegral <$> (c_b3DynamicTree_CreateProxy a0 p1 a2 a3)
{- | Destroy a proxy. This asserts if the id is invalid.
Binds @b3DynamicTree_DestroyProxy@.
-}
destroyProxy
:: Ptr DynamicTree
-> Int
-- ^ @proxyId@
-> IO ()
destroyProxy a0 a1 =
c_b3DynamicTree_DestroyProxy a0 (fromIntegral a1)
{- | Move a proxy to a new AABB by removing and reinserting into the tree.
Binds @b3DynamicTree_MoveProxy@.
-}
moveProxy
:: Ptr DynamicTree
-> Int
-- ^ @proxyId@
-> AABB
-> IO ()
moveProxy a0 a1 a2 =
with a2 $ \p2 ->
c_b3DynamicTree_MoveProxy a0 (fromIntegral a1) p2
{- | Enlarge a proxy and enlarge ancestors as necessary.
Binds @b3DynamicTree_EnlargeProxy@.
-}
enlargeProxy
:: Ptr DynamicTree
-> Int
-- ^ @proxyId@
-> AABB
-> IO ()
enlargeProxy a0 a1 a2 =
with a2 $ \p2 ->
c_b3DynamicTree_EnlargeProxy a0 (fromIntegral a1) p2
{- | Modify the category bits on a proxy. This is an expensive operation.
Binds @b3DynamicTree_SetCategoryBits@.
-}
setCategoryBits
:: Ptr DynamicTree
-> Int
-- ^ @proxyId@
-> Word64
-- ^ @categoryBits@
-> IO ()
setCategoryBits a0 a1 a2 =
c_b3DynamicTree_SetCategoryBits a0 (fromIntegral a1) a2
{- | Get the category bits on a proxy.
Binds @b3DynamicTree_GetCategoryBits@.
-}
getCategoryBits
:: Ptr DynamicTree
-> Int
-- ^ @proxyId@
-> IO Word64
getCategoryBits a0 a1 =
c_b3DynamicTree_GetCategoryBits a0 (fromIntegral a1)
{- | Query an AABB for overlapping proxies. The callback function is called for each proxy that overlaps the supplied AABB.
Returns: performance data
Binds @b3DynamicTree_Query@.
-}
query
:: Ptr DynamicTree
-> AABB
-> Word64
-- ^ @maskBits@
-> Bool
-- ^ @requireAllBits@
-> FunPtr TreeQueryCallbackFcn
-> Ptr ()
-- ^ @context@
-> IO TreeStats
query a0 a1 a2 a3 a4 a5 =
with a1 $ \p1 ->
alloca $ \pOut -> c_b3DynamicTree_Query a0 p1 a2 (fromBool a3) a4 a5 pOut >> peek pOut
{- | Query an AABB for the closest object. The callback function is called for each proxy that might be closest to the supplied
point.
Returns: performance data
Binds @b3DynamicTree_QueryClosest@.
-}
queryClosest
:: Ptr DynamicTree
-- ^ @tree@: the dynamic tree to query
-> Vec3
-- ^ @point@: the query point
-> Word64
-- ^ @maskBits@: nodes are skipped if the bit-wise AND with the node category bits is zero
-> Bool
-- ^ @requireAllBits@: nodes are skipped if the bit-wise AND with the node category bits does not equal the maskBits
-> FunPtr TreeQueryClosestCallbackFcn
-- ^ @callback@: a user provided instance of @b3TreeQueryClosestCallbackFcn@
-> Ptr ()
-- ^ @context@: a user context object that is provided to the callback
-> Ptr Float
-- ^ @minDistanceSqr@: the initial and final minimum squared distance. Provide a small initial to restrict the search and improve performance. If the value is large this query has performance that scales linearly with the number of proxies and would be slower than a brute force search.
-> IO TreeStats
queryClosest a0 a1 a2 a3 a4 a5 a6 =
with a1 $ \p1 ->
alloca $ \pOut -> c_b3DynamicTree_QueryClosest a0 p1 a2 (fromBool a3) a4 a5 a6 pOut >> peek pOut
{- | Ray cast against the proxies in the tree. This relies on the callback
to perform an exact ray cast in the case where the proxy contains a shape.
The callback also performs any collision filtering. This has performance
roughly equal to k * log(n), where k is the number of collisions and n is the
number of proxies in the tree.
Bit-wise filtering using mask bits can greatly improve performance in some scenarios.
However, this filtering may be approximate, so the user should still apply filtering to results.
Returns: performance data
Binds @b3DynamicTree_RayCast@.
-}
rayCast
:: Ptr DynamicTree
-- ^ @tree@: the dynamic tree to ray cast
-> RayCastInput
-- ^ @input@: the ray cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1)
-> Word64
-- ^ @maskBits@: bit mask test: \`bool accept = (maskBits & node-\>categoryBits) != 0;\`
-> Bool
-- ^ @requireAllBits@: modifies bit mask test: \`bool accept = (maskBits & node-\>categoryBits) == maskBits;\`
-> FunPtr TreeRayCastCallbackFcn
-- ^ @callback@: a callback function that is called for each proxy that is hit by the ray
-> Ptr ()
-- ^ @context@: user context that is passed to the callback
-> IO TreeStats
rayCast a0 a1 a2 a3 a4 a5 =
with a1 $ \p1 ->
alloca $ \pOut -> c_b3DynamicTree_RayCast a0 p1 a2 (fromBool a3) a4 a5 pOut >> peek pOut
{- | Sweep an AABB through the tree. The box is in the tree\'s world float frame and the callback
re-differences each shape at full precision against the query origin. Used by the large world
spatial queries so the tree traversal stays float while the narrow phase stays precise.
Binds @b3DynamicTree_BoxCast@.
-}
boxCast
:: Ptr DynamicTree
-> Ptr BoxCastInput
-> Word64
-- ^ @maskBits@
-> Bool
-- ^ @requireAllBits@
-> FunPtr TreeBoxCastCallbackFcn
-> Ptr ()
-- ^ @context@
-> IO TreeStats
boxCast a0 a1 a2 a3 a4 a5 =
alloca $ \pOut -> c_b3DynamicTree_BoxCast a0 a1 a2 (fromBool a3) a4 a5 pOut >> peek pOut
-- | Like 'boxCast', but the result is written into a caller-supplied buffer.
boxCastInto
:: Ptr DynamicTree
-> Ptr BoxCastInput
-> Word64
-- ^ @maskBits@
-> Bool
-- ^ @requireAllBits@
-> FunPtr TreeBoxCastCallbackFcn
-> Ptr ()
-- ^ @context@
-> Ptr TreeStats
-- ^ Result buffer.
-> IO ()
boxCastInto a0 a1 a2 a3 a4 a5 out =
c_b3DynamicTree_BoxCast a0 a1 a2 (fromBool a3) a4 a5 out
{- | Get the height of the binary tree.
Binds @b3DynamicTree_GetHeight@.
-}
getHeight
:: Ptr DynamicTree
-> IO Int
getHeight a0 =
fromIntegral <$> (c_b3DynamicTree_GetHeight a0)
{- | Get the ratio of the sum of the node areas to the root area.
Binds @b3DynamicTree_GetAreaRatio@.
-}
getAreaRatio
:: Ptr DynamicTree
-> IO Float
getAreaRatio a0 =
c_b3DynamicTree_GetAreaRatio a0
{- | Get the bounding box that contains the entire tree
Binds @b3DynamicTree_GetRootBounds@.
-}
getRootBounds
:: Ptr DynamicTree
-> IO AABB
getRootBounds a0 =
alloca $ \pOut -> c_b3DynamicTree_GetRootBounds a0 pOut >> peek pOut
-- | Like 'getRootBounds', but the result is written into a caller-supplied buffer.
getRootBoundsInto
:: Ptr DynamicTree
-> Ptr AABB
-- ^ Result buffer.
-> IO ()
getRootBoundsInto a0 out =
c_b3DynamicTree_GetRootBounds a0 out
{- | Get the number of proxies created
Binds @b3DynamicTree_GetProxyCount@.
-}
getProxyCount
:: Ptr DynamicTree
-> IO Int
getProxyCount a0 =
fromIntegral <$> (c_b3DynamicTree_GetProxyCount a0)
{- | Rebuild the tree while retaining subtrees that haven\'t changed. Returns the number of boxes sorted.
Binds @b3DynamicTree_Rebuild@.
-}
rebuild
:: Ptr DynamicTree
-> Bool
-- ^ @fullBuild@
-> IO Int
rebuild a0 a1 =
fromIntegral <$> (c_b3DynamicTree_Rebuild a0 (fromBool a1))
{- | Get the number of bytes used by this tree
Binds @b3DynamicTree_GetByteCount@.
-}
getByteCount
:: Ptr DynamicTree
-> IO Int
getByteCount a0 =
fromIntegral <$> (c_b3DynamicTree_GetByteCount a0)
{- | Validate this tree. For testing.
Binds @b3DynamicTree_Validate@.
-}
validate
:: Ptr DynamicTree
-> IO ()
validate a0 =
c_b3DynamicTree_Validate a0
{- | Validate this tree has no enlarged AABBs. For testing.
Binds @b3DynamicTree_ValidateNoEnlarged@.
-}
validateNoEnlarged
:: Ptr DynamicTree
-> IO ()
validateNoEnlarged a0 =
c_b3DynamicTree_ValidateNoEnlarged a0
{- | Save this tree to a file for debugging
Binds @b3DynamicTree_Save@.
-}
save
:: Ptr DynamicTree
-> CString
-- ^ @fileName@
-> IO ()
save a0 a1 =
c_b3DynamicTree_Save a0 a1
{- | Load a file for debugging
Binds @b3DynamicTree_Load@.
-}
load
:: CString
-- ^ @fileName@
-> Float
-- ^ @scale@
-> Ptr DynamicTree
-- ^ Result buffer.
-> IO ()
load a0 a1 out =
c_b3DynamicTree_Load a0 a1 out