packages feed

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 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+