#ifndef __FBSPE_BI__
#define __FBSPE_BI__

' [S]imple [P]hysics [E]ngine wrapper for FreeBASIC

' limitations:
' Non-Commercial License
' Only for windows
' Not multi threding

' homepage: [url=http://spehome.com]spehome.com[/url]

' download: [url=http://www.alice-dsl.net/d.j.peters/libs/fbSPE.zip]fbSPE.zip[/url]

' For commercial License Agreements (windows,linux,mac)
' take a look at http://spehome.com/license.php


#inclib "SPEWrapper"

#define MAKECLASS(n) type n : as any ptr pThis : end type

MAKECLASS(SPEWORLD)
MAKECLASS(SPESHAPE)
MAKECLASS(SPEMESH)
MAKECLASS(SPERIGIDBODY)
MAKECLASS(SPEPHYSICSSTATE)
MAKECLASS(SPEJOINT)
MAKECLASS(SPECONSTRAINT)
MAKECLASS(SPECONTACT)
MAKECLASS(SPEPARTICLE)
MAKECLASS(SPEFLUID)

type SPEBOOL as byte ' C++ 8 bit

type SPEFLOAT as single

const as SPEFLOAT SPE_POSITIVE_INFINITE =  1.0e30
const as SPEFLOAT SPE_NEGATIVE_INFINITE = -1.0e30

type SPEVECTOR3
  as SPEFLOAT x,y,z
end type

type SPEVECTOR2
  as SPEFLOAT u,v
end type

type SPEVERTEX
  as SPEVECTOR3 p ' position
  as SPEVECTOR3 n ' normale
  as SPEVECTOR2 t ' texture
end type

type SPETRIANGLE
  as SPEVERTEX v(2)
end type

type SPEMATRIX
  declare operator cast as SPEFLOAT ptr 
  as SPEFLOAT mat(15)
end type
operator SPEMATRIX.cast as SPEFLOAT ptr
  return @mat(0)
end operator

type SPEVECTOR
  declare constructor (x_ as SPEFLOAT=0, y as SPEFLOAT=0, z as SPEFLOAT=0, w_ as SPEFLOAT=0)
  declare operator cast as SPEFLOAT ptr
  as SPEFLOAT x,y,z,w
end type

constructor SPEVECTOR(x_ as SPEFLOAT, y_ as SPEFLOAT, z_ as SPEFLOAT, w_ as SPEFLOAT)
 x=x_:y=y_:z=z_:w=w_
end constructor

operator SPEVECTOR.cast as SPEFLOAT ptr
  return @x
end operator


type SPEPLANE
  as SPEVECTOR n
  as SPEFLOAT  d
end type

type SPEJOINTDESC
  declare constructor
  declare sub Default()
  as SPERIGIDBODY ptr Body(1)
  as SPEVECTOR        BodyAnchor(1)
  as SPEVECTOR        WorldAnchor
  as SPEFLOAT         MaxDistance
  as SPEFLOAT         BreakForce
  as SPEBOOL          DetectCollision
  as SPEBOOL          CreateByWorldAnchor
end type

constructor SPEJOINTDESC
  Default()
end constructor

sub SPEJOINTDESC.Default()
  Body(0)             = 0
  Body(1)             = 0
  BodyAnchor(0)       = SPEVECTOR(0.0, 0.0, 0.0)
  BodyAnchor(1)       = SPEVECTOR(0.0, 0.0, 0.0)
  WorldAnchor         = SPEVECTOR(0.0, 0.0, 0.0)
  MaxDistance         = 0.0
  BreakForce          = -1.0
  DetectCollision     = 1 ' true
  CreateByWorldAnchor = 1 ' true
end sub


type SPECALLBACKFUNC as function cdecl (pParam as any ptr) as any ptr

type SPEHANDLE as any ptr


enum SPERESULT
  SPE_FAILED = 0
  SPE_OK     = 1
end enum

enum SPECONTACTTYPE
  SPE_CONTACT_COLLISION
  SPE_CONTACT_JOINT
  SPE_CONTACT_CUSTOM
end enum

type SPECONSTRAINTDATA
  declare constructor
  declare sub Default()
  
  as SPEVECTOR r(1) ' vector from center of mass to constraint point
  as SPEVECTOR n    ' normal
  as SPEFLOAT dv      ' desired relative velocity in normal
  as SPEFLOAT u       ' friction coefficient in tangent space
  as SPEFLOAT low     ' low and high bound of normal impulse
  as SPEFLOAT high
end type

constructor SPECONSTRAINTDATA
  Default()
end constructor

sub SPECONSTRAINTDATA.Default()
  u    = SPE_POSITIVE_INFINITE
  low  = SPE_NEGATIVE_INFINITE
  high = SPE_POSITIVE_INFINITE
end sub

type SPECASTRAYINFO
  as SPERIGIDBODY ptr Body
  as SPEVECTOR        Position
  as SPEVECTOR        Normal
  as SPEFLOAT         Distance
end type

enum SPEGROUPPHYSICSFLAG
  SPE_PHYSICS_NONE      = &H0 ' no collision detection and no solving
  SPE_PHYSICS_COLLISION = &H1 ' detect collision only but never solve
  SPE_PHYSICS_SOLVE     = &H2 ' do not detect collision but solve constraints from Joint and Custom Contact
  SPE_PHYSICS_FULL      = SPE_PHYSICS_COLLISION or SPE_PHYSICS_SOLVE ' both
end enum

enum SPEFLUIDMATERIAL
  SPE_WATER = 0
  SPE_HWATER
  SPE_SMOKE
end enum


extern "C"

' ###########
' # Helpers #
' ###########
' rotate vector around a ray (position,direction,angle)
declare function VectorRotateRay(byref vector as SPEVECTOR, byref p as SPEVECTOR, byref d as SPEVECTOR, a as SPEFLOAT) as SPEVECTOR
' rotate around a direction (direction,angle)
declare function VectorRotateDir(byref vector as SPEVECTOR, byref d as SPEVECTOR, a as SPEFLOAT) as SPEVECTOR
' create a (pitch,yaw,roll) matrix e.g. BodySetOrientation(body,MatrixXYZ(-90,45,15))
declare function MatrixXYZ(p as SPEFLOAT, y as SPEFLOAT, r as SPEFLOAT) as SPEMATRIX
' create a (pitch) matrix e.g. BodySetOrientation(body,MatrixX(-90))
declare function MatrixX(p as SPEFLOAT) as SPEMATRIX
' create a (yaw) matrix e.g. BodySetOrientation(body,MatrixY(45))
declare function MatrixY(y as SPEFLOAT) as SPEMATRIX
' create a (roll) matrix e.g. BodySetOrientation(body,MatrixZ(15))
declare function MatrixZ(r as SPEFLOAT) as SPEMATRIX

' #########
' # World #
' #########
declare function CreateWorld() as SPEWORLD ptr
declare sub      ReleaseWorld                (pWorld as SPEWORLD ptr)

declare sub      WorldSetGravity             (pWorld as SPEWORLD ptr, byref g as SPEVECTOR)
declare function WorldGetGravity             (pWorld as SPEWORLD ptr) as SPEVECTOR

declare sub      WorldSetStepTime            (pWorld as SPEWORLD ptr, dt as SPEFLOAT=0.01)
declare function WorldGetStepTime            (pWorld as SPEWORLD ptr) as SPEFLOAT

declare sub      WorldSetMaxStepPerUpdate    (pWorld as SPEWORLD ptr, nStep as integer=2)
declare function WorldGetMaxStepPerUpdate    (pWorld as SPEWORLD ptr) as integer

declare function WorldUpdate                 (pWorld as SPEWORLD ptr, dt as SPEFLOAT) as integer
declare sub      WorldDirectStep             (pWorld as SPEWORLD ptr)

declare sub      WorldSetSolverCacheFactor   (pWorld as SPEWORLD ptr, factor as SPEFLOAT)
declare function WorldGetSolverCacheFactor   (pWorld as SPEWORLD ptr) as SPEFLOAT

declare sub      WorldSetSolverPrecision     (pWorld as SPEWORLD ptr, precision as integer)
declare function WorldGetSolverPrecision     (pWorld as SPEWORLD ptr) as integer

declare sub      WorldSetCallBackPreSolve    (pWorld as SPEWORLD ptr, pFunc as SPECALLBACKFUNC, pParam as any ptr)
declare sub      WorldSetCallBackStepFinished(pWorld as SPEWORLD ptr, pFunc as SPECALLBACKFUNC, pParam as any ptr)

declare sub      WorldClear                  (pWorld as SPEWORLD ptr)
declare sub      WorldClearGarbage           (pWorld as SPEWORLD ptr)

declare sub      WorldAddGroupPhysicsFlag    (pWorld as SPEWORLD ptr, id0 as integer, id1 as integer, flag as SPEGROUPPHYSICSFLAG)
declare function WorldGetGroupPhysicsFlag    (pWorld as SPEWORLD ptr, id0 as integer, id1 as integer) as SPEGROUPPHYSICSFLAG
declare sub      WorldDeleteGroupPhysicsFlag (pWorld as SPEWORLD ptr, id0 as integer, id1 as integer)
declare function WorldGetNumGroupPhysicsFlags(pWorld as SPEWORLD ptr) as integer
declare sub      WorldClearGroupPhysicsFlag  (pWorld as SPEWORLD ptr)
' internal shape instance
declare sub      WorldSetShape(pWorld as SPEWORLD ptr, pShape as SPESHAPE ptr)
declare function WorldGetShape(pWorld as SPEWORLD ptr) as SPESHAPE ptr
' internal lists for breakable body
declare function WorldGetBreakList   (pWorld as SPEWORLD ptr) as integer
declare function WorldGetBodyListSize(pWorld as SPEWORLD ptr) as integer
declare function WorldGetBodyListItem(pWorld as SPEWORLD ptr, index as integer) as SPERIGIDBODY ptr
declare function WorldGetMeshListSize(pWorld as SPEWORLD ptr) as integer
declare function WorldGetMeshListItem(pWorld as SPEWORLD ptr, index as integer) as SPEMESH ptr

declare sub      WorldCarve                  (pWorld as SPEWORLD ptr, pBody as SPERIGIDBODY ptr, byref knife as SPEPLANE)
'declare sub     WorldCarve                  (pWorld as SPEWORLD ptr,pBody as SPERIGIDBODY ptr, SPEArray<SPEPLANE> &knives)
declare function WorldCastRay                (pWorld as SPEWORLD ptr,byref o as SPEVECTOR, byref d as SPEVECTOR, byref i as SPECASTRAYINFO) as SPEBOOL

' ########
' # Mesh #
' ########
declare function MeshInitialize      (pMesh as SPEMESH ptr, pPosition as any ptr, PositionStride as integer, pTexture as any ptr, TextureStride as integer, pIndex as integer ptr, NumTriangles as integer) as SPERESULT
declare function MeshGetData         (pMesh as SPEMESH ptr, AttribId as integer) as any ptr
declare function MeshGetNum          (pMesh as SPEMESH ptr, AttribId as integer) as integer
declare sub      MeshClear           (pMesh as SPEMESH ptr)
declare function MeshGetTriangleCount(pMesh as SPEMESH ptr) as integer
declare function MeshGetVertexPointer(pMesh as SPEMESH ptr) as SPEVERTEX ptr

' #########
' # Shape #
' #########
declare function WorldCreateShape            (pWorld as SPEWORLD ptr) as SPESHAPE ptr
declare sub      WorldReleaseShape           (pWorld as SPEWORLD ptr, pShape as SPESHAPE ptr)

declare function ShapeInitializeFromIndex32  (pShape as SPESHAPE ptr, pVertex as any ptr, StrideSize as integer, pIndex as integer ptr, NumTriangles as integer) as SPERESULT
declare function ShapeInitializeFromIndex16  (pShape as SPESHAPE ptr, pVertex as any ptr, StrideSize as integer, pIndex as short   ptr, NumTriangles as integer) as SPERESULT
declare function ShapeInitializeForStatic    (pShape as SPESHAPE ptr, pVertex as any ptr, StrideSize as integer, pIndex as integer ptr, NumTriangles as integer) as SPERESULT
declare function ShapeInitializeFromConvexHull(pShape as SPESHAPE ptr,pVertex as any ptr, StrideSize as integer, NumVertices as integer) as SPERESULT
declare function ShapeInitializeFromMesh     (pShape as SPESHAPE ptr, SPEMESH as SPEMESH) as SPERESULT
declare function ShapeInitializeAsSphere     (pShape as SPESHAPE ptr, r as SPEFLOAT) as SPERESULT
declare function ShapeInitializeAsCapsule    (pShape as SPESHAPE ptr, length as SPEFLOAT, r as SPEFLOAT) as SPERESULT
declare function ShapeGetVolume              (pShape as SPESHAPE ptr) as SPEFLOAT
declare function ShapeSetMassCenter          (pShape as SPESHAPE ptr, byref cm as SPEVECTOR) as SPERESULT
declare function ShapeGetMassCenter          (pShape as SPESHAPE ptr) as SPEVECTOR
declare function ShapeGetMesh                (pShape as SPESHAPE ptr) as SPEMESH ptr
declare function ShapeCloneTo                (pShape as SPESHAPE ptr, ppShape as SPESHAPE ptr ptr) as SPERESULT

' #############
' # RigidBody #
' #############
declare function WorldCreateRigidBody        (pWorld as SPEWORLD ptr, pShape as SPESHAPE     ptr = 0) as SPERIGIDBODY ptr
declare function WorldAddRigidBody           (pWorld as SPEWORLD ptr, pShape as SPESHAPE     ptr = 0) as SPERIGIDBODY ptr
declare function WorldDeleteRigidBody        (pWorld as SPEWORLD ptr, pBody  as SPERIGIDBODY ptr = 0) as SPERESULT

declare sub      BodySetMass                 (pBody as SPERIGIDBODY ptr, mass as SPEFLOAT)
declare function BodyGetMass                 (pBody as SPERIGIDBODY ptr) as SPEFLOAT
declare sub      BodySetDensity              (pBody as SPERIGIDBODY ptr, density as SPEFLOAT)
declare function BodyGetDensity              (pBody as SPERIGIDBODY ptr) as SPEFLOAT
declare sub      BodySetInertia              (pBody as SPERIGIDBODY ptr,byref inertia as SPEMATRIX)
declare function BodyGetInertia              (pBody as SPERIGIDBODY ptr) as SPEMATRIX
declare function BodyGetWorldInertia         (pBody as SPERIGIDBODY ptr) as SPEMATRIX

declare sub      BodySetPosition             (pBody as SPERIGIDBODY ptr,byref p as SPEVECTOR)
declare function BodyGetPosition             (pBody as SPERIGIDBODY ptr) as SPEVECTOR
declare sub      BodySetOrientation          (pBody as SPERIGIDBODY ptr,byref ort as SPEMATRIX)
declare function BodyGetOrientation          (pBody as SPERIGIDBODY ptr) as SPEMATRIX
declare sub      BodySetVelocity             (pBody as SPERIGIDBODY ptr,byref v as SPEMATRIX)
declare function BodyGetVelocity             (pBody as SPERIGIDBODY ptr) as SPEVECTOR
declare sub      BodySetAngularVelocity      (pBody as SPERIGIDBODY ptr,byref av as SPEVECTOR)
declare function BodyGetAngularVelocity      (pBody as SPERIGIDBODY ptr) as SPEVECTOR

declare sub      BodySetPositionMesh         (pBody as SPERIGIDBODY ptr,byref p as SPEVECTOR)
declare function BodyGetPositionMesh         (pBody as SPERIGIDBODY ptr) as SPEVECTOR
declare sub      BodySetOrientationMesh      (pBody as SPERIGIDBODY ptr,byref o as SPEMATRIX)
declare function BodyGetOrientationMesh      (pBody as SPERIGIDBODY ptr) as SPEMATRIX
declare sub      BodySetTransformMesh        (pBody as SPERIGIDBODY ptr,byref t as SPEMATRIX)
declare sub      BodySetTransform            (pBody as SPERIGIDBODY ptr, pmat as SPEFLOAT ptr)
declare function BodyGetTransform            (pBody as SPERIGIDBODY ptr, pmat as SPEFLOAT ptr=0) as SPEMATRIX

' Properties
declare sub      BodySetBeStatic             (pBody as SPERIGIDBODY ptr, bs as SPEBOOL)
declare function BodyGetBeStatic             (pBody as SPERIGIDBODY ptr) as SPEBOOL
declare function BodySetSleeping             (pBody as SPERIGIDBODY ptr, sleeping as SPEBOOL) as SPERESULT
declare function BodyGetSleeping             (pBody as SPERIGIDBODY ptr) as SPEBOOL
declare sub      BodySetSleepFactor          (pBody as SPERIGIDBODY ptr, factor as SPEFLOAT)
declare function BodyGetSleepFactor          (pBody as SPERIGIDBODY ptr) as SPEFLOAT
declare sub      BodySetDynamicGeneration    (pBody as SPERIGIDBODY ptr, dg as SPEBOOL)
declare function BodyGetDynamicGeneration    (pBody as SPERIGIDBODY ptr) as SPEBOOL
declare sub      BodySetExternForceField     (pBody as SPERIGIDBODY ptr,byref force as SPEVECTOR)
declare function BodyGetExternForceField     (pBody as SPERIGIDBODY ptr) as SPEVECTOR

' Materials
declare sub      BodySetDamping              (pBody as SPERIGIDBODY ptr, damping as SPEFLOAT)
declare function BodyGetDamping              (pBody as SPERIGIDBODY ptr) as SPEFLOAT
declare sub      BodySetAngularDamping       (pBody as SPERIGIDBODY ptr, angulardamping as SPEFLOAT)
declare function BodyGetAngularDamping       (pBody as SPERIGIDBODY ptr) as SPEFLOAT
declare sub      BodySetFriction             (pBody as SPERIGIDBODY ptr, friction as SPEFLOAT)
declare function BodyGetFriction             (pBody as SPERIGIDBODY ptr) as SPEFLOAT
declare sub      BodySetElasticity           (pBody as SPERIGIDBODY ptr, elasticity as SPEFLOAT)
declare function BodyGetElasticity           (pBody as SPERIGIDBODY ptr) as SPEFLOAT

' Interaction
declare sub      BodyApplyWorldImpulse       (pBody as SPERIGIDBODY ptr,byref J as SPEVECTOR, byref p as SPEVECTOR)
declare sub      BodyApplyBodyTorque         (pBody as SPERIGIDBODY ptr, byref torque as SPEVECTOR)

' Contact query
declare function BodyGetNumContacts          (pBody as SPERIGIDBODY ptr) as integer
declare function BodyGetContact              (pBody as SPERIGIDBODY ptr, index as integer) as SPECONTACT ptr
declare function BodyCastRay                 (pBody as SPERIGIDBODY ptr,byref RayPos as SPEVECTOR, byref RayDir as SPEVECTOR, byref Info as SPECASTRAYINFO) as SPEBOOL

' Physics filter
declare sub      BodyAddCollisionException   (pBody as SPERIGIDBODY ptr,pBody2 as SPERIGIDBODY ptr)
declare function BodyBeInCollisionException  (pBody as SPERIGIDBODY ptr,pBody2 as SPERIGIDBODY ptr) as SPEBOOL
declare sub      BodyDeleteCollisionException(pBody as SPERIGIDBODY ptr,pBody2 as SPERIGIDBODY ptr)

declare sub      BodySetGroupId              (pBody as SPERIGIDBODY ptr, id as integer)
declare function BodyGetGroupId              (pBody as SPERIGIDBODY ptr) as integer

' Breakable object
declare sub      BodySetBreakForce           (pBody as SPERIGIDBODY ptr, force as SPEFLOAT)
declare function BodyGetBreakForce           (pBody as SPERIGIDBODY ptr) as SPEFLOAT
declare function BodyWantBreak               (pBody as SPERIGIDBODY ptr) as SPEBOOL
declare function BodyGetBreakContact         (pBody as SPERIGIDBODY ptr) as SPECONTACT ptr 
declare sub      BodyPatternState            (pBody as SPERIGIDBODY ptr, pBody2 as SPERIGIDBODY ptr)

declare function BodyGetShape                (pBody as SPERIGIDBODY ptr) as SPESHAPE ptr

declare function BodyGetUserData             (pBody as SPERIGIDBODY ptr) as any ptr
declare sub      BodySetUserData             (pBody as SPERIGIDBODY ptr, ud as any ptr)

' #################
' # Physics state #
' #################
declare function BodyGetState                (pBody as SPERIGIDBODY ptr) as SPEPHYSICSSTATE ptr
declare function BodyGetNewState             (pBody as SPERIGIDBODY ptr) as SPEPHYSICSSTATE ptr
' Set or Get member of State for body frame
declare sub      PhysicsStateSetPosition     (pPhysicsState as SPEPHYSICSSTATE ptr,byref p as SPEVECTOR)
declare function PhysicsStateGetPosition     (pPhysicsState as SPEPHYSICSSTATE ptr) as SPEVECTOR
declare sub      PhysicsStateSetOrientation  (pPhysicsState as SPEPHYSICSSTATE ptr,byref o as SPEMATRIX)
declare function PhysicsStateGetOrientation  (pPhysicsState as SPEPHYSICSSTATE ptr) as SPEMATRIX
declare sub      PhysicsStateSetVelocity     (pPhysicsState as SPEPHYSICSSTATE ptr,byref v as SPEVECTOR)
declare function PhysicsStateGetVelocity     (pPhysicsState as SPEPHYSICSSTATE ptr) as SPEVECTOR
declare sub      PhysicsStateSetAngularVelocity(pPhysicsState as SPEPHYSICSSTATE ptr,byref av as SPEVECTOR)
declare function PhysicsStateGetAngularVelocity(pPhysicsState as SPEPHYSICSSTATE ptr) as SPEVECTOR
' Set or Get member of State for mesh frame
declare sub      PhysicsStateSetPositionMesh   (pPhysicsState as SPEPHYSICSSTATE ptr,byref p as SPEVECTOR)
declare function PhysicsStateGetPositionMesh   (pPhysicsState as SPEPHYSICSSTATE ptr) as SPEVECTOR
declare sub      PhysicsStateSetOrientationMesh(pPhysicsState as SPEPHYSICSSTATE ptr,byref o as SPEMATRIX)
declare function PhysicsStateGetOrientationMesh(pPhysicsState as SPEPHYSICSSTATE ptr) as SPEMATRIX
' Transform a point or a vector between body frame and world frame
declare function PhysicsStatePointBodyToWorld (pPhysicsState as SPEPHYSICSSTATE ptr,byref p as SPEVECTOR) as SPEVECTOR
declare function PhysicsStatePointWorldToBody (pPhysicsState as SPEPHYSICSSTATE ptr,byref p as SPEVECTOR) as SPEVECTOR
declare function PhysicsStateVectorBodyToWorld(pPhysicsState as SPEPHYSICSSTATE ptr,byref p as SPEVECTOR) as SPEVECTOR
declare function PhysicsStateVectorWorldToBody(pPhysicsState as SPEPHYSICSSTATE ptr,byref p as SPEVECTOR) as SPEVECTOR
' Get the velocity at a point in world frame
declare function PhysicsStateGetVelocityAtWorldPoint(pPhysicsState as SPEPHYSICSSTATE ptr,byref p as SPEVECTOR) as SPEVECTOR

' #########
' # Joint # (index must be 0 or 1)
' #########
declare function WorldAddJoint               (pWorld as SPEWORLD ptr, byref d as SPEJOINTDESC) as SPEJOINT ptr
declare function WorldDeleteJoint            (pWorld as SPEWORLD ptr, pJoint as SPEJOINT ptr) as SPERESULT

declare function JointGetRigidBody           (pJoint as SPEJOINT ptr, index as integer) as SPERIGIDBODY ptr
declare function JointGetWorldAnchor         (pJoint as SPEJOINT ptr) as SPEVECTOR
declare sub      JointSetBodyAnchor          (pJoint as SPEJOINT ptr, index as integer, byref anchor as SPEVECTOR)
declare function JointGetBodyAnchor          (pJoint as SPEJOINT ptr, index as integer) as SPEVECTOR
declare function JointIsBroken               (pJoint as SPEJOINT ptr) as SPEBOOL
declare function JointGetContact             (pJoint as SPEJOINT ptr) as SPECONTACT ptr

' ##############
' # Constraint #
' ##############
declare function ConstraintSetData           (pConstraint as SPECONSTRAINT ptr,byref d as SPECONSTRAINTDATA) as SPERESULT
declare sub      ConstraintGetData           (pConstraint as SPECONSTRAINT ptr,byref d as SPECONSTRAINTDATA)
declare sub      ConstraintSetEnabled        (pConstraint as SPECONSTRAINT ptr, enabled as SPEBOOL)
declare function ConstraintGetEnabled        (pConstraint as SPECONSTRAINT ptr) as SPEBOOL
declare function ConstraintGetPosition       (pConstraint as SPECONSTRAINT ptr) as SPEVECTOR
declare function ConstraintGetNormal         (pConstraint as SPECONSTRAINT ptr) as SPEVECTOR
declare function ConstraintGetImpulse        (pConstraint as SPECONSTRAINT ptr) as SPEVECTOR

' ###########
' # Contact # (index must be 0 or 1)
' ###########
declare function WorldAddCustomContact       (pWorld as SPEWORLD ptr) as SPECONTACT ptr
declare function WorldDeleteCustomContact    (pWorld as SPEWORLD ptr, pContact as SPECONTACT ptr = 0) as SPERESULT

declare sub      ContactSetRigidBody         (pContact as SPECONTACT ptr, pBody0 as SPERIGIDBODY ptr, pBody1 as  SPERIGIDBODY ptr)
declare function ContactGetRigidBody         (pContact as SPECONTACT ptr, index as integer) as SPERIGIDBODY ptr
declare function ContactAddConstraint        (pContact as SPECONTACT ptr) as SPECONSTRAINT ptr
declare function ContactDeleteConstraint     (pContact as SPECONTACT ptr, pIConstraint as SPECONSTRAINT ptr = 0) as SPERESULT
declare function ContactSetEnabled           (pContact as SPECONTACT ptr, enabled as SPEBOOL) as SPERESULT
declare function ContactGetEnabled           (pContact as SPECONTACT ptr) as SPEBOOL
declare function ContactGetNumConstraints    (pContact as SPECONTACT ptr) as integer
declare function ContactGetConstraint        (pContact as SPECONTACT ptr, index as integer) as SPECONSTRAINT ptr
declare function ContactGetVirtualConstraint (pContact as SPECONTACT ptr) as SPECONSTRAINT ptr
declare function ContactGetType              (pContact as SPECONTACT ptr) as SPECONTACTTYPE
declare function ContactGetSumImpulse        (pContact as SPECONTACT ptr, index as integer) as SPEVECTOR
declare function ContactGetSumTorque         (pContact as SPECONTACT ptr, index as integer) as SPEVECTOR

' #########
' # Fluid #
' #########
declare function WorldAddFluid               (pWorld as SPEWORLD ptr) as SPEFLUID ptr
declare function WorldDeleteFluid            (pWorld as SPEWORLD ptr, pFluid as SPEFLUID ptr = 0) as SPERESULT

declare sub      FluidSetMaterial            (pFluid as SPEFLUID ptr, m as SPEFLUIDMATERIAL)

declare function FluidGetNumParticles        (pFluid as SPEFLUID ptr) as integer
declare sub      FluidGetParticlePosition    (pFluid as SPEFLUID ptr, pData as any ptr, StrideSize as integer)
declare sub      FluidGetParticleVelocity    (pFluid as SPEFLUID ptr, pData as any ptr, StrideSize as integer)

declare sub      FluidSetMeshGeneration      (pFluid as SPEFLUID ptr, mg as SPEBOOL)
declare function FluidGetMeshGeneration      (pFluid as SPEFLUID ptr) as SPEBOOL
declare function FluidGetMesh                (pFluid as SPEFLUID ptr) as SPEMESH ptr

' ############
' # Particle #
' ############
declare function FluidAddParticle            (pFluid as SPEFLUID ptr, byref p as SPEVECTOR) as SPEPARTICLE ptr
declare function FluidAddParticleVelocity    (pFluid as SPEFLUID ptr, byref p as SPEVECTOR,byref v as SPEVECTOR) as SPEPARTICLE ptr
declare sub      FluidDeleteParticle         (pFluid as SPEFLUID ptr, pParticle as SPEPARTICLE ptr)


declare sub      ParticleSetPosition         (pParticle as SPEPARTICLE ptr,byref p as SPEVECTOR)
declare function ParticleGetPosition         (pParticle as SPEPARTICLE ptr, p as any ptr = 0) as SPEVECTOR

declare sub      ParticleSetVelocity         (pParticle as SPEPARTICLE ptr,byref v as SPEVECTOR)
declare function ParticleGetVelocity         (pParticle as SPEPARTICLE ptr, v as any ptr=0) as SPEVECTOR

end extern

#endif ' __FBSPE_BI__




