Box3D-0.1.0.0: src/Box3D/Mesh.hsc
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- Produced by boxnd-gen; edit the generator, not this file.
module Box3D.Mesh
( Mesh (..)
, MeshData (..)
, MeshTriangle (..)
, MeshEdgeFlags (..)
, pattern ConcaveEdge1
, pattern ConcaveEdge2
, pattern ConcaveEdge3
, pattern InverseConcaveEdge1
, pattern InverseConcaveEdge2
, pattern InverseConcaveEdge3
, pattern AllConcaveEdges
, pattern FlatEdge1
, pattern FlatEdge2
, pattern FlatEdge3
, pattern AllFlatEdges
, MeshDef (..)
, create
, destroy
)
where
import Foreign
import Foreign.C.Types (CBool (..), CInt (..))
import Box3D.MathTypes (AABB, Vec3)
#include "box3d/box3d.h"
-- | This allows mesh data to be re-used with different scales.
data Mesh = Mesh
{ data_ :: Ptr MeshData
-- ^ Immutable pointer to the mesh data.
, scale :: Vec3
-- ^ This scale may be non-uniform and have negative components. However,
-- no component may be very small in magnitude.
}
deriving (Eq, Show)
instance Storable Mesh where
sizeOf _ = #{size b3Mesh}
alignment _ = #{alignment b3Mesh}
peek p =
Mesh
<$> #{peek b3Mesh, data} p
<*> #{peek b3Mesh, scale} p
poke p (Mesh f1 f2) = do
#{poke b3Mesh, data} p f1
#{poke b3Mesh, scale} p f2
{- | This is a sorted triangle collision bounding volume hierarchy.
__Note:__ This struct has data hanging off the end and cannot be directly copied.
-}
data MeshData = MeshData
{ version :: Word64
-- ^ Version must be first.
, hash :: Word64
-- ^ Hash of this mesh (this field is zero when the hash is computed)
, byteCount :: Int32
-- ^ The total number of bytes for this mesh.
, bounds :: AABB
-- ^ Local axis-aligned box.
, surfaceArea :: Float
-- ^ Combined surface area of all triangles. Single-sided.
, treeHeight :: Int32
-- ^ The height of the bounding volume hierarchy.
, degenerateCount :: Int32
-- ^ The number of degenerate triangles. Diagnostic.
, nodeOffset :: Int32
-- ^ Offset of the node array in bytes from the struct address.
, nodeCount :: Int32
-- ^ The number of BVH nodes.
, vertexOffset :: Int32
-- ^ Offset of the vertex array in bytes from the struct address.
, vertexCount :: Int32
-- ^ The number of vertices.
, triangleOffset :: Int32
-- ^ Offset of the triangle array in bytes from the struct address.
, triangleCount :: Int32
-- ^ The number of triangles.
, materialOffset :: Int32
-- ^ Offset of the material array in bytes from the struct address.
, materialCount :: Int32
-- ^ The number of materials.
, flagsOffset :: Int32
-- ^ Offset of the triangle flag array in bytes from the struct address.
, padding :: Int32
-- ^ Explicit padding.
}
deriving (Eq, Show)
instance Storable MeshData where
sizeOf _ = #{size b3MeshData}
alignment _ = #{alignment b3MeshData}
peek p =
MeshData
<$> #{peek b3MeshData, version} p
<*> #{peek b3MeshData, hash} p
<*> #{peek b3MeshData, byteCount} p
<*> #{peek b3MeshData, bounds} p
<*> #{peek b3MeshData, surfaceArea} p
<*> #{peek b3MeshData, treeHeight} p
<*> #{peek b3MeshData, degenerateCount} p
<*> #{peek b3MeshData, nodeOffset} p
<*> #{peek b3MeshData, nodeCount} p
<*> #{peek b3MeshData, vertexOffset} p
<*> #{peek b3MeshData, vertexCount} p
<*> #{peek b3MeshData, triangleOffset} p
<*> #{peek b3MeshData, triangleCount} p
<*> #{peek b3MeshData, materialOffset} p
<*> #{peek b3MeshData, materialCount} p
<*> #{peek b3MeshData, flagsOffset} p
<*> #{peek b3MeshData, padding} p
poke p (MeshData f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17) = do
#{poke b3MeshData, version} p f1
#{poke b3MeshData, hash} p f2
#{poke b3MeshData, byteCount} p f3
#{poke b3MeshData, bounds} p f4
#{poke b3MeshData, surfaceArea} p f5
#{poke b3MeshData, treeHeight} p f6
#{poke b3MeshData, degenerateCount} p f7
#{poke b3MeshData, nodeOffset} p f8
#{poke b3MeshData, nodeCount} p f9
#{poke b3MeshData, vertexOffset} p f10
#{poke b3MeshData, vertexCount} p f11
#{poke b3MeshData, triangleOffset} p f12
#{poke b3MeshData, triangleCount} p f13
#{poke b3MeshData, materialOffset} p f14
#{poke b3MeshData, materialCount} p f15
#{poke b3MeshData, flagsOffset} p f16
#{poke b3MeshData, padding} p f17
-- | A mesh triangle.
data MeshTriangle = MeshTriangle
{ index1 :: Int32
-- ^ Index of vertex 1.
, index2 :: Int32
-- ^ Index of vertex 2.
, index3 :: Int32
-- ^ Index of vertex 3.
}
deriving (Eq, Show)
instance Storable MeshTriangle where
sizeOf _ = #{size b3MeshTriangle}
alignment _ = #{alignment b3MeshTriangle}
peek p =
MeshTriangle
<$> #{peek b3MeshTriangle, index1} p
<*> #{peek b3MeshTriangle, index2} p
<*> #{peek b3MeshTriangle, index3} p
poke p (MeshTriangle f1 f2 f3) = do
#{poke b3MeshTriangle, index1} p f1
#{poke b3MeshTriangle, index2} p f2
#{poke b3MeshTriangle, index3} p f3
-- | Triangle mesh edge flags.
newtype MeshEdgeFlags = MeshEdgeFlags CInt
deriving (Eq, Show, Storable)
pattern ConcaveEdge1 :: MeshEdgeFlags
pattern ConcaveEdge2 :: MeshEdgeFlags
pattern ConcaveEdge3 :: MeshEdgeFlags
pattern InverseConcaveEdge1 :: MeshEdgeFlags
pattern InverseConcaveEdge2 :: MeshEdgeFlags
pattern InverseConcaveEdge3 :: MeshEdgeFlags
pattern AllConcaveEdges :: MeshEdgeFlags
pattern FlatEdge1 :: MeshEdgeFlags
pattern FlatEdge2 :: MeshEdgeFlags
pattern FlatEdge3 :: MeshEdgeFlags
pattern AllFlatEdges :: MeshEdgeFlags
pattern ConcaveEdge1 = MeshEdgeFlags #{const b3_concaveEdge1}
pattern ConcaveEdge2 = MeshEdgeFlags #{const b3_concaveEdge2}
pattern ConcaveEdge3 = MeshEdgeFlags #{const b3_concaveEdge3}
pattern InverseConcaveEdge1 = MeshEdgeFlags #{const b3_inverseConcaveEdge1}
pattern InverseConcaveEdge2 = MeshEdgeFlags #{const b3_inverseConcaveEdge2}
pattern InverseConcaveEdge3 = MeshEdgeFlags #{const b3_inverseConcaveEdge3}
pattern AllConcaveEdges = MeshEdgeFlags #{const b3_allConcaveEdges}
pattern FlatEdge1 = MeshEdgeFlags #{const b3_flatEdge1}
pattern FlatEdge2 = MeshEdgeFlags #{const b3_flatEdge2}
pattern FlatEdge3 = MeshEdgeFlags #{const b3_flatEdge3}
pattern AllFlatEdges = MeshEdgeFlags #{const b3_allFlatEdges}
{- | This is used to create a re-usable collision mesh. No pointers
are held to this data in @b3MeshData@. So all this data can be temporary.
-}
data MeshDef = MeshDef
{ vertices :: Ptr Vec3
-- ^ Triangle vertices.
, indices :: Ptr ()
-- ^ Triangle vertex indices. 3 for each triangle. CCW winding.
, materialIndices :: Ptr ()
-- ^ Triangle material index. 1 per triangle. Indexes into @b3ShapeDef::materials@.
-- This allows different run-time material data to be associated with different
-- instances of this mesh.
, weldTolerance :: Float
-- ^ Tolerance for vertex welding in length units.
, vertexCount :: CInt
-- ^ The vertex count. Must be 3 or more.
, triangleCount :: CInt
-- ^ The triangle count. Must be 1 or more.
, weldVertices :: CBool
-- ^ Optionally weld nearby vertices.
, useMedianSplit :: CBool
-- ^ Use the median split instead of SAH to speed up mesh creation. Good
-- for meshes that are structured like a grid.
, identifyEdges :: CBool
-- ^ Compute triangle adjacency information using shared edges
}
deriving (Eq, Show)
instance Storable MeshDef where
sizeOf _ = #{size b3MeshDef}
alignment _ = #{alignment b3MeshDef}
peek p =
MeshDef
<$> #{peek b3MeshDef, vertices} p
<*> #{peek b3MeshDef, indices} p
<*> #{peek b3MeshDef, materialIndices} p
<*> #{peek b3MeshDef, weldTolerance} p
<*> #{peek b3MeshDef, vertexCount} p
<*> #{peek b3MeshDef, triangleCount} p
<*> #{peek b3MeshDef, weldVertices} p
<*> #{peek b3MeshDef, useMedianSplit} p
<*> #{peek b3MeshDef, identifyEdges} p
poke p (MeshDef f1 f2 f3 f4 f5 f6 f7 f8 f9) = do
#{poke b3MeshDef, vertices} p f1
#{poke b3MeshDef, indices} p f2
#{poke b3MeshDef, materialIndices} p f3
#{poke b3MeshDef, weldTolerance} p f4
#{poke b3MeshDef, vertexCount} p f5
#{poke b3MeshDef, triangleCount} p f6
#{poke b3MeshDef, weldVertices} p f7
#{poke b3MeshDef, useMedianSplit} p f8
#{poke b3MeshDef, identifyEdges} p f9
foreign import ccall unsafe "b3CreateMesh"
c_b3CreateMesh :: Ptr MeshDef -> Ptr CInt -> CInt -> IO (Ptr MeshData)
foreign import ccall unsafe "b3DestroyMesh"
c_b3DestroyMesh :: Ptr MeshData -> IO ()
{- | Create a generic mesh.
Binds @b3CreateMesh@.
-}
create
:: Ptr MeshDef
-> Ptr CInt
-- ^ @degenerateTriangleIndices@
-> Int
-- ^ @degenerateCapacity@
-> IO (Ptr MeshData)
create a0 a1 a2 =
c_b3CreateMesh a0 a1 (fromIntegral a2)
{- | Destroy a mesh.
Binds @b3DestroyMesh@.
-}
destroy
:: Ptr MeshData
-> IO ()
destroy a0 =
c_b3DestroyMesh a0