bullet (empty) → 0.1.1
raw patch · 10 files changed
+1287/−0 lines, 10 filesdep +basesetup-changedbinary-added
Dependencies added: base
Files
- Examples/BulletExample.hs +338/−0
- Examples/bullet-example-1.png binary
- Examples/bullet-example-2.png binary
- LICENSE +28/−0
- Physics/Bullet.hs +258/−0
- README +17/−0
- Setup.lhs +4/−0
- bullet.cabal +32/−0
- cbits/bullet.cpp +436/−0
- cbits/bullet.h +174/−0
+ Examples/BulletExample.hs view
@@ -0,0 +1,338 @@+import Control.Monad+import Control.Concurrent.MVar+import System.Exit+import Graphics.UI.GLUT+import Graphics.Rendering.OpenGL+import Graphics.Rendering.OpenGL.GL.CoordTrans+import Unsafe.Coerce -- because realToFrac just doesn't cut it...++import Physics.Bullet+import Foreign hiding (rotate)++timerFrequencyMillis :: Timeout+timerFrequencyMillis = 1++data BCube = BCube (GLfloat,GLfloat,GLfloat,PlRigidBodyHandle,(GLfloat,GLfloat,GLfloat,GLfloat))++data State = State {+ dworld :: PlDynamicsWorldHandle,+ cubes :: [BCube],+ viewAngle :: MVar GLfloat,+ viewHeight :: MVar GLfloat,+ paused :: MVar Bool+ }++createBCube dw ((x,y,z), (w,h,d), m, col) = do+ shape <- plNewBoxShape w h d+ b <- plCreateRigidBody Foreign.nullPtr m shape+ plAddRigidBody dw b+ plSetPosition b (x,y,z)+ return $ BCube (unsafeCoerce w,unsafeCoerce h,unsafeCoerce d,b,col)++lightPosition = Vertex4 5 20 10 0++lightPositionDeltas = map calcDelta [0..lightSteps-1]+ where Vertex4 lxo lyo lzo _ = lightPosition+ calcDelta l = (lightSize*(lx1*sin ll+lx2*cos ll),+ lightSize*(ly1*sin ll+ly2*cos ll),+ lightSize*(lz1*sin ll+lz2*cos ll))+ where ll = 2*pi*l/lightSteps+ ll1 = sqrt (lxo*lxo+lzo*lzo)+ (lx1,ly1,lz1) = (lzo/ll1,0,-lxo/ll1)+ ll2 = sqrt (lxo*lxo*lyo*lyo+(lxo*lxo+lzo*lzo)*(lxo*lxo+lzo*lzo)+lzo*lzo*lyo*lyo)+ (lx2,ly2,lz2) = (-lxo*lyo/ll2,(lxo*lxo+lzo*lzo)/ll2,-lzo*lyo/ll2)++lightSteps = 8+lightSize = 0.3++camDistance = 8++makeState :: IO State+makeState = do+ sdk <- plNewBulletSdk+ dw <- plCreateDynamicsWorld sdk+ ang <- newMVar 0+ h <- newMVar (-6)+ p <- newMVar False++ -- set up bullet scene+ cs <- mapM (createBCube dw) $ [+ ((0,-0.1,0), (50.0,0.1,50.0), 0, (0.9,0.9,0.9,1)),+ ((4,15,-0.5), (1,1,1), 10, blue)+ ]+ ++ map (\x -> ((-5+x*0.5,0.5+10-abs(x-10),0), (0.5,0.5,0.5), 1, green)) [0..20]+ ++ map (\x -> let h = min 4.5 (5-abs(x-5)) in ((-5+x,h,0), (0.1,h,0.1), 2, yellow)) [1..9]++ return $ State {+ dworld = dw,+ cubes = cs,+ viewAngle = ang,+ viewHeight = h,+ paused = p+ }++ where green = (0,1,0,1)+ yellow = (1,1,0,1)+ blue = (0,0,1,1)++display :: State -> DisplayCallback+display state = do+ loadIdentity+ height <- readMVar $ viewHeight state+ rotate (-atan ((height+3)/camDistance)*180/pi) (Vector3 1 0 (0 :: GLfloat))+ translate (Vector3 0 height (-camDistance))+ angle <- readMVar $ viewAngle state+ rotate angle (Vector3 0 1 0)++ scale (1 :: GLfloat) 1 1++ position (Light 0) $= lightPosition++ let cs = cubes state++ -- draw fully lit scene+ clear [ColorBuffer, DepthBuffer]+ cullFace $= Just Back++ forM_ cs $ \(BCube (w,h,d,body,(r,g,b,a))) -> do+ materialDiffuse Front $= Color4 r g b a+ preservingMatrix $ do+ -- get position and orientation of body+ (e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,eA,eB,eC,eD,eE,eF) <- plGetOpenGLMatrix body+ let f = unsafeCoerce+ m <- newMatrix ColumnMajor $ [f e0,f e1,f e2,f e3,f e4,f e5,f e6,f e7,f e8,f e9,f eA,f eB,f eC,f eD,f eE,f eF]+ -- set position and orientation of gl modelview matrix+ multMatrix (m :: GLmatrix GLfloat)+ drawCube w h d++ -- settings needed for casting+ depthMask $= Disabled+ stencilTest $= Enabled++ forM_ lightPositionDeltas $ \lpd -> do+ -- generate shadow volumes (note that they are open-ended!)+ svs <- forM (tail cs) $ \(BCube (w,h,d,body,_)) -> do+ (px,py,pz) <- plGetPosition body+ (ox,oy,oz,ow) <- plGetOrientation body+ return $ (body, cubeShadow lpd (-unsafeCoerce px,-unsafeCoerce py,-unsafeCoerce pz) (unsafeCoerce ow,-unsafeCoerce ox,-unsafeCoerce oy,-unsafeCoerce oz) w h d)++ renderShadows svs++ -- restore settings+ stencilTest $= Disabled+ depthMask $= Enabled++ flush+ swapBuffers++renderShadows svs = do+ -- increment stencil for the front faces of shadow volumes+ lighting $= Disabled+ colorMask $= Color4 Disabled Disabled Disabled Disabled+ stencilFunc $= (Always, 0, 0)+ stencilOp $= (OpKeep, OpKeep, OpIncrWrap)+ drawShadowVolumes svs++ -- decrement stencil for the back faces of shadow volumes+ cullFace $= Just Front+ stencilOp $= (OpKeep, OpKeep, OpDecrWrap)+ drawShadowVolumes svs++ -- apply shadow using the stencil buffer+ colorMask $= Color4 Enabled Enabled Enabled Enabled+ depthFunc $= Just Less+ stencilOp $= (OpZero, OpZero, OpZero)+ stencilFunc $= (Less, 0, 0xffffffff)+ lighting $= Enabled+ cullFace $= Just Back+ blend $= Enabled+ blendFunc $= (SrcAlpha, OneMinusSrcAlpha)++ materialDiffuse Front $= Color4 0 0 0 (0.4/lightSteps)+ preservingMatrix $ do+ loadIdentity+ renderPrimitive TriangleStrip $ do+ vertex $ Vertex3 (-10) 10 (-1 :: GLfloat)+ vertex $ Vertex3 (-10) (-10) (-1 :: GLfloat)+ vertex $ Vertex3 10 10 (-1 :: GLfloat)+ vertex $ Vertex3 10 (-10) (-1 :: GLfloat)++ blend $= Disabled++drawShadowVolumes svs =+ forM_ svs $ \(body,vs) -> do+ preservingMatrix $ do+ -- get position and orientation of body+ (e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,eA,eB,eC,eD,eE,eF) <- plGetOpenGLMatrix body+ let f = unsafeCoerce+ m <- newMatrix ColumnMajor $ [f e0,f e1,f e2,f e3,f e4,f e5,f e6,f e7,f e8,f e9,f eA,f eB,f eC,f eD,f eE,f eF]+ -- set position and orientation of gl modelview matrix+ multMatrix (m :: GLmatrix GLfloat)+ renderPrimitive Quads $ forM_ vs $ \(p1,p2,p3,p4) -> do+ vertex p1+ vertex p2+ vertex p3+ vertex p4++keyboard :: State -> KeyboardMouseCallback+keyboard state key keyState mods _ = do+ case (key, keyState) of+ (Char 'q', Down) -> exitWith ExitSuccess+ (Char '\27', Down) -> exitWith ExitSuccess+ --(Char 't', Down) -> modelCycle state $~ tail+ --(SpecialKey KeyHome, Down) -> resetState state+ (SpecialKey KeyLeft, Down) -> do+ angle <- takeMVar $ viewAngle state+ putMVar (viewAngle state) (angle+2)+ (SpecialKey KeyRight, Down) -> do+ angle <- takeMVar $ viewAngle state+ putMVar (viewAngle state) (angle-2)+ (SpecialKey KeyUp, Down) -> do+ height <- takeMVar $ viewHeight state+ putMVar (viewHeight state) (height-0.2)+ (SpecialKey KeyDown, Down) -> do+ height <- takeMVar $ viewHeight state+ putMVar (viewHeight state) (height+0.2)+ (Char 'p', Down) -> do+ isPaused <- takeMVar $ paused state+ putMVar (paused state) (not isPaused)+ (_, _) -> return ()++reshape :: ReshapeCallback+reshape size@(Size w h) = do+ let vp = 0.8+ aspect = fromIntegral w / fromIntegral h++ viewport $= (Position 0 0, size)++ matrixMode $= Projection+ loadIdentity+ frustum (-vp) vp (-vp / aspect) (vp / aspect) 1 1000++ matrixMode $= Modelview 0+ loadIdentity+ translate (Vector3 0 0 (-5 :: GLfloat))++timer :: State -> TimerCallback+timer state = do+ addTimerCallback timerFrequencyMillis (timer state)+ isPaused <- readMVar $ paused state+ when (not isPaused) $ plStepSimulation (dworld state) (fromIntegral(timerFrequencyMillis))+ postRedisplay Nothing++drawFace :: Normal3 GLfloat -> Vertex3 GLfloat -> Vertex3 GLfloat+ -> Vertex3 GLfloat -> Vertex3 GLfloat -> IO ()+drawFace p q r s t = do+ let texCoord2f = texCoord :: TexCoord2 GLfloat -> IO ()+ normal p+ texCoord2f (TexCoord2 1 1)+ vertex q+ texCoord2f (TexCoord2 0 1)+ vertex r+ texCoord2f (TexCoord2 0 0)+ vertex s+ texCoord2f (TexCoord2 1 0)+ vertex t++drawCube :: GLfloat -> GLfloat -> GLfloat -> IO ()+drawCube sx sy sz = do+ let a = Vertex3 sx sy sz+ b = Vertex3 sx sy (-sz)+ c = Vertex3 sx (-sy) (-sz)+ d = Vertex3 sx (-sy) sz+ e = Vertex3 (-sx) sy sz+ f = Vertex3 (-sx) sy (-sz)+ g = Vertex3 (-sx) (-sy) (-sz)+ h = Vertex3 (-sx) (-sy) sz++ i = Normal3 1 0 0+ k = Normal3 (-1) 0 0+ l = Normal3 0 0 (-1)+ m = Normal3 0 0 1+ n = Normal3 0 1 0+ o = Normal3 0 (-1) 0++ renderPrimitive Quads $ do+ drawFace i d c b a+ drawFace k g h e f+ drawFace l c g f b+ drawFace m h d a e+ drawFace n e a b f+ drawFace o g c d h++cubeShadow (ldx,ldy,ldz) (x,y,z) (a,b,c,d) sx sy sz =+ map shadowFace $ filter shouldCast edges+ where [oxx,oxy,oxz,oyx,oyy,oyz,ozx,ozy,ozz] =+ [a*a+b*b-c*c-d*d, 2*(b*c-a*d), 2*(a*c+b*d),+ 2*(a*d+b*c), a*a-b*b+c*c-d*d, 2*(c*d-a*b),+ 2*(b*d-a*c), 2*(a*b+c*d), a*a-b*b-c*c+d*d]++ Vertex4 lxo lyo lzo _ = lightPosition+ (lxt,lyt,lzt) = (lxo+ldx+x,lyo+ldy+y,lzo+ldz+z)+ (lx,ly,lz) = (lxt*oxx+lyt*oxy+lzt*oxz,+ lxt*oyx+lyt*oyy+lzt*oyz,+ lxt*ozx+lyt*ozy+lzt*ozz)++ ni = lx > sx+ nk = lx < (-sx)+ nl = lz < (-sz)+ nm = lz > sz+ nn = ly > sy+ no = ly < (-sy)++ va = ( sx, sy, sz)+ vb = ( sx, sy,-sz)+ vc = ( sx,-sy,-sz)+ vd = ( sx,-sy, sz)+ ve = (-sx, sy, sz)+ vf = (-sx, sy,-sz)+ vg = (-sx,-sy,-sz)+ vh = (-sx,-sy, sz)++ edges = [(vd,vc,ni,no),(vc,vb,ni,nl),(vb,va,ni,nn),(va,vd,ni,nm),+ (vg,vh,nk,no),(vf,vg,nk,nl),(ve,vf,nk,nn),(vh,ve,nk,nm),+ (vc,vg,nl,no),(vf,vb,nl,nn),(vh,vd,nm,no),(va,ve,nm,nn)]++ shouldCast (_,_,c1,c2) = (c1 && (not c2)) || (c2 && (not c1))++ shadowFace ((v1x,v1y,v1z),(v2x,v2y,v2z),n1,n2) =+ if n2 then+ (Vertex3 v1x v1y v1z, Vertex3 v2x v2y v2z,+ Vertex3 v3x v3y v3z, Vertex3 v4x v4y v4z)+ else+ (Vertex3 v4x v4y v4z, Vertex3 v3x v3y v3z,+ Vertex3 v2x v2y v2z, Vertex3 v1x v1y v1z)+ where ss = 1000+ v3x = v2x+(v2x-lx)*ss+ v3y = v2y+(v2y-ly)*ss+ v3z = v2z+(v2z-lz)*ss+ v4x = v1x+(v1x-lx)*ss+ v4y = v1y+(v1y-ly)*ss+ v4z = v1z+(v1z-lz)*ss+++main = do+ getArgsAndInitialize+ initialDisplayMode $= [RGBMode, WithDepthBuffer, WithStencilBuffer, DoubleBuffered, Multisampling]+ initialWindowSize $= Size 800 800+ createWindow "Bullet Example"++ state <- makeState+ displayCallback $= display state+ keyboardMouseCallback $= Just (keyboard state)+ reshapeCallback $= Just reshape+ addTimerCallback timerFrequencyMillis (timer state)++ materialDiffuse Front $= Color4 1 0.3 0.2 1+ materialSpecular Front $= Color4 0.3 0.3 0.3 1+ materialShininess Front $= 16+ lighting $= Enabled+ light (Light 0) $= Enabled++ depthFunc $= Just Less+ clearColor $= Color4 0.0 0.0 0.0 1++ clear [StencilBuffer]++ mainLoop+
+ Examples/bullet-example-1.png view
binary file changed (absent → 28784 bytes)
+ Examples/bullet-example-2.png view
binary file changed (absent → 29785 bytes)
+ LICENSE view
@@ -0,0 +1,28 @@+Copyright (c) 2009, Csaba Hruska+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice,+ this list of conditions and the following disclaimer.++2. 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.++3. Neither the name of the author 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 OWNER 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.
+ Physics/Bullet.hs view
@@ -0,0 +1,258 @@+{-# CFILES cbits/bullet.c #-} -- for Hugs (?)+module Physics.Bullet (+ PlQuaternion, PlVector3, PlRayCastResult, PlMatrix,+ PlPhysicsSdkHandle, PlDynamicsWorldHandle, PlRigidBodyHandle, PlUserDataHandle, PlCollisionShapeHandle, PlMeshInterfaceHandle,+ plNewBulletSdk, plDeletePhysicsSdk,+-- plCreateSapBroadphase, plDestroyBroadphase,+-- plCreateProxy, plDestroyProxy, plSetBoundingBox,+-- plCreateCollisionWorld,+ plCreateDynamicsWorld, plDeleteDynamicsWorld, plStepSimulation, plAddRigidBody, plRemoveRigidBody,+ plCreateRigidBody, plDeleteRigidBody,+ plNewSphereShape, plNewBoxShape, plNewCapsuleShape, plNewConeShape, plNewCylinderShape, plNewCompoundShape,++ plAddChildShape, plDeleteShape, plNewConvexHullShape, plAddVertex, plNewMeshInterface,+ plAddTriangle, plNewStaticTriangleMeshShape,plNewGimpactTriangleMeshShape,plNewConvexTriangleMeshShape,+ plSetScaling, plGetOpenGLMatrix, plGetPosition, plGetOrientation, plSetPosition, plSetOrientation, plSetEuler+-- plRayCast++) where++import Foreign+import Foreign.C.Types+import Foreign.Marshal.Array+{-+typedef float plVector3[3];+typedef float plQuaternion[4];+typedef float plVehicleTuning[5];++typedef struct plRayCastResult {+ plRigidBodyHandle m_body; + plCollisionShapeHandle m_shape; + plVector3 m_positionWorld; + plVector3 m_normalWorld;+} plRayCastResult;+-}+--plRayCastResult+--type PlRayCastResult = Ptr ()+data PlRayCastResult_ = PlRayCastResult_ PlRigidBodyHandle PlCollisionShapeHandle PlVector3 PlVector3+type PlRayCastResult = Ptr PlRayCastResult_++type PlQuaternion = Ptr CFloat++type PlVector3 = Ptr CFloat++type PlMatrix = Ptr CFloat++type PlVehicleTuning = Ptr CFloat++-----------------------------------------+data PlPhysicsSdk = PlPhysicsSdk+type PlPhysicsSdkHandle = Ptr PlPhysicsSdk++data PlDynamicsWorld = PlDynamicsWorld+type PlDynamicsWorldHandle = Ptr PlDynamicsWorld++data PlRigidBody = PlRigidBody+type PlRigidBodyHandle = Ptr PlRigidBody++type PlUserDataHandle = Ptr ()++data PlCollisionShape = PlCollisionShape+type PlCollisionShapeHandle = Ptr PlCollisionShape++data PlMeshInterface = PlMeshInterface+type PlMeshInterfaceHandle = Ptr PlMeshInterface++foreign import ccall unsafe "plNewBulletSdk" plNewBulletSdk :: IO PlPhysicsSdkHandle+foreign import ccall unsafe "plDeletePhysicsSdk" plDeletePhysicsSdk :: PlPhysicsSdkHandle -> IO ()+--foreign import ccall "plCreateSapBroadphase" plCreateSapBroadphase :: Ptr a -> Ptr a -> IO (Ptr a)+--foreign import ccall "plDestroyBroadphase" plDestroyBroadphase :: Ptr a -> IO()+--foreign import ccall "plCreateProxy" plCreateProxy :: Ptr a -> Ptr a -> CCFloat -> CCFloat -> CCFloat -> CCFloat -> CCFloat -> CCFloat -> IO( Ptr a )+--foreign import ccall "plDestroyProxy" plDestroyProxy :: Ptr a -> Ptr a -> IO()+--foreign import ccall "plSetBoundingBox" plSetBoundingBox :: Ptr a -> CCFloat -> CCFloat -> CCFloat -> CCFloat -> CCFloat -> CCFloat -> IO()+--foreign import ccall "plCreateCollisionWorld" plCreateCollisionWorld :: Ptr a -> IO( Ptr a )+foreign import ccall unsafe "plCreateDynamicsWorld" plCreateDynamicsWorld :: PlPhysicsSdkHandle -> IO PlDynamicsWorldHandle+foreign import ccall unsafe "plDeleteDynamicsWorld" plDeleteDynamicsWorld :: PlDynamicsWorldHandle -> IO ()+foreign import ccall unsafe "plStepSimulation" plStepSimulation :: PlDynamicsWorldHandle -> CFloat -> IO ()+foreign import ccall unsafe "plAddRigidBody" plAddRigidBody :: PlDynamicsWorldHandle -> PlRigidBodyHandle -> IO ()+foreign import ccall unsafe "plRemoveRigidBody" plRemoveRigidBody :: PlDynamicsWorldHandle -> PlRigidBodyHandle -> IO ()+foreign import ccall unsafe "plCreateRigidBody" plCreateRigidBody :: PlUserDataHandle -> CFloat -> PlCollisionShapeHandle -> IO PlRigidBodyHandle+foreign import ccall unsafe "plDeleteRigidBody" plDeleteRigidBody :: PlRigidBodyHandle -> IO ()+foreign import ccall unsafe "plNewSphereShape" plNewSphereShape :: CFloat -> IO PlCollisionShapeHandle+foreign import ccall unsafe "plNewBoxShape" plNewBoxShape :: CFloat -> CFloat -> CFloat -> IO PlCollisionShapeHandle+foreign import ccall unsafe "plNewCapsuleShape" plNewCapsuleShape :: CFloat -> CFloat -> IO PlCollisionShapeHandle+foreign import ccall unsafe "plNewConeShape" plNewConeShape :: CFloat -> CFloat -> IO PlCollisionShapeHandle+foreign import ccall unsafe "plNewCylinderShape" plNewCylinderShape :: CFloat -> CFloat -> IO PlCollisionShapeHandle+foreign import ccall unsafe "plNewCompoundShape" plNewCompoundShape :: IO PlCollisionShapeHandle+foreign import ccall unsafe "plAddChildShape" plAddChildShape_ :: PlCollisionShapeHandle -> PlCollisionShapeHandle -> PlVector3 -> PlQuaternion -> IO ()+foreign import ccall unsafe "plDeleteShape" plDeleteShape :: PlCollisionShapeHandle -> IO ()+foreign import ccall unsafe "plNewConvexHullShape" plNewConvexHullShape :: Ptr CFloat -> Int -> Int -> IO PlCollisionShapeHandle++foreign import ccall unsafe "plAddVertex" plAddVertex :: PlCollisionShapeHandle -> CFloat -> CFloat -> CFloat -> IO ()++foreign import ccall unsafe "plNewMeshInterface" plNewMeshInterface :: IO PlMeshInterfaceHandle+foreign import ccall unsafe "plAddTriangle" plAddTriangle_ :: PlMeshInterfaceHandle -> PlVector3 -> PlVector3 -> PlVector3 -> Int -> IO ()+foreign import ccall unsafe "plNewStaticTriangleMeshShape" plNewStaticTriangleMeshShape :: PlMeshInterfaceHandle -> IO PlCollisionShapeHandle+foreign import ccall unsafe "plNewGimpactTriangleMeshShape" plNewGimpactTriangleMeshShape :: PlMeshInterfaceHandle -> IO PlCollisionShapeHandle+foreign import ccall unsafe "plNewConvexTriangleMeshShape" plNewConvexTriangleMeshShape :: PlMeshInterfaceHandle -> IO PlCollisionShapeHandle++foreign import ccall unsafe "plSetScaling" plSetScaling_ :: PlCollisionShapeHandle -> PlVector3 -> IO ()+foreign import ccall unsafe "plGetOpenGLMatrix" plGetOpenGLMatrix_ :: PlRigidBodyHandle -> PlMatrix -> IO ()+foreign import ccall unsafe "plGetPosition" plGetPosition_ :: PlRigidBodyHandle -> PlVector3 -> IO ()+foreign import ccall unsafe "plGetOrientation" plGetOrientation_ :: PlRigidBodyHandle -> PlQuaternion -> IO ()+foreign import ccall unsafe "plSetPosition" plSetPosition_ :: PlRigidBodyHandle -> PlVector3 -> IO ()+foreign import ccall unsafe "plSetOrientation" plSetOrientation_ :: PlRigidBodyHandle -> PlQuaternion -> IO ()+foreign import ccall unsafe "plSetEuler" plSetEuler :: CFloat -> CFloat -> CFloat -> PlQuaternion -> IO ()+foreign import ccall unsafe "plRayCast" plRayCast :: PlDynamicsWorldHandle -> PlVector3 -> PlVector3 -> PlRayCastResult -> IO Int++-- TODO : new functions+{-+plCreateRaycastVehicle :: PlVehicleTuning -> PlRigidBodyHandle -> IO PlRaycastVehicleHandle+plAddVehicle :: PlDynamicsWorldHandle -> PlRaycastVehicleHandle -> IO ()+plSetCoordinateSystem :: PlRaycastVehicleHandle -> Int -> Int -> Int -> IO ()+plAddWheel :: PlCFloat3 -> PlCFloat3 -> PlCFloat3 -> CFloat -> CFloat -> PlCFloat5 -> Bool -> IO (wheelinfo ????)+++ btRaycastVehicle::btVehicleTuning m_tuning;+ btVehicleRaycaster* m_vehicleRayCaster;+ btRaycastVehicle* m_vehicle;+ btCollisionShape* m_wheelShape;++ btWheelInfo& addWheel( const btVector3& connectionPointCS0, const btVector3& wheelDirectionCS0,const btVector3& wheelAxleCS,btScalar suspensionRestLength,btScalar wheelRadius,const btVehicleTuning& tuning, bool isFrontWheel);++ class btVehicleTuning+ {+ public:++ btVehicleTuning()+ :m_suspensionStiffness(btScalar(5.88)),+ m_suspensionCompression(btScalar(0.83)),+ m_suspensionDamping(btScalar(0.88)),+ m_maxSuspensionTravelCm(btScalar(500.)),+ m_frictionSlip(btScalar(10.5))+ {+ }+ btScalar m_suspensionStiffness;+ btScalar m_suspensionCompression;+ btScalar m_suspensionDamping;+ btScalar m_maxSuspensionTravelCm;+ btScalar m_frictionSlip;++ };+-}++-- more nice wrappers+plGetOpenGLMatrix body =+ allocaArray 16 f+ where+ f p = do+ plGetOpenGLMatrix_ body p+ e0 <- peekElemOff p 0+ e1 <- peekElemOff p 1+ e2 <- peekElemOff p 2+ e3 <- peekElemOff p 3+ e4 <- peekElemOff p 4+ e5 <- peekElemOff p 5+ e6 <- peekElemOff p 6+ e7 <- peekElemOff p 7+ e8 <- peekElemOff p 8+ e9 <- peekElemOff p 9+ eA <- peekElemOff p 10+ eB <- peekElemOff p 11+ eC <- peekElemOff p 12+ eD <- peekElemOff p 13+ eE <- peekElemOff p 14+ eF <- peekElemOff p 15+ return (e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,eA,eB,eC,eD,eE,eF)+ --mapM (peekElemOff m) [0..15]++packCFloat3 p (x,y,z) = do+ pokeElemOff p 0 x + pokeElemOff p 1 y+ pokeElemOff p 2 z++unpackCFloat3 p = do+ x <- peekElemOff p 0+ y <- peekElemOff p 1+ z <- peekElemOff p 2+ return (x,y,z)++packCFloat4 p (x,y,z,w) = do+ pokeElemOff p 0 x + pokeElemOff p 1 y+ pokeElemOff p 2 z+ pokeElemOff p 3 w++unpackCFloat4 p = do+ x <- peekElemOff p 0+ y <- peekElemOff p 1+ z <- peekElemOff p 2+ w <- peekElemOff p 3+ return (x,y,z,w)++packCFloat5 p (x,y,z,w,q) = do+ pokeElemOff p 0 x + pokeElemOff p 1 y+ pokeElemOff p 2 z+ pokeElemOff p 3 w+ pokeElemOff p 4 q++unpackCFloat5 p = do+ x <- peekElemOff p 0+ y <- peekElemOff p 1+ z <- peekElemOff p 2+ w <- peekElemOff p 3+ q <- peekElemOff p 4+ return (x,y,z,w,q)++plGetPosition body =+ allocaArray 3 f+ where+ f p = do+ plGetPosition_ body p+ unpackCFloat3 p++plSetPosition b pos =+ allocaArray 3 f+ where+ f p = do+ packCFloat3 p pos+ plSetPosition_ b p++plGetOrientation body =+ allocaArray 4 f+ where+ f p = do+ plGetOrientation_ body p+ unpackCFloat4 p++plSetOrientation b o =+ allocaArray 4 f+ where+ f p = do+ packCFloat4 p o+ plSetOrientation_ b p++plAddChildShape compShape chShape chPos chOrig =+ allocaArray 7 f+ where+ f p = do+ packCFloat3 p chPos+ packCFloat4 (advancePtr p 3) chOrig+ plAddChildShape_ compShape chShape p (advancePtr p 3)++plAddTriangle meshInterface v0 v1 v2 rmDup =+ allocaArray 9 f+ where+ f p = do+ packCFloat3 p v0+ packCFloat3 (advancePtr p 3) v1+ packCFloat3 (advancePtr p 6) v2+ plAddTriangle_ meshInterface p (advancePtr p 3) (advancePtr p 6) $ if rmDup then 1 else 0++plSetScaling shape v =+ allocaArray 3 f+ where+ f p = do+ packCFloat3 p v+ plSetScaling_ shape p
+ README view
@@ -0,0 +1,17 @@+Compile:+ - get bullet physics engine:+ svn checkout http://bullet.googlecode.com/svn/trunk/ bullet-read-only++ - compile and install the library:+ cd bullet-read-only+ cmake .+ make+ sudo make install++ - compile and install the haskell bullet binding:+ cabal install (run command in the bullet.cabal's directory)++ - compile and run the example (needs OpenGL and GLUT):+ cd Examples+ ghc --make -O2 BulletExample+ ./BulletExample
+ Setup.lhs view
@@ -0,0 +1,4 @@+#! /usr/bin/env runhaskell + +> import Distribution.Simple +> main = defaultMain
+ bullet.cabal view
@@ -0,0 +1,32 @@+Name: bullet+Version: 0.1.1+Synopsis: A wrapper for the Bullet physics engine.+Description: A wrapper for the Bullet physics engine.+License: BSD3+License-file: LICENSE+Author: Csaba Hruska+Maintainer: csaba (dot) hruska (at) gmail (dot) com+Homepage: http://www.haskell.org/haskellwiki/Bullet+Stability: Experimental+Category: Physics+Tested-With: GHC == 6.10.1, GHC == 6.10.4+Cabal-Version: >= 1.2+Build-Type: Simple++Extra-Source-Files: cbits/bullet.h+ Examples/BulletExample.hs+ Examples/bullet-example-1.png+ Examples/bullet-example-2.png+ README++Library+ Build-Depends: base >= 4 && < 5++ Exposed-Modules: Physics.Bullet++ Hs-Source-Dirs: .+ Extensions: ForeignFunctionInterface+ Extra-Libraries: BulletDynamics LinearMath BulletCollision++ C-Sources: cbits/bullet.cpp+ Include-Dirs: cbits
+ cbits/bullet.cpp view
@@ -0,0 +1,436 @@+/*+Bullet Continuous Collision Detection and Physics Library C API modifications+Copyright (c) 2009 Csaba Hruska++Bullet Continuous Collision Detection and Physics Library+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/++This software is provided 'as-is', without any express or implied warranty.+In no event will the authors be held liable for any damages arising from the use of this software.+Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions:++1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.+3. This notice may not be removed or altered from any source distribution.+*/++#include "bullet.h"+#include "btBulletDynamicsCommon.h"+#include "LinearMath/btAlignedAllocator.h"++++#include "LinearMath/btVector3.h"+#include "LinearMath/btScalar.h" +#include "LinearMath/btMatrix3x3.h"+#include "LinearMath/btTransform.h"+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"+#include "BulletCollision/CollisionShapes/btTriangleShape.h"++#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"+#include "BulletCollision/NarrowPhaseCollision/btPointCollector.h"+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"+#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"+#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"+#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"+#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h"+#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"+#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"+#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"+#include "LinearMath/btStackAlloc.h"++#include "BulletCollision/Gimpact/btGImpactShape.h"+#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"++/*+ Create and Delete a Physics SDK +*/++struct btPhysicsSdk+{++// btDispatcher* m_dispatcher;+// btOverlappingPairCache* m_pairCache;+// btConstraintSolver* m_constraintSolver++ btVector3 m_worldAabbMin;+ btVector3 m_worldAabbMax;+++ //todo: version, hardware/optimization settings etc?+ btPhysicsSdk()+ :m_worldAabbMin(-1000,-1000,-1000),+ m_worldAabbMax(1000,1000,1000)+ {++ }++ +};++plPhysicsSdkHandle plNewBulletSdk()+{+ void* mem = btAlignedAlloc(sizeof(btPhysicsSdk),16);+ return (plPhysicsSdkHandle)new (mem)btPhysicsSdk;+}++void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk)+{+ btPhysicsSdk* phys = reinterpret_cast<btPhysicsSdk*>(physicsSdk);+ btAlignedFree(phys); +}+++/* Dynamics World */+plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdkHandle)+{+ btPhysicsSdk* physicsSdk = reinterpret_cast<btPhysicsSdk*>(physicsSdkHandle);+ void* mem = btAlignedAlloc(sizeof(btDefaultCollisionConfiguration),16);+ btDefaultCollisionConfiguration* collisionConfiguration = new (mem)btDefaultCollisionConfiguration();+ mem = btAlignedAlloc(sizeof(btCollisionDispatcher),16);+ btCollisionDispatcher* dispatcher = new (mem)btCollisionDispatcher(collisionConfiguration);+ mem = btAlignedAlloc(sizeof(btAxisSweep3),16);+ btBroadphaseInterface* pairCache = new (mem)btAxisSweep3(physicsSdk->m_worldAabbMin,physicsSdk->m_worldAabbMax);+ mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16);+ btConstraintSolver* constraintSolver = new(mem) btSequentialImpulseConstraintSolver();++ //register algorithm+ btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);++ mem = btAlignedAlloc(sizeof(btDiscreteDynamicsWorld),16);+ return (plDynamicsWorldHandle) new (mem)btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration);+}+void plDeleteDynamicsWorld(plDynamicsWorldHandle world)+{+ //todo: also clean up the other allocations, axisSweep, pairCache,dispatcher,constraintSolver,collisionConfiguration+ btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);+ btAlignedFree(dynamicsWorld);+}++void plStepSimulation(plDynamicsWorldHandle world, plReal timeStep)+{+ btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);+ btAssert(dynamicsWorld);+ dynamicsWorld->stepSimulation(timeStep);+}++void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object)+{+ btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);+ btAssert(dynamicsWorld);+ btRigidBody* body = reinterpret_cast< btRigidBody* >(object);+ btAssert(body);++ dynamicsWorld->addRigidBody(body);+}++void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object)+{+ btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);+ btAssert(dynamicsWorld);+ btRigidBody* body = reinterpret_cast< btRigidBody* >(object);+ btAssert(body);++ dynamicsWorld->removeRigidBody(body);+}++/* Rigid Body */++plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape )+{+ btTransform trans;+ trans.setIdentity();+ btVector3 localInertia(0,0,0);+ btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);+ btAssert(shape);+ if (mass)+ {+ shape->calculateLocalInertia(mass,localInertia);+ }+ void* mem = btAlignedAlloc(sizeof(btRigidBody),16);+ btRigidBody::btRigidBodyConstructionInfo rbci(mass, 0,shape,localInertia);+ btRigidBody* body = new (mem)btRigidBody(rbci);+ body->setWorldTransform(trans);+ body->setUserPointer(user_data);+ return (plRigidBodyHandle) body;+}++void plDeleteRigidBody(plRigidBodyHandle cbody)+{+ btRigidBody* body = reinterpret_cast< btRigidBody* >(cbody);+ btAssert(body);+ btAlignedFree( body);+}+++/* Collision Shape definition */++plCollisionShapeHandle plNewSphereShape(plReal radius)+{+ void* mem = btAlignedAlloc(sizeof(btSphereShape),16);+ return (plCollisionShapeHandle) new (mem)btSphereShape(radius);+ +}+ +plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z)+{+ void* mem = btAlignedAlloc(sizeof(btBoxShape),16);+ return (plCollisionShapeHandle) new (mem)btBoxShape(btVector3(x,y,z));+}++plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height)+{+ //capsule is convex hull of 2 spheres, so use btMultiSphereShape+ + const int numSpheres = 2;+ btVector3 positions[numSpheres] = {btVector3(0,height,0),btVector3(0,-height,0)};+ btScalar radi[numSpheres] = {radius,radius};+ void* mem = btAlignedAlloc(sizeof(btMultiSphereShape),16);+ return (plCollisionShapeHandle) new (mem)btMultiSphereShape(positions,radi,numSpheres);+}+plCollisionShapeHandle plNewConeShape(plReal radius, plReal height)+{+ void* mem = btAlignedAlloc(sizeof(btConeShape),16);+ return (plCollisionShapeHandle) new (mem)btConeShape(radius,height);+}++plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height)+{+ void* mem = btAlignedAlloc(sizeof(btCylinderShape),16);+ return (plCollisionShapeHandle) new (mem)btCylinderShape(btVector3(radius,height,radius));+}++/* Convex Meshes */+plCollisionShapeHandle plNewConvexHullShape()+{+ void* mem = btAlignedAlloc(sizeof(btConvexHullShape),16);+ return (plCollisionShapeHandle) new (mem)btConvexHullShape();+}+++/* Concave static triangle meshes */+plMeshInterfaceHandle plNewMeshInterface()+{+ void* mem = btAlignedAlloc(sizeof(btTriangleMesh),16);+ return (plMeshInterfaceHandle) new (mem)btTriangleMesh();+}++void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2, int rmDup)+{+ btTriangleMesh* triangleMesh = reinterpret_cast<btTriangleMesh*>(meshHandle);+ triangleMesh->addTriangle(btVector3(v0[0],v0[1],v0[2]),btVector3(v1[0],v1[1],v1[2]),btVector3(v2[0],v2[1],v2[2]),rmDup != 0);+}++plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle meshHandle)+{+ btTriangleMesh* triangleMesh = reinterpret_cast<btTriangleMesh*>(meshHandle);+ void* mem = btAlignedAlloc(sizeof(btBvhTriangleMeshShape),16);+ return (plCollisionShapeHandle) new (mem)btBvhTriangleMeshShape(triangleMesh,true);+}++plCollisionShapeHandle plNewGimpactTriangleMeshShape(plMeshInterfaceHandle meshHandle)+{+ btTriangleMesh* triangleMesh = reinterpret_cast<btTriangleMesh*>(meshHandle);+ void* mem = btAlignedAlloc(sizeof(btGImpactMeshShape),16);+ btGImpactMeshShape* trimesh = new (mem)btGImpactMeshShape(triangleMesh);+ trimesh->updateBound();+ return (plCollisionShapeHandle) mem;+}++plCollisionShapeHandle plNewConvexTriangleMeshShape(plMeshInterfaceHandle meshHandle)+{+ btTriangleMesh* triangleMesh = reinterpret_cast<btTriangleMesh*>(meshHandle);+ void* mem = btAlignedAlloc(sizeof(btConvexTriangleMeshShape),16);+ return (plCollisionShapeHandle) new (mem)btConvexTriangleMeshShape(triangleMesh);+}++plCollisionShapeHandle plNewCompoundShape()+{+ void* mem = btAlignedAlloc(sizeof(btCompoundShape),16);+ return (plCollisionShapeHandle) new (mem)btCompoundShape();+}++void plAddChildShape(plCollisionShapeHandle compoundShapeHandle,plCollisionShapeHandle childShapeHandle, plVector3 childPos,plQuaternion childOrn)+{+ btCollisionShape* colShape = reinterpret_cast<btCollisionShape*>(compoundShapeHandle);+ btAssert(colShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE);+ btCompoundShape* compoundShape = reinterpret_cast<btCompoundShape*>(colShape);+ btCollisionShape* childShape = reinterpret_cast<btCollisionShape*>(childShapeHandle);+ btTransform localTrans;+ localTrans.setIdentity();+ localTrans.setOrigin(btVector3(childPos[0],childPos[1],childPos[2]));+ localTrans.setRotation(btQuaternion(childOrn[0],childOrn[1],childOrn[2],childOrn[3]));+ compoundShape->addChildShape(localTrans,childShape);+}++void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient)+{+ btQuaternion orn;+ orn.setEuler(yaw,pitch,roll);+ orient[0] = orn.getX();+ orient[1] = orn.getY();+ orient[2] = orn.getZ();+ orient[3] = orn.getW();++}+++++void plAddVertex(plCollisionShapeHandle cshape, plReal x,plReal y,plReal z)+{+ btCollisionShape* colShape = reinterpret_cast<btCollisionShape*>( cshape);+ (void)colShape;+ btAssert(colShape->getShapeType()==CONVEX_HULL_SHAPE_PROXYTYPE);+ btConvexHullShape* convexHullShape = reinterpret_cast<btConvexHullShape*>( cshape);+ convexHullShape->addPoint(btVector3(x,y,z));++}++void plDeleteShape(plCollisionShapeHandle cshape)+{+ btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);+ btAssert(shape);+ btAlignedFree(shape);+}+void plSetScaling(plCollisionShapeHandle cshape, plVector3 cscaling)+{+ btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);+ btAssert(shape);+ btVector3 scaling(cscaling[0],cscaling[1],cscaling[2]);+ shape->setLocalScaling(scaling); +}++void plSetPosition(plRigidBodyHandle object, const plVector3 position)+{+ btRigidBody* body = reinterpret_cast< btRigidBody* >(object);+ btAssert(body);+ btVector3 pos(position[0],position[1],position[2]);+ btTransform worldTrans = body->getWorldTransform();+ worldTrans.setOrigin(pos);+ body->setWorldTransform(worldTrans);+}++void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation)+{+ btRigidBody* body = reinterpret_cast< btRigidBody* >(object);+ btAssert(body);+ btQuaternion orn(orientation[0],orientation[1],orientation[2],orientation[3]);+ btTransform worldTrans = body->getWorldTransform();+ worldTrans.setRotation(orn);+ body->setWorldTransform(worldTrans);+}++void plSetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix)+{+ btRigidBody* body = reinterpret_cast< btRigidBody* >(object);+ btAssert(body);+ btTransform& worldTrans = body->getWorldTransform();+ worldTrans.setFromOpenGLMatrix(matrix);+}++void plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix)+{+ btRigidBody* body = reinterpret_cast< btRigidBody* >(object);+ btAssert(body);+ body->getWorldTransform().getOpenGLMatrix(matrix);++}++void plGetPosition(plRigidBodyHandle object,plVector3 position)+{+ btRigidBody* body = reinterpret_cast< btRigidBody* >(object);+ btAssert(body);+ const btVector3& pos = body->getWorldTransform().getOrigin();+ position[0] = pos.getX();+ position[1] = pos.getY();+ position[2] = pos.getZ();+}++void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation)+{+ btRigidBody* body = reinterpret_cast< btRigidBody* >(object);+ btAssert(body);+ const btQuaternion& orn = body->getWorldTransform().getRotation();+ orientation[0] = orn.getX();+ orientation[1] = orn.getY();+ orientation[2] = orn.getZ();+ orientation[3] = orn.getW();+}++++//plRigidBodyHandle plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal);++// extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal);++double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3])+{+ btVector3 vp(p1[0], p1[1], p1[2]);+ btTriangleShape trishapeA(vp, + btVector3(p2[0], p2[1], p2[2]), + btVector3(p3[0], p3[1], p3[2]));+ trishapeA.setMargin(0.000001f);+ btVector3 vq(q1[0], q1[1], q1[2]);+ btTriangleShape trishapeB(vq, + btVector3(q2[0], q2[1], q2[2]), + btVector3(q3[0], q3[1], q3[2]));+ trishapeB.setMargin(0.000001f);+ + // btVoronoiSimplexSolver sGjkSimplexSolver;+ // btGjkEpaPenetrationDepthSolver penSolverPtr; + + static btSimplexSolverInterface sGjkSimplexSolver;+ sGjkSimplexSolver.reset();+ + static btGjkEpaPenetrationDepthSolver Solver0;+ static btMinkowskiPenetrationDepthSolver Solver1;+ + btConvexPenetrationDepthSolver* Solver = NULL;+ + Solver = &Solver1; + + btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver);+ + convexConvex.m_catchDegeneracies = 1;+ + // btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,0);+ + btPointCollector gjkOutput;+ btGjkPairDetector::ClosestPointInput input;+ + btStackAlloc gStackAlloc(1024*1024*2);+ + input.m_stackAlloc = &gStackAlloc;+ + btTransform tr;+ tr.setIdentity();+ + input.m_transformA = tr;+ input.m_transformB = tr;+ + convexConvex.getClosestPoints(input, gjkOutput, 0);+ + + if (gjkOutput.m_hasResult)+ {+ + pb[0] = pa[0] = gjkOutput.m_pointInWorld[0];+ pb[1] = pa[1] = gjkOutput.m_pointInWorld[1];+ pb[2] = pa[2] = gjkOutput.m_pointInWorld[2];++ pb[0]+= gjkOutput.m_normalOnBInWorld[0] * gjkOutput.m_distance;+ pb[1]+= gjkOutput.m_normalOnBInWorld[1] * gjkOutput.m_distance;+ pb[2]+= gjkOutput.m_normalOnBInWorld[2] * gjkOutput.m_distance;+ + normal[0] = gjkOutput.m_normalOnBInWorld[0];+ normal[1] = gjkOutput.m_normalOnBInWorld[1];+ normal[2] = gjkOutput.m_normalOnBInWorld[2];++ return gjkOutput.m_distance;+ }+ return -1.0f; +}+
+ cbits/bullet.h view
@@ -0,0 +1,174 @@+/*+Bullet Continuous Collision Detection and Physics Library C API modifications+Copyright (c) 2009 Csaba Hruska++Bullet Continuous Collision Detection and Physics Library+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/++This software is provided 'as-is', without any express or implied warranty.+In no event will the authors be held liable for any damages arising from the use of this software.+Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions:++1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.+3. This notice may not be removed or altered from any source distribution.+*/++#ifndef BULLET_C_API_H+#define BULLET_C_API_H++#define PL_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name++#ifdef BT_USE_DOUBLE_PRECISION+typedef double plReal;+#else+typedef float plReal;+#endif++typedef plReal plVector3[3];+typedef plReal plQuaternion[4];++#ifdef __cplusplus+extern "C" { +#endif++/** Particular physics SDK (C-API) */+ PL_DECLARE_HANDLE(plPhysicsSdkHandle);++/** Dynamics world, belonging to some physics SDK (C-API)*/+ PL_DECLARE_HANDLE(plDynamicsWorldHandle);++/** Rigid Body that can be part of a Dynamics World (C-API)*/ + PL_DECLARE_HANDLE(plRigidBodyHandle);++/** Collision Shape/Geometry, property of a Rigid Body (C-API)*/+ PL_DECLARE_HANDLE(plCollisionShapeHandle);++/** Constraint for Rigid Bodies (C-API)*/+ PL_DECLARE_HANDLE(plConstraintHandle);++/** Triangle Mesh interface (C-API)*/+ PL_DECLARE_HANDLE(plMeshInterfaceHandle);++/** Broadphase Scene/Proxy Handles (C-API)*/+ PL_DECLARE_HANDLE(plCollisionBroadphaseHandle);+ PL_DECLARE_HANDLE(plBroadphaseProxyHandle);+ PL_DECLARE_HANDLE(plCollisionWorldHandle);++/**+ Create and Delete a Physics SDK +*/++ extern plPhysicsSdkHandle plNewBulletSdk(); //this could be also another sdk, like ODE, PhysX etc.+ extern void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk);++/** Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */++ typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2);++ extern plCollisionBroadphaseHandle plCreateSapBroadphase(btBroadphaseCallback beginCallback,btBroadphaseCallback endCallback);++ extern void plDestroyBroadphase(plCollisionBroadphaseHandle bp);++ extern plBroadphaseProxyHandle plCreateProxy(plCollisionBroadphaseHandle bp, void* clientData, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);++ extern void plDestroyProxy(plCollisionBroadphaseHandle bp, plBroadphaseProxyHandle proxyHandle);++ extern void plSetBoundingBox(plBroadphaseProxyHandle proxyHandle, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);++/* todo: add pair cache support with queries like add/remove/find pair */+ + extern plCollisionWorldHandle plCreateCollisionWorld(plPhysicsSdkHandle physicsSdk);++/* todo: add/remove objects */+ ++/* Dynamics World */++ extern plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdk);++ extern void plDeleteDynamicsWorld(plDynamicsWorldHandle world);++ extern void plStepSimulation(plDynamicsWorldHandle, plReal timeStep);++ extern void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);++ extern void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);+++/* Rigid Body */++ extern plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape );++ extern void plDeleteRigidBody(plRigidBodyHandle body);+++/* Collision Shape definition */++ extern plCollisionShapeHandle plNewSphereShape(plReal radius);+ extern plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z);+ extern plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height); + extern plCollisionShapeHandle plNewConeShape(plReal radius, plReal height);+ extern plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height);+ extern plCollisionShapeHandle plNewCompoundShape();+ extern void plAddChildShape(plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn);++ extern void plDeleteShape(plCollisionShapeHandle shape);++ /* Convex Meshes */+ extern plCollisionShapeHandle plNewConvexHullShape();+ extern void plAddVertex(plCollisionShapeHandle convexHull, plReal x,plReal y,plReal z);+ /* Concave static triangle meshes */+ extern plMeshInterfaceHandle plNewMeshInterface();+ extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2, int rmDup);+ extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);+ extern plCollisionShapeHandle plNewGimpactTriangleMeshShape(plMeshInterfaceHandle);+ extern plCollisionShapeHandle plNewConvexTriangleMeshShape(plMeshInterfaceHandle);++ extern void plSetScaling(plCollisionShapeHandle shape, plVector3 scaling);++/* SOLID has Response Callback/Table/Management */+/* PhysX has Triggers, User Callbacks and filtering */+/* ODE has the typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); */++/* typedef void plUpdatedPositionCallback(void* userData, plRigidBodyHandle rbHandle, plVector3 pos); */+/* typedef void plUpdatedOrientationCallback(void* userData, plRigidBodyHandle rbHandle, plQuaternion orientation); */++ /* get world transform */+ extern void plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix);+ extern void plGetPosition(plRigidBodyHandle object,plVector3 position);+ extern void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation);++ /* set world transform (position/orientation) */+ extern void plSetPosition(plRigidBodyHandle object, const plVector3 position);+ extern void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation);+ extern void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient);+ extern void plSetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix);++ typedef struct plRayCastResult {+ plRigidBodyHandle m_body; + plCollisionShapeHandle m_shape; + plVector3 m_positionWorld; + plVector3 m_normalWorld;+ } plRayCastResult;++ extern int plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plRayCastResult res);++ /* Sweep API */++ /* extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); */++ /* Continuous Collision Detection API */+ + // needed for source/blender/blenkernel/intern/collision.c+ double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]);++#ifdef __cplusplus+}+#endif+++#endif //BULLET_C_API_H+