Hipmunk-5.1.0: Physics/Hipmunk/Unsafe.hsc
-----------------------------------------------------------------------------
-- |
-- Module : Physics/Hipmunk/Unsafe.hsc
-- Copyright : (c) 2008-2010 Felipe A. Lessa
-- License : MIT (see LICENSE)
--
-- Maintainer : felipe.lessa@gmail.com
-- Stability : provisional
-- Portability : portable (needs FFI)
--
-- All functions on this module are /UNSAFE/ in the sense that
-- they may reduce the physical accuracy or numerical stability
-- of the simulation if you use them correctly, or may crash your
-- system if you are not careful enough. Read their
-- documentation carefully and use them only if you really need
-- and know what you are doing.
--
-----------------------------------------------------------------------------
module Physics.Hipmunk.Unsafe
(-- * Shapes
unsafeShapeRedefine,
-- * Constraints
unsafeRememberC
)
where
import Foreign hiding (rotate, new)
import Foreign.C
#include "wrapper.h"
import Physics.Hipmunk.Common
import Physics.Hipmunk.Internal
import Physics.Hipmunk.Shape
-- | @unsafeShapeRedefine shape type off@ redefines @shape@ to
-- have new parameters described on @type@ and to be at offset
-- @off@. Be careful, /you should not change the shape type/.
-- For example, it is unsafe to change a circle shape's radius,
-- but it is an error to try to change a circle into a segment
-- or a polygon. Note also that these errors /are not/
-- /checked/, meaning /they will probably crash Chipmunk/.
unsafeShapeRedefine :: Shape -> ShapeType -> Position -> IO ()
unsafeShapeRedefine (S shape _) (Circle r) off =
withForeignPtr shape $ \shape_ptr ->
with off $ \off_ptr -> do
cpCircleShapeSetRadius shape_ptr r
wrCircleShapeSetOffset shape_ptr off_ptr
unsafeShapeRedefine (S shape _) (LineSegment p1 p2 r) off =
withForeignPtr shape $ \shape_ptr ->
with (p1+off) $ \p1off_ptr ->
with (p2+off) $ \p2off_ptr -> do
wrSegmentShapeSetEndpoints shape_ptr p1off_ptr p2off_ptr
cpSegmentShapeSetRadius shape_ptr r
unsafeShapeRedefine (S shape _) (Polygon verts) off =
withForeignPtr shape $ \shape_ptr ->
with off $ \off_ptr ->
withArrayLen verts $ \verts_len verts_ptr -> do
let verts_len' = fromIntegral verts_len
wrPolyShapeSetVerts shape_ptr verts_len' verts_ptr off_ptr
foreign import ccall unsafe "wrapper.h"
cpCircleShapeSetRadius :: ShapePtr -> CpFloat -> IO ()
foreign import ccall unsafe "wrapper.h"
wrCircleShapeSetOffset :: ShapePtr -> VectorPtr -> IO ()
foreign import ccall unsafe "wrapper.h"
wrSegmentShapeSetEndpoints :: ShapePtr -> VectorPtr -> VectorPtr -> IO ()
foreign import ccall unsafe "wrapper.h"
cpSegmentShapeSetRadius :: ShapePtr -> CpFloat -> IO ()
foreign import ccall unsafe "wrapper.h"
wrPolyShapeSetVerts :: ShapePtr -> CInt -> VectorPtr -> VectorPtr -> IO ()
-- | Unsafe function that changes the constraint type to
-- anything. It is unsafe because you should call 'redefine'
-- only on the same kind of constraint you created, and this
-- function allows you to bypass the type system checks. Note
-- also that, unlike Chipmunk, we don't check at run-time that
-- 'redefine' is being called on the right type!
unsafeRememberC :: ConstraintType a => Constraint Unknown -> Constraint a
unsafeRememberC (C c b1 b2) = C c b1 b2
{-# INLINE unsafeRememberC #-}