source: trunk/src/bullet/bullet_world.cc @ 527

Last change on this file since 527 was 527, checked in by epyon, 9 years ago
  • physics update
File size: 10.0 KB
RevLine 
[520]1// Copyright (C) 2016 ChaosForge Ltd
2// http://chaosforge.org/
3//
4// This file is part of Nova libraries.
5// For conditions of distribution and use, see copying.txt file in root folder.
6
7#include "nv/bullet/bullet_world.hh"
8
9#include "src/bullet/bullet_helper.hh"
10#include <btBulletDynamicsCommon.h>
11#include <btBulletCollisionCommon.h>
12
13using namespace nv;
14
15struct alignas( 16 ) motion_state : public btMotionState
16{
17        btTransform m_gfx_world_tr;
18        btTransform     m_com_offset;
19        btTransform     m_com_offset_inv;
20        SIMD_FORCE_INLINE void* operator new( size_t sz ) { return btAlignedAlloc( sz, 16 ); }
21        SIMD_FORCE_INLINE void  operator delete( void* ptr ) { btAlignedFree( ptr ); }
22
23        motion_state( const btTransform& start_tr = btTransform::getIdentity(), const btTransform& com_offset = btTransform::getIdentity() )
24                : m_gfx_world_tr( start_tr )
25                , m_com_offset( com_offset )
26                , m_com_offset_inv( m_com_offset.inverse() )
27        {
28        }
29
30        motion_state( const transform& startTrans = transform(), const nv::transform& com_offset = nv::transform() )
31                : m_gfx_world_tr( n2b( startTrans ) )
32                , m_com_offset( n2b( com_offset ) )
33                , m_com_offset_inv( m_com_offset.inverse() )
34        {
35        }
36
37        nv::transform get_world_transform() const
38        {
39                return b2n( m_gfx_world_tr );
40        }
41
42        void set_world_transform( const nv::transform& tr )
43        {
44                m_gfx_world_tr = n2b( tr );
45        }
46
47        virtual void    getWorldTransform( btTransform& com_world_tr ) const
48        {
49                com_world_tr = m_gfx_world_tr * m_com_offset_inv;
50        }
51
52        virtual void    setWorldTransform( const btTransform& com_world_tr )
53        {
54                m_gfx_world_tr = com_world_tr * m_com_offset;
55        }
56
57};
58
59
60#define SELF static_cast<btDiscreteDynamicsWorld*>( world )
61
62bullet_world::bullet_world()
63{
64        btBroadphaseInterface*               broadphase = new btDbvtBroadphase();
65        btDefaultCollisionConfiguration*     collisionConfiguration = new btDefaultCollisionConfiguration();
66        btCollisionDispatcher*               dispatcher = new btCollisionDispatcher( collisionConfiguration );
67        btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
68        btDiscreteDynamicsWorld*             dworld = new btDiscreteDynamicsWorld( dispatcher, broadphase, solver, collisionConfiguration );
69        world = dworld;
70}
71
72void bullet_world::set_gravity( const vec3& gravity )
73{
74        SELF->setGravity( n2b( gravity ) );
75}
76
77int nv::bullet_world::step_simulation( float dtime, int max_sub_steps /*= 1*/, float fixed_time_step /*= 1.0f / 60.0f */ )
78{
79        return SELF->stepSimulation( dtime, max_sub_steps, fixed_time_step );
80}
81
82collision_shape bullet_world::create_sphere( float radius )
83{
84        return collision_shape{ ( void* )new btSphereShape( radius ) };
85}
86
87nv::collision_shape nv::bullet_world::create_capsule( float radius, float height )
88{
89        return collision_shape{ ( void* )new btCapsuleShape( radius, height ) };
90}
91
[527]92nv::collision_shape nv::bullet_world::create_cylinder( const vec3& half_extents )
93{
94        return collision_shape{ ( void* )new btCylinderShape( n2b( half_extents ) ) };
95}
96
[520]97collision_shape bullet_world::create_box( const vec3& half_extens )
98{
99        return collision_shape{ ( void* )new btBoxShape( n2b( half_extens ) ) };
100}
101
102collision_shape bullet_world::create_static_plane( const vec3& norm, float cst )
103{
104        return collision_shape{ ( void* )new btStaticPlaneShape( n2b( norm ), cst ) };
105}
106
107void bullet_world::add_rigid_body( rigid_body body )
108{
109        SELF->addRigidBody( static_cast<btRigidBody*>( body.internal ) );
110}
111
112rigid_body bullet_world::create_rigid_body( float mass, const transform& tr, collision_shape shape, const vec3& com_offset )
113{
114        btCollisionShape* sh = static_cast<btCollisionShape*>( shape.internal );
115        bool is_dynamic = ( mass != 0.f );
116
117        btVector3 local_inertia( 0, 0, 0 );
118        if ( is_dynamic )
119                sh->calculateLocalInertia( mass, local_inertia );
120
121        motion_state* ms = new motion_state( tr, nv::transform( com_offset ) );
122
123        btRigidBody::btRigidBodyConstructionInfo rb_info( mass, ms, sh, local_inertia );
124        btRigidBody* body = new btRigidBody( rb_info );
125        return rigid_body{ body };
126}
127
[525]128nv::collision_shape nv::bullet_world::create_mesh( array_view< vec3 > vtx, array_view< uint32 > idx )
[520]129{
130        btTriangleMesh* mesh = new btTriangleMesh;
131        for ( uint32 i = 0; i < idx.size() / 3; ++i )
132        {
133                mesh->addTriangle( n2b( vtx[idx[i * 3+0]] ), n2b(vtx[idx[i * 3+1]]), n2b( vtx[idx[i * 3+ 2]] ) );
134        }
135
136//      btTriangleIndexVertexArray* array = new btTriangleIndexVertexArray( idx.size() / 3, (int*)idx.data(), 3 * sizeof(int), vtx.size(), (float*)vtx.data(), sizeof(vtx) );
137        btBvhTriangleMeshShape* shape = new btBvhTriangleMeshShape( mesh, true );
138//      shape->buildOptimizedBvh();
139        return collision_shape{ shape, nullptr };
140}
141
142constraint nv::bullet_world::create_hinge_constraint( rigid_body a, const transform& ta, rigid_body b, const transform& tb, const vec2& low_high, const vec3& params /*= vec3( 0.9f, 0.3f, 1.0f ) */ )
143{
144        btRigidBody* rba = static_cast<btRigidBody*>( a.internal );
145        btRigidBody* rbb = static_cast<btRigidBody*>( b.internal );
146        btHingeConstraint* hinge = new btHingeConstraint( *rba, *rbb, n2b( ta ), n2b( tb ) );
147        hinge->setLimit( low_high.x, low_high.y, params.x, params.y, params.z );
148        return constraint{ hinge };
149}
150
151constraint nv::bullet_world::create_cone_twist_constraint( rigid_body a, const transform& ta, rigid_body b, const transform& tb, const vec3& sst, const vec3& params /*= vec3( 1.0f, 0.3f, 1.0f ) */ )
152{
153        btRigidBody* rba = static_cast<btRigidBody*>( a.internal );
154        btRigidBody* rbb = static_cast<btRigidBody*>( b.internal );
155        btConeTwistConstraint* cone_twist = new btConeTwistConstraint( *rba, *rbb, n2b( ta ), n2b( tb ) );
156        cone_twist->setLimit( sst.x, sst.y, sst.z, params.x, params.y, params.z );
157        return constraint{ cone_twist };
158}
159
160void nv::bullet_world::remove_rigid_body( rigid_body body )
161{
162        SELF->removeRigidBody( static_cast<btRigidBody*>( body.internal ) );
163}
164
165void nv::bullet_world::add_constraint( constraint cons )
166{
167        SELF->addConstraint( static_cast<btTypedConstraint*>( cons.internal ), true );
168}
169
170void nv::bullet_world::set_rigid_body_damping( rigid_body body, float linear, float angular )
171{
172        btRigidBody* rb = static_cast<btRigidBody*>( body.internal );
173        rb->setDamping( linear, angular );
174}
175
176void nv::bullet_world::set_rigid_body_deactivation_time( rigid_body body, float time )
177{
178        btRigidBody* rb = static_cast<btRigidBody*>( body.internal );
179        rb->setDeactivationTime( time );
180}
181
182void nv::bullet_world::set_rigid_body_activation_state( rigid_body body, activation_state state )
183{
184        btRigidBody* rb = static_cast<btRigidBody*>( body.internal );
185        rb->setActivationState( state );
186}
187
188void nv::bullet_world::set_rigid_body_sleeping_thresholds( rigid_body body, float linear, float angular )
189{
190        btRigidBody* rb = static_cast<btRigidBody*>( body.internal );
191        rb->setSleepingThresholds( linear, angular );
192}
193
194void nv::bullet_world::set_rigid_body_linear_velocity( rigid_body body, const vec3& velocity )
195{
196        btRigidBody* rb = static_cast<btRigidBody*>( body.internal );
197        rb->setLinearVelocity( n2b( velocity ) );
198}
199
200void nv::bullet_world::set_rigid_body_ccd( rigid_body body, float radius, float threshold )
201{
202        btRigidBody* rb = static_cast<btRigidBody*>( body.internal );
203        rb->setCcdMotionThreshold( threshold );
204        rb->setCcdSweptSphereRadius( radius );
205}
206
207nv::transform nv::bullet_world::get_world_transform( rigid_body body )
208{
209        btRigidBody* rb = static_cast<btRigidBody*>( body.internal );
210        return static_cast<motion_state*>( rb->getMotionState() )->get_world_transform();
211}
212
213void nv::bullet_world::set_world_transform( rigid_body body, const nv::transform& tr )
214{
215        btRigidBody* rb = static_cast<btRigidBody*>( body.internal );
216        static_cast<motion_state*>( rb->getMotionState() )->set_world_transform( tr );
217}
218
219int nv::bullet_world::get_collision_flags( rigid_body body )
220{
221        btRigidBody* rb = static_cast<btRigidBody*>( body.internal );
222        return rb->getCollisionFlags();
223}
224
225void nv::bullet_world::set_collision_flags( rigid_body body, int flags )
226{
227        btRigidBody* rb = static_cast<btRigidBody*>( body.internal );
228        return rb->setCollisionFlags( flags );
229}
230
231class ClosestStaticRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
232{
233public:
234        ClosestStaticRayResultCallback( const btVector3& from, const btVector3&  to ) : btCollisionWorld::ClosestRayResultCallback( from, to ) {}
235
236        virtual btScalar addSingleResult( btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace )
237        {
238                if ( !rayResult.m_collisionObject->isStaticObject() )
239                        return 1.0;
240
241                return ClosestRayResultCallback::addSingleResult( rayResult, normalInWorldSpace );
242        }
243};
244
245
246bool nv::bullet_world::ray_test( const vec3& from, const vec3& to, vec3& hpos, vec3& hnorm, bool static_only )
247{
248        btVector3 bfrom( n2b( from ) );
249        btVector3 bto( n2b( to ) );
250        if ( !static_only )
251        {
252                btCollisionWorld::ClosestRayResultCallback raycb( bfrom, bto );
253                SELF->rayTest( bfrom, bto, raycb );
254                bool result = false;
255                if ( raycb.hasHit() )
256                {
257                        result = true;
258                        hpos = b2n( raycb.m_hitPointWorld );
259                        hnorm = b2n( raycb.m_hitNormalWorld );
260                }
261                return result;
262        }
263        else
264        {
265                ClosestStaticRayResultCallback raycb( bfrom, bto );
266                SELF->rayTest( bfrom, bto, raycb );
267                bool result = false;
268                if ( raycb.hasHit() )
269                {
270                        result = true;
271                        hpos = b2n( raycb.m_hitPointWorld );
272                        hnorm = b2n( raycb.m_hitNormalWorld );
273                }
274                return result;
275        }
276}
277
278void bullet_world::release( collision_shape sh )
279{
280        if ( !sh.internal ) return;
[525]281        if ( sh.mesh )
[520]282        {
283                btStridingMeshInterface* smi = static_cast<btStridingMeshInterface*>( sh.mesh );
284                delete smi;
285        }
286
287        btCollisionShape* cs = static_cast<btCollisionShape*>( sh.internal );
288        delete cs;
289
290}
291
292void bullet_world::release( constraint c )
293{
294        if ( !c.internal ) return;
295        btTypedConstraint* tc = static_cast<btTypedConstraint*>( c.internal );
296        SELF->removeConstraint( tc );
297        delete tc;
298}
299
300void bullet_world::release( rigid_body body )
301{
302        if ( !body.internal ) return;
303        btRigidBody* rb = static_cast<btRigidBody*>( body.internal );
304        SELF->removeRigidBody( rb );
305        delete rb;
306}
Note: See TracBrowser for help on using the repository browser.