lambdacube-bullet-0.2.1: Graphics/LambdaCube/Bullet.hs
module Graphics.LambdaCube.Bullet where
import Control.Applicative
import Control.Monad
import Control.Monad.Trans
import Data.List
import Data.Maybe
import Data.Vector ((!))
import qualified Data.Vector as V
import System.IO.Unsafe
import Physics.Bullet.Raw
import Physics.Bullet.Raw.Class
import Physics.Bullet.Raw.Types
import Graphics.LambdaCube
import Graphics.LambdaCube.Common
import Graphics.LambdaCube.RenderSystem
import Graphics.LambdaCube.World
-- ideal code from LC:
{-
mkTriangleMeshInterface mesh = do
mi <- btTriangleMesh True True
forM_ (vertices of the mesh triangle) $ \(a,b,c) -> btTriangleMesh_addTriangle mi a b c
return mi
-}
mkTriangleMeshInterfaceM :: VMesh -> IO BtTriangleMesh
mkTriangleMeshInterfaceM mesh = do
mi <- btTriangleMesh True True
forM_ (vmSubMeshList mesh) $ \sm -> do
let VVD_POSITION pos = V.head $ V.filter (\vd -> VVT_POSITION == vectorVertexType vd) $ fromMaybe (fromJust $ vmSharedVertexData mesh) $ vsmVertexData sm
idx = fromJust $ vsmIndexData sm
f n = let Vec3 x y z = pos ! n in Vector3 x y z
addStrip (a,b) i = btTriangleMesh_addTriangle mi (f a) (f b) (f i) False >> return (b,i)
addFan a b i = btTriangleMesh_addTriangle mi (f a) (f b) (f i) False >> return i
case vsmOperationType sm of
OT_TRIANGLE_LIST -> forM_ (unfoldr split3 idx) $ \iv -> do
btTriangleMesh_addTriangle mi (f (iv ! 0)) (f (iv ! 1)) (f (iv ! 2)) False
where
split3 v
| V.length v < 3 = Nothing
| otherwise = Just (V.take 3 v, V.drop 3 v)
OT_TRIANGLE_STRIP -> void $ let ab = V.take 2 idx in V.foldM' addStrip (ab ! 0, ab ! 1) $ V.drop 2 idx
OT_TRIANGLE_FAN -> void $ let ab = V.take 2 idx in V.foldM' (addFan $ ab ! 0) (ab ! 1) $ V.drop 2 idx
_ -> return ()
return mi
mkStaticTriangleMeshShapeM :: VMesh -> IO BtBvhTriangleMeshShape
mkStaticTriangleMeshShapeM mesh = do
mi <- mkTriangleMeshInterfaceM mesh
btBvhTriangleMeshShape0 mi True True
--mkGimpactTriangleMeshShape mesh = do
-- plNewGimpactTriangleMeshShape =<< mkTriangleMeshInterface mesh
mkConvexTriangleMeshShapeM :: VMesh -> IO BtConvexTriangleMeshShape
mkConvexTriangleMeshShapeM mesh = do
mi <- mkTriangleMeshInterfaceM mesh
btConvexTriangleMeshShape mi True
mkTriangleMeshInterface :: VMesh -> BtTriangleMesh
mkTriangleMeshInterface = unsafePerformIO . mkTriangleMeshInterfaceM
mkStaticTriangleMeshShape :: VMesh -> BtBvhTriangleMeshShape
mkStaticTriangleMeshShape = unsafePerformIO . mkStaticTriangleMeshShapeM
mkConvexTriangleMeshShape :: VMesh -> BtConvexTriangleMeshShape
mkConvexTriangleMeshShape = unsafePerformIO . mkConvexTriangleMeshShapeM
debugDrawPhysics :: (RenderSystem rs vb ib q t p lp, BtDynamicsWorldClass bc) => bc -> Proj4 -> LCM (World rs vb ib q t p lp) e ()
debugDrawPhysics dynamicsWorld camMat = do
rs <- wrRenderSystem <$> peekLCM
liftIO $ do
-- debug draw bullet space
--when debugDrawAll $
-- GL.clear [GL.DepthBuffer]
setWorldMatrix rs one
setViewMatrix rs camMat
setLightingEnabled rs False
setCullingMode rs $ CULL_NONE
forM_ [0..7] $ \i -> do
setActiveTextureUnit rs i
setTexture rs Nothing
--setDepthBias rs 1 1
btDynamicsWorld_debugDrawWorld dynamicsWorld