| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369 |
- /*
- * Copyright (c) 2012-2023 Daniele Bartolini et al.
- * SPDX-License-Identifier: MIT
- */
- #include "config.h"
- #if CROWN_PHYSICS_BULLET
- #include "core/containers/array.inl"
- #include "core/containers/hash_map.inl"
- #include "core/math/color4.inl"
- #include "core/math/constants.h"
- #include "core/math/matrix4x4.inl"
- #include "core/math/quaternion.inl"
- #include "core/math/vector3.inl"
- #include "core/memory/proxy_allocator.h"
- #include "core/strings/string_id.inl"
- #include "device/log.h"
- #include "resource/physics_resource.h"
- #include "resource/resource_manager.h"
- #include "world/debug_line.h"
- #include "world/event_stream.inl"
- #include "world/physics.h"
- #include "world/physics_world.h"
- #include "world/unit_manager.h"
- #include <BulletCollision/BroadphaseCollision/btDbvtBroadphase.h>
- #include <BulletCollision/CollisionDispatch/btCollisionObject.h>
- #include <BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h>
- #include <BulletCollision/CollisionDispatch/btGhostObject.h>
- #include <BulletCollision/CollisionShapes/btBoxShape.h>
- #include <BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h>
- #include <BulletCollision/CollisionShapes/btCapsuleShape.h>
- #include <BulletCollision/CollisionShapes/btCompoundShape.h>
- #include <BulletCollision/CollisionShapes/btConvexHullShape.h>
- #include <BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h>
- #include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
- #include <BulletCollision/CollisionShapes/btSphereShape.h>
- #include <BulletCollision/CollisionShapes/btStaticPlaneShape.h>
- #include <BulletCollision/CollisionShapes/btTriangleMesh.h>
- #include <BulletDynamics/ConstraintSolver/btFixedConstraint.h>
- #include <BulletDynamics/ConstraintSolver/btHingeConstraint.h>
- #include <BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h>
- #include <BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h>
- #include <BulletDynamics/ConstraintSolver/btSliderConstraint.h>
- #define BT_THREADSAFE 0
- #include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
- #include <BulletDynamics/Dynamics/btRigidBody.h>
- #include <LinearMath/btDefaultMotionState.h>
- #include <LinearMath/btIDebugDraw.h>
- LOG_SYSTEM(PHYSICS, "physics")
- namespace crown
- {
- namespace physics_globals
- {
- static btDefaultCollisionConfiguration *_bt_configuration;
- static btCollisionDispatcher *_bt_dispatcher;
- static btBroadphaseInterface *_bt_interface;
- static btSequentialImpulseConstraintSolver *_bt_solver;
- void init(Allocator &a)
- {
- _bt_configuration = CE_NEW(a, btDefaultCollisionConfiguration);
- _bt_dispatcher = CE_NEW(a, btCollisionDispatcher)(_bt_configuration);
- _bt_interface = CE_NEW(a, btDbvtBroadphase);
- _bt_solver = CE_NEW(a, btSequentialImpulseConstraintSolver);
- }
- void shutdown(Allocator &a)
- {
- CE_DELETE(a, _bt_solver);
- CE_DELETE(a, _bt_interface);
- CE_DELETE(a, _bt_dispatcher);
- CE_DELETE(a, _bt_configuration);
- }
- } // namespace physics_globals
- static inline btVector3 to_btVector3(const Vector3 &v)
- {
- return btVector3(v.x, v.y, v.z);
- }
- static inline btQuaternion to_btQuaternion(const Quaternion &q)
- {
- return btQuaternion(q.x, q.y, q.z, q.w);
- }
- static inline btTransform to_btTransform(const Matrix4x4 &m)
- {
- btMatrix3x3 basis(m.x.x, m.y.x, m.z.x
- , m.x.y, m.y.y, m.z.y
- , m.x.z, m.y.z, m.z.z
- );
- btVector3 pos(m.t.x, m.t.y, m.t.z);
- return btTransform(basis, pos);
- }
- static inline Vector3 to_vector3(const btVector3 &v)
- {
- return vector3(v.x(), v.y(), v.z());
- }
- static inline Quaternion to_quaternion(const btQuaternion &q)
- {
- return from_elements(q.x(), q.y(), q.z(), q.w());
- }
- static inline Matrix4x4 to_matrix4x4(const btTransform &t)
- {
- const btVector3 x = t.getBasis().getRow(0);
- const btVector3 y = t.getBasis().getRow(1);
- const btVector3 z = t.getBasis().getRow(2);
- const btVector3 o = t.getOrigin();
- Matrix4x4 m;
- m.x.x = x.x();
- m.x.y = y.x();
- m.x.z = z.x();
- m.x.w = 0.0f;
- m.y.x = x.y();
- m.y.y = y.y();
- m.y.z = z.y();
- m.y.w = 0.0f;
- m.z.x = x.z();
- m.z.y = y.z();
- m.z.z = z.z();
- m.z.w = 0.0f;
- m.t.x = o.x();
- m.t.y = o.y();
- m.t.z = o.z();
- m.t.w = 1.0f;
- return m;
- }
- struct MyDebugDrawer : public btIDebugDraw
- {
- DebugLine *_lines;
- explicit MyDebugDrawer(DebugLine &dl)
- : _lines(&dl)
- {
- }
- void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 & /*color*/) override
- {
- const Vector3 start = to_vector3(from);
- const Vector3 end = to_vector3(to);
- _lines->add_line(start, end, COLOR4_ORANGE);
- }
- void drawContactPoint(const btVector3 &pointOnB, const btVector3 & /*normalOnB*/, btScalar /*distance*/, int /*lifeTime*/, const btVector3 & /*color*/) override
- {
- const Vector3 from = to_vector3(pointOnB);
- _lines->add_sphere(from, 0.1f, COLOR4_WHITE);
- }
- void reportErrorWarning(const char *warningString) override
- {
- logw(PHYSICS, warningString);
- }
- void draw3dText(const btVector3 & /*location*/, const char * /*textString*/) override
- {
- }
- void setDebugMode(int /*debugMode*/) override
- {
- }
- int getDebugMode() const override
- {
- return DBG_DrawWireframe
- | DBG_DrawConstraints
- | DBG_DrawConstraintLimits
- | DBG_FastWireframe
- ;
- }
- };
- struct MyFilterCallback : public btOverlapFilterCallback
- {
- bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const override
- {
- bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
- collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
- return collides;
- }
- };
- struct PhysicsWorldImpl
- {
- struct ColliderInstanceData
- {
- UnitId unit;
- Matrix4x4 local_tm;
- btTriangleIndexVertexArray *vertex_array;
- btCollisionShape *shape;
- ColliderInstance next;
- };
- struct ActorInstanceData
- {
- UnitId unit;
- btRigidBody *body;
- };
- Allocator *_allocator;
- UnitManager *_unit_manager;
- HashMap<UnitId, u32> _collider_map;
- HashMap<UnitId, u32> _actor_map;
- Array<ColliderInstanceData> _collider;
- Array<ActorInstanceData> _actor;
- Array<btTypedConstraint *> _joints;
- MyFilterCallback _filter_callback;
- btDiscreteDynamicsWorld *_dynamics_world;
- MyDebugDrawer _debug_drawer;
- EventStream _events;
- UnitDestroyCallback _unit_destroy_callback;
- const PhysicsConfigResource *_config_resource;
- bool _debug_drawing;
- PhysicsWorldImpl(Allocator &a, ResourceManager &rm, UnitManager &um, DebugLine &dl)
- : _allocator(&a)
- , _unit_manager(&um)
- , _collider_map(a)
- , _actor_map(a)
- , _collider(a)
- , _actor(a)
- , _joints(a)
- , _dynamics_world(NULL)
- , _debug_drawer(dl)
- , _events(a)
- , _debug_drawing(false)
- {
- _dynamics_world = CE_NEW(*_allocator, btDiscreteDynamicsWorld)(physics_globals::_bt_dispatcher
- , physics_globals::_bt_interface
- , physics_globals::_bt_solver
- , physics_globals::_bt_configuration
- );
- _dynamics_world->getCollisionWorld()->setDebugDrawer(&_debug_drawer);
- _dynamics_world->setInternalTickCallback(tick_cb, this);
- _dynamics_world->getPairCache()->setOverlapFilterCallback(&_filter_callback);
- _config_resource = (PhysicsConfigResource *)rm.get(RESOURCE_TYPE_PHYSICS_CONFIG, STRING_ID_64("global", 0x0b2f08fe66e395c0));
- _unit_destroy_callback.destroy = PhysicsWorldImpl::unit_destroyed_callback;
- _unit_destroy_callback.user_data = this;
- _unit_destroy_callback.node.next = NULL;
- _unit_destroy_callback.node.prev = NULL;
- um.register_destroy_callback(&_unit_destroy_callback);
- }
- ~PhysicsWorldImpl()
- {
- _unit_manager->unregister_destroy_callback(&_unit_destroy_callback);
- for (u32 i = 0; i < array::size(_actor); ++i) {
- btRigidBody *body = _actor[i].body;
- _dynamics_world->removeRigidBody(body);
- CE_DELETE(*_allocator, body->getMotionState());
- CE_DELETE(*_allocator, body->getCollisionShape());
- CE_DELETE(*_allocator, body);
- }
- for (u32 i = 0; i < array::size(_collider); ++i) {
- CE_DELETE(*_allocator, _collider[i].vertex_array);
- CE_DELETE(*_allocator, _collider[i].shape);
- }
- CE_DELETE(*_allocator, _dynamics_world);
- }
- PhysicsWorldImpl(const PhysicsWorldImpl &) = delete;
- PhysicsWorldImpl &operator=(const PhysicsWorldImpl &) = delete;
- ColliderInstance collider_create(UnitId unit, const ColliderDesc *sd, const Vector3 &scale)
- {
- btTriangleIndexVertexArray *vertex_array = NULL;
- btCollisionShape *child_shape = NULL;
- switch (sd->type) {
- case ColliderType::SPHERE:
- child_shape = CE_NEW(*_allocator, btSphereShape)(sd->sphere.radius);
- break;
- case ColliderType::CAPSULE:
- child_shape = CE_NEW(*_allocator, btCapsuleShape)(sd->capsule.radius, sd->capsule.height);
- break;
- case ColliderType::BOX:
- child_shape = CE_NEW(*_allocator, btBoxShape)(to_btVector3(sd->box.half_size));
- break;
- case ColliderType::CONVEX_HULL: {
- const u8 *data = (u8 *)&sd[1];
- const u32 num = *(u32 *)data;
- const btScalar *points = (btScalar *)(data + sizeof(u32));
- child_shape = CE_NEW(*_allocator, btConvexHullShape)(points, (int)num, sizeof(Vector3));
- break;
- }
- case ColliderType::MESH: {
- const char *data = (char *)&sd[1];
- const u32 num_points = *(u32 *)data;
- const char *points = data + sizeof(u32);
- const u32 num_indices = *(u32 *)(points + num_points*sizeof(Vector3));
- const char *indices = points + sizeof(u32) + num_points*sizeof(Vector3);
- btIndexedMesh part;
- part.m_vertexBase = (const unsigned char *)points;
- part.m_vertexStride = sizeof(Vector3);
- part.m_numVertices = num_points;
- part.m_triangleIndexBase = (const unsigned char *)indices;
- part.m_triangleIndexStride = sizeof(u16)*3;
- part.m_numTriangles = num_indices/3;
- part.m_indexType = PHY_SHORT;
- vertex_array = CE_NEW(*_allocator, btTriangleIndexVertexArray)();
- vertex_array->addIndexedMesh(part, PHY_SHORT);
- const btVector3 aabb_min(-1000.0f, -1000.0f, -1000.0f);
- const btVector3 aabb_max(1000.0f, 1000.0f, 1000.0f);
- child_shape = CE_NEW(*_allocator, btBvhTriangleMeshShape)(vertex_array, false, aabb_min, aabb_max);
- break;
- }
- case ColliderType::HEIGHTFIELD:
- CE_FATAL("Not implemented");
- break;
- default:
- CE_FATAL("Unknown shape type");
- break;
- }
- child_shape->setLocalScaling(to_btVector3(scale));
- const u32 last = array::size(_collider);
- ColliderInstanceData cid;
- cid.unit = unit;
- cid.local_tm = sd->local_tm;
- cid.vertex_array = vertex_array;
- cid.shape = child_shape;
- cid.next.i = UINT32_MAX;
- ColliderInstance ci = collider_first(unit);
- while (is_valid(ci) && is_valid(collider_next(ci)))
- ci = collider_next(ci);
- if (is_valid(ci))
- _collider[ci.i].next.i = last;
- else
- hash_map::set(_collider_map, unit, last);
- array::push_back(_collider, cid);
- return make_collider_instance(last);
- }
- void collider_destroy(ColliderInstance collider)
- {
- CE_ASSERT(collider.i < array::size(_collider), "Index out of bounds");
- const u32 last = array::size(_collider) - 1;
- const UnitId u = _collider[collider.i].unit;
- const ColliderInstance first_i = collider_first(u);
- const ColliderInstance last_i = make_collider_instance(last);
- collider_swap_node(last_i, collider);
- collider_remove_node(first_i, collider);
- CE_DELETE(*_allocator, _collider[collider.i].vertex_array);
- CE_DELETE(*_allocator, _collider[collider.i].shape);
- _collider[collider.i] = _collider[last];
- array::pop_back(_collider);
- }
- void collider_remove_node(ColliderInstance first, ColliderInstance collider)
- {
- CE_ASSERT(first.i < array::size(_collider), "Index out of bounds");
- CE_ASSERT(collider.i < array::size(_collider), "Index out of bounds");
- const UnitId u = _collider[first.i].unit;
- if (collider.i == first.i) {
- if (!is_valid(collider_next(collider)))
- hash_map::remove(_collider_map, u);
- else
- hash_map::set(_collider_map, u, collider_next(collider).i);
- } else {
- ColliderInstance prev = collider_previous(collider);
- _collider[prev.i].next = collider_next(collider);
- }
- }
- void collider_swap_node(ColliderInstance a, ColliderInstance b)
- {
- CE_ASSERT(a.i < array::size(_collider), "Index out of bounds");
- CE_ASSERT(b.i < array::size(_collider), "Index out of bounds");
- const UnitId u = _collider[a.i].unit;
- const ColliderInstance first_i = collider_first(u);
- if (a.i == first_i.i) {
- hash_map::set(_collider_map, u, b.i);
- } else {
- const ColliderInstance prev_a = collider_previous(a);
- CE_ENSURE(prev_a.i != a.i);
- _collider[prev_a.i].next = b;
- }
- }
- ColliderInstance collider_first(UnitId unit)
- {
- return make_collider_instance(hash_map::get(_collider_map, unit, UINT32_MAX));
- }
- ColliderInstance collider_next(ColliderInstance collider)
- {
- return _collider[collider.i].next;
- }
- ColliderInstance collider_previous(ColliderInstance collider)
- {
- CE_ASSERT(collider.i < array::size(_collider), "Index out of bounds");
- const UnitId u = _collider[collider.i].unit;
- ColliderInstance curr = collider_first(u);
- ColliderInstance prev = { UINT32_MAX };
- while (curr.i != collider.i) {
- prev = curr;
- curr = collider_next(curr);
- }
- return prev;
- }
- ActorInstance actor_create(UnitId unit, const ActorResource *ar, const Matrix4x4 &tm)
- {
- CE_ASSERT(!hash_map::has(_actor_map, unit), "Unit already has an actor component");
- const PhysicsActor *actor_class = physics_config_resource::actor(_config_resource, ar->actor_class);
- const PhysicsMaterial *material = physics_config_resource::material(_config_resource, ar->material);
- const bool is_kinematic = (actor_class->flags & CROWN_PHYSICS_ACTOR_KINEMATIC) != 0;
- const bool is_dynamic = (actor_class->flags & CROWN_PHYSICS_ACTOR_DYNAMIC) != 0;
- const bool is_static = !is_kinematic && !is_dynamic;
- const bool is_trigger = (actor_class->flags & CROWN_PHYSICS_ACTOR_TRIGGER) != 0;
- const f32 mass = is_dynamic ? ar->mass : 0.0f;
- // Create compound shape
- btCompoundShape *shape = CE_NEW(*_allocator, btCompoundShape)(true);
- ColliderInstance ci = collider_first(unit);
- while (is_valid(ci)) {
- shape->addChildShape(to_btTransform(_collider[ci.i].local_tm), _collider[ci.i].shape);
- ci = collider_next(ci);
- }
- // Create motion state
- const btTransform tr = to_btTransform(tm);
- btDefaultMotionState *ms = is_static
- ? NULL
- : CE_NEW(*_allocator, btDefaultMotionState)(tr)
- ;
- // If dynamic, calculate inertia
- btVector3 inertia;
- if (mass != 0.0f) // Actor is dynamic iff mass != 0
- shape->calculateLocalInertia(mass, inertia);
- btRigidBody::btRigidBodyConstructionInfo rbinfo(mass, ms, shape, inertia);
- rbinfo.m_startWorldTransform = tr;
- rbinfo.m_linearDamping = actor_class->linear_damping;
- rbinfo.m_angularDamping = actor_class->angular_damping;
- rbinfo.m_restitution = material->restitution;
- rbinfo.m_friction = material->friction;
- rbinfo.m_rollingFriction = material->rolling_friction;
- rbinfo.m_linearSleepingThreshold = 0.5f; // FIXME
- rbinfo.m_angularSleepingThreshold = 0.7f; // FIXME
- // Create rigid body
- btRigidBody *body = CE_NEW(*_allocator, btRigidBody)(rbinfo);
- int cflags = body->getCollisionFlags();
- cflags |= is_kinematic ? btCollisionObject::CF_KINEMATIC_OBJECT : 0;
- cflags |= is_static ? btCollisionObject::CF_STATIC_OBJECT : 0;
- cflags |= is_trigger ? btCollisionObject::CF_NO_CONTACT_RESPONSE : 0;
- body->setCollisionFlags(cflags);
- if (is_kinematic)
- body->setActivationState(DISABLE_DEACTIVATION);
- body->setLinearFactor(btVector3((ar->flags & ActorFlags::LOCK_TRANSLATION_X) ? 0.0f : 1.0f
- , (ar->flags & ActorFlags::LOCK_TRANSLATION_Y) ? 0.0f : 1.0f
- , (ar->flags & ActorFlags::LOCK_TRANSLATION_Z) ? 0.0f : 1.0f
- ));
- body->setAngularFactor(btVector3((ar->flags & ActorFlags::LOCK_ROTATION_X) ? 0.0f : 1.0f
- , (ar->flags & ActorFlags::LOCK_ROTATION_Y) ? 0.0f : 1.0f
- , (ar->flags & ActorFlags::LOCK_ROTATION_Z) ? 0.0f : 1.0f
- ));
- const u32 last = array::size(_actor);
- body->setUserPointer((void *)(uintptr_t)last);
- // Set collision filters
- const u32 me = physics_config_resource::filter(_config_resource, ar->collision_filter)->me;
- const u32 mask = physics_config_resource::filter(_config_resource, ar->collision_filter)->mask;
- _dynamics_world->addRigidBody(body, me, mask);
- ActorInstanceData aid;
- aid.unit = unit;
- aid.body = body;
- array::push_back(_actor, aid);
- hash_map::set(_actor_map, unit, last);
- return make_actor_instance(last);
- }
- void actor_destroy(ActorInstance actor)
- {
- const u32 last = array::size(_actor) - 1;
- const UnitId u = _actor[actor.i].unit;
- const UnitId last_u = _actor[last].unit;
- _dynamics_world->removeRigidBody(_actor[actor.i].body);
- CE_DELETE(*_allocator, _actor[actor.i].body->getMotionState());
- CE_DELETE(*_allocator, _actor[actor.i].body->getCollisionShape());
- CE_DELETE(*_allocator, _actor[actor.i].body);
- _actor[actor.i] = _actor[last];
- _actor[actor.i].body->setUserPointer((void *)(uintptr_t)actor.i);
- array::pop_back(_actor);
- hash_map::set(_actor_map, last_u, actor.i);
- hash_map::remove(_actor_map, u);
- }
- ActorInstance actor(UnitId unit)
- {
- return make_actor_instance(hash_map::get(_actor_map, unit, UINT32_MAX));
- }
- Vector3 actor_world_position(ActorInstance actor) const
- {
- return to_vector3(_actor[actor.i].body->getCenterOfMassPosition());
- }
- Quaternion actor_world_rotation(ActorInstance actor) const
- {
- return to_quaternion(_actor[actor.i].body->getOrientation());
- }
- Matrix4x4 actor_world_pose(ActorInstance actor) const
- {
- return to_matrix4x4(_actor[actor.i].body->getCenterOfMassTransform());
- }
- void actor_teleport_world_position(ActorInstance actor, const Vector3 &p)
- {
- btTransform pose = _actor[actor.i].body->getCenterOfMassTransform();
- pose.setOrigin(to_btVector3(p));
- _actor[actor.i].body->setCenterOfMassTransform(pose);
- }
- void actor_teleport_world_rotation(ActorInstance actor, const Quaternion &r)
- {
- btTransform pose = _actor[actor.i].body->getCenterOfMassTransform();
- pose.setRotation(to_btQuaternion(r));
- _actor[actor.i].body->setCenterOfMassTransform(pose);
- }
- void actor_teleport_world_pose(ActorInstance actor, const Matrix4x4 &m)
- {
- const Quaternion rot = rotation(m);
- const Vector3 pos = translation(m);
- btTransform pose = _actor[actor.i].body->getCenterOfMassTransform();
- pose.setRotation(to_btQuaternion(rot));
- pose.setOrigin(to_btVector3(pos));
- _actor[actor.i].body->setCenterOfMassTransform(pose);
- }
- Vector3 actor_center_of_mass(ActorInstance actor) const
- {
- return to_vector3(_actor[actor.i].body->getCenterOfMassTransform().getOrigin());
- }
- void actor_enable_gravity(ActorInstance actor)
- {
- btRigidBody *body = _actor[actor.i].body;
- body->setFlags(body->getFlags() & ~BT_DISABLE_WORLD_GRAVITY);
- body->setGravity(_dynamics_world->getGravity());
- }
- void actor_disable_gravity(ActorInstance actor)
- {
- btRigidBody *body = _actor[actor.i].body;
- body->setFlags(body->getFlags() | BT_DISABLE_WORLD_GRAVITY);
- body->setGravity(btVector3(0.0f, 0.0f, 0.0f));
- }
- void actor_enable_collision(ActorInstance /*i*/)
- {
- CE_FATAL("Not implemented yet");
- }
- void actor_disable_collision(ActorInstance /*i*/)
- {
- CE_FATAL("Not implemented yet");
- }
- void actor_set_collision_filter(ActorInstance /*i*/, StringId32 /*filter*/)
- {
- CE_FATAL("Not implemented yet");
- }
- void actor_set_kinematic(ActorInstance actor, bool kinematic)
- {
- btRigidBody *body = _actor[actor.i].body;
- int flags = body->getCollisionFlags();
- if (kinematic) {
- body->setCollisionFlags(flags | btCollisionObject::CF_KINEMATIC_OBJECT);
- body->setActivationState(DISABLE_DEACTIVATION);
- } else {
- body->setCollisionFlags(flags & ~btCollisionObject::CF_KINEMATIC_OBJECT);
- body->setActivationState(ACTIVE_TAG);
- }
- }
- bool actor_is_static(ActorInstance actor) const
- {
- return _actor[actor.i].body->getCollisionFlags() & btCollisionObject::CF_STATIC_OBJECT;
- }
- bool actor_is_dynamic(ActorInstance actor) const
- {
- const int flags = _actor[actor.i].body->getCollisionFlags();
- return !(flags & btCollisionObject::CF_STATIC_OBJECT)
- && !(flags & btCollisionObject::CF_KINEMATIC_OBJECT)
- ;
- }
- bool actor_is_kinematic(ActorInstance actor) const
- {
- const int flags = _actor[actor.i].body->getCollisionFlags();
- return (flags & (btCollisionObject::CF_KINEMATIC_OBJECT)) != 0;
- }
- bool actor_is_nonkinematic(ActorInstance actor) const
- {
- return actor_is_dynamic(actor) && !actor_is_kinematic(actor);
- }
- f32 actor_linear_damping(ActorInstance actor) const
- {
- return _actor[actor.i].body->getLinearDamping();
- }
- void actor_set_linear_damping(ActorInstance actor, f32 rate)
- {
- _actor[actor.i].body->setDamping(rate, _actor[actor.i].body->getAngularDamping());
- }
- f32 actor_angular_damping(ActorInstance actor) const
- {
- return _actor[actor.i].body->getAngularDamping();
- }
- void actor_set_angular_damping(ActorInstance actor, f32 rate)
- {
- _actor[actor.i].body->setDamping(_actor[actor.i].body->getLinearDamping(), rate);
- }
- Vector3 actor_linear_velocity(ActorInstance actor) const
- {
- btVector3 v = _actor[actor.i].body->getLinearVelocity();
- return to_vector3(v);
- }
- void actor_set_linear_velocity(ActorInstance actor, const Vector3 &vel)
- {
- _actor[actor.i].body->activate();
- _actor[actor.i].body->setLinearVelocity(to_btVector3(vel));
- }
- Vector3 actor_angular_velocity(ActorInstance actor) const
- {
- btVector3 v = _actor[actor.i].body->getAngularVelocity();
- return to_vector3(v);
- }
- void actor_set_angular_velocity(ActorInstance actor, const Vector3 &vel)
- {
- _actor[actor.i].body->activate();
- _actor[actor.i].body->setAngularVelocity(to_btVector3(vel));
- }
- void actor_add_impulse(ActorInstance actor, const Vector3 &impulse)
- {
- _actor[actor.i].body->activate();
- _actor[actor.i].body->applyCentralImpulse(to_btVector3(impulse));
- }
- void actor_add_impulse_at(ActorInstance actor, const Vector3 &impulse, const Vector3 &pos)
- {
- _actor[actor.i].body->activate();
- _actor[actor.i].body->applyImpulse(to_btVector3(impulse), to_btVector3(pos));
- }
- void actor_add_torque_impulse(ActorInstance actor, const Vector3 &imp)
- {
- _actor[actor.i].body->applyTorqueImpulse(to_btVector3(imp));
- }
- void actor_push(ActorInstance actor, const Vector3 &vel, f32 mass)
- {
- const Vector3 f = vel * mass;
- _actor[actor.i].body->applyCentralForce(to_btVector3(f));
- }
- void actor_push_at(ActorInstance actor, const Vector3 &vel, f32 mass, const Vector3 &pos)
- {
- const Vector3 f = vel * mass;
- _actor[actor.i].body->applyForce(to_btVector3(f), to_btVector3(pos));
- }
- bool actor_is_sleeping(ActorInstance actor)
- {
- return !_actor[actor.i].body->isActive();
- }
- void actor_wake_up(ActorInstance actor)
- {
- _actor[actor.i].body->activate(true);
- }
- JointInstance joint_create(ActorInstance a0, ActorInstance a1, const JointDesc &jd)
- {
- const btVector3 anchor_0 = to_btVector3(jd.anchor_0);
- const btVector3 anchor_1 = to_btVector3(jd.anchor_1);
- btRigidBody *body_0 = _actor[a0.i].body;
- btRigidBody *body_1 = is_valid(a1) ? _actor[a1.i].body : NULL;
- btTypedConstraint *joint = NULL;
- switch (jd.type) {
- case JointType::FIXED: {
- const btTransform frame_0 = btTransform(btQuaternion::getIdentity(), anchor_0);
- const btTransform frame_1 = btTransform(btQuaternion::getIdentity(), anchor_1);
- joint = CE_NEW(*_allocator, btFixedConstraint)(*body_0
- , *body_1
- , frame_0
- , frame_1
- );
- break;
- }
- case JointType::SPRING:
- joint = CE_NEW(*_allocator, btPoint2PointConstraint)(*body_0
- , *body_1
- , anchor_0
- , anchor_1
- );
- break;
- case JointType::HINGE: {
- btHingeConstraint *hinge = CE_NEW(*_allocator, btHingeConstraint)(*body_0
- , *body_1
- , anchor_0
- , anchor_1
- , to_btVector3(jd.hinge.axis)
- , to_btVector3(jd.hinge.axis)
- );
- hinge->enableAngularMotor(jd.hinge.use_motor
- , jd.hinge.target_velocity
- , jd.hinge.max_motor_impulse
- );
- hinge->setLimit(jd.hinge.lower_limit
- , jd.hinge.upper_limit
- , jd.hinge.bounciness
- );
- joint = hinge;
- break;
- }
- default:
- CE_FATAL("Unknown joint type");
- break;
- }
- joint->setBreakingImpulseThreshold(jd.break_force);
- _dynamics_world->addConstraint(joint);
- return make_joint_instance(UINT32_MAX);
- }
- void joint_destroy(JointInstance /*i*/)
- {
- CE_FATAL("Not implemented yet");
- }
- bool cast_ray(RaycastHit &hit, const Vector3 &from, const Vector3 &dir, f32 len)
- {
- const btVector3 aa = to_btVector3(from);
- const btVector3 bb = to_btVector3(from + dir*len);
- btCollisionWorld::ClosestRayResultCallback cb(aa, bb);
- // Collide with everything
- cb.m_collisionFilterGroup = -1;
- cb.m_collisionFilterMask = -1;
- _dynamics_world->rayTest(aa, bb, cb);
- if (cb.hasHit()) {
- const u32 actor_i = (u32)(uintptr_t)btRigidBody::upcast(cb.m_collisionObject)->getUserPointer();
- hit.position = to_vector3(cb.m_hitPointWorld);
- hit.normal = to_vector3(cb.m_hitNormalWorld);
- hit.time = (f32)cb.m_closestHitFraction;
- hit.unit = _actor[actor_i].unit;
- hit.actor.i = actor_i;
- return true;
- }
- return false;
- }
- bool cast_ray_all(Array<RaycastHit> &hits, const Vector3 &from, const Vector3 &dir, f32 len)
- {
- const btVector3 aa = to_btVector3(from);
- const btVector3 bb = to_btVector3(from + dir*len);
- btCollisionWorld::AllHitsRayResultCallback cb(aa, bb);
- // Collide with everything
- cb.m_collisionFilterGroup = -1;
- cb.m_collisionFilterMask = -1;
- _dynamics_world->rayTest(aa, bb, cb);
- if (cb.hasHit()) {
- const int num = cb.m_hitPointWorld.size();
- array::resize(hits, num);
- for (int i = 0; i < num; ++i) {
- const u32 actor_i = (u32)(uintptr_t)btRigidBody::upcast(cb.m_collisionObjects[i])->getUserPointer();
- hits[i].position = to_vector3(cb.m_hitPointWorld[i]);
- hits[i].normal = to_vector3(cb.m_hitNormalWorld[i]);
- hits[i].time = (f32)cb.m_closestHitFraction;
- hits[i].unit = _actor[actor_i].unit;
- hits[i].actor.i = actor_i;
- }
- return true;
- }
- return false;
- }
- bool cast(RaycastHit &hit, const btConvexShape *shape, const Vector3 &from, const Vector3 &dir, f32 len)
- {
- const btTransform aa(btQuaternion::getIdentity(), to_btVector3(from));
- const btTransform bb(btQuaternion::getIdentity(), to_btVector3(from + dir*len));
- btCollisionWorld::ClosestConvexResultCallback cb(btVector3(0, 0, 0), btVector3(0, 0, 0));
- // Collide with everything
- cb.m_collisionFilterGroup = -1;
- cb.m_collisionFilterMask = -1;
- _dynamics_world->convexSweepTest(shape, aa, bb, cb);
- if (cb.hasHit()) {
- const u32 actor_i = (u32)(uintptr_t)btRigidBody::upcast(cb.m_hitCollisionObject)->getUserPointer();
- hit.position = to_vector3(cb.m_hitPointWorld);
- hit.normal = to_vector3(cb.m_hitNormalWorld);
- hit.time = (f32)cb.m_closestHitFraction;
- hit.unit = _actor[actor_i].unit;
- hit.actor.i = actor_i;
- return true;
- }
- return false;
- }
- bool cast_sphere(RaycastHit &hit, const Vector3 &from, f32 radius, const Vector3 &dir, f32 len)
- {
- btSphereShape shape(radius);
- return cast(hit, &shape, from, dir, len);
- }
- bool cast_box(RaycastHit &hit, const Vector3 &from, const Vector3 &half_extents, const Vector3 &dir, f32 len)
- {
- btBoxShape shape(to_btVector3(half_extents));
- return cast(hit, &shape, from, dir, len);
- }
- Vector3 gravity() const
- {
- return to_vector3(_dynamics_world->getGravity());
- }
- void set_gravity(const Vector3 &g)
- {
- _dynamics_world->setGravity(to_btVector3(g));
- }
- void update_actor_world_poses(const UnitId *begin, const UnitId *end, const Matrix4x4 *begin_world)
- {
- for (; begin != end; ++begin, ++begin_world) {
- const u32 ai = hash_map::get(_actor_map, *begin, UINT32_MAX);
- if (ai == UINT32_MAX)
- continue;
- const Quaternion rot = rotation(*begin_world);
- const Vector3 pos = translation(*begin_world);
- // http://www.bulletphysics.org/mediawiki-1.5.8/index.php/MotionStates
- btMotionState *ms = _actor[ai].body->getMotionState();
- if (ms)
- ms->setWorldTransform(btTransform(to_btQuaternion(rot), to_btVector3(pos)));
- }
- }
- void update(f32 dt)
- {
- // 12Hz to 120Hz
- _dynamics_world->stepSimulation(dt, 7, 1.0f/60.0f);
- const int num = _dynamics_world->getNumCollisionObjects();
- const btCollisionObjectArray &collision_array = _dynamics_world->getCollisionObjectArray();
- // Update actors
- for (int i = 0; i < num; ++i) {
- if ((uintptr_t)collision_array[i]->getUserPointer() == (uintptr_t)UINT32_MAX)
- continue;
- btRigidBody *body = btRigidBody::upcast(collision_array[i]);
- if (body
- && body->getMotionState()
- && body->isActive()
- ) {
- const UnitId unit_id = _actor[(u32)(uintptr_t)body->getUserPointer()].unit;
- btTransform tr;
- body->getMotionState()->getWorldTransform(tr);
- // Post transform event
- {
- PhysicsTransformEvent ev;
- ev.unit_id = unit_id;
- ev.world = to_matrix4x4(tr);
- event_stream::write(_events, EventType::PHYSICS_TRANSFORM, ev);
- }
- }
- }
- }
- EventStream &events()
- {
- return _events;
- }
- void debug_draw()
- {
- if (!_debug_drawing)
- return;
- _dynamics_world->debugDrawWorld();
- _debug_drawer._lines->submit();
- _debug_drawer._lines->reset();
- }
- void enable_debug_drawing(bool enable)
- {
- _debug_drawing = enable;
- }
- void tick_callback(btDynamicsWorld *world, btScalar /*dt*/)
- {
- // Limit bodies velocity
- for (u32 i = 0; i < array::size(_actor); ++i) {
- CE_ENSURE(NULL != _actor[i].body);
- const btVector3 velocity = _actor[i].body->getLinearVelocity();
- const btScalar speed = velocity.length();
- if (speed > 100.0f)
- _actor[i].body->setLinearVelocity(velocity * 100.0f / speed);
- }
- // Check collisions
- int num_manifolds = world->getDispatcher()->getNumManifolds();
- for (int i = 0; i < num_manifolds; ++i) {
- const btPersistentManifold *manifold = world->getDispatcher()->getManifoldByIndexInternal(i);
- const btCollisionObject *obj_a = manifold->getBody0();
- const btCollisionObject *obj_b = manifold->getBody1();
- const ActorInstance a0 = make_actor_instance((u32)(uintptr_t)obj_a->getUserPointer());
- const ActorInstance a1 = make_actor_instance((u32)(uintptr_t)obj_b->getUserPointer());
- const UnitId u0 = _actor[a0.i].unit;
- const UnitId u1 = _actor[a1.i].unit;
- int num_contacts = manifold->getNumContacts();
- for (int j = 0; j < num_contacts; ++j) {
- const btManifoldPoint &pt = manifold->getContactPoint(j);
- if (pt.m_distance1 < 0.0f) {
- // Post collision event
- PhysicsCollisionEvent ev;
- ev.type = pt.m_lifeTime == 1 ? PhysicsCollisionEvent::TOUCH_BEGIN : PhysicsCollisionEvent::TOUCHING;
- ev.units[0] = u0;
- ev.units[1] = u1;
- ev.actors[0] = a0;
- ev.actors[1] = a1;
- ev.position = to_vector3(pt.m_positionWorldOnB);
- ev.normal = to_vector3(pt.m_normalWorldOnB);
- ev.distance = pt.m_distance1;
- event_stream::write(_events, EventType::PHYSICS_COLLISION, ev);
- }
- }
- }
- }
- void unit_destroyed_callback(UnitId unit)
- {
- {
- ActorInstance first = actor(unit);
- if (is_valid(first))
- actor_destroy(first);
- }
- {
- ColliderInstance curr = collider_first(unit);
- ColliderInstance next;
- while (is_valid(curr)) {
- next = collider_next(curr);
- collider_destroy(curr);
- curr = next;
- }
- }
- }
- static void tick_cb(btDynamicsWorld *world, btScalar dt)
- {
- PhysicsWorldImpl *bw = static_cast<PhysicsWorldImpl *>(world->getWorldUserInfo());
- bw->tick_callback(world, dt);
- }
- static void unit_destroyed_callback(UnitId unit, void *user_ptr)
- {
- static_cast<PhysicsWorldImpl *>(user_ptr)->unit_destroyed_callback(unit);
- }
- static ColliderInstance make_collider_instance(u32 i)
- {
- ColliderInstance inst = { i }; return inst;
- }
- static ActorInstance make_actor_instance(u32 i)
- {
- ActorInstance inst = { i }; return inst;
- }
- static JointInstance make_joint_instance(u32 i)
- {
- JointInstance inst = { i }; return inst;
- }
- };
- PhysicsWorld::PhysicsWorld(Allocator &a, ResourceManager &rm, UnitManager &um, DebugLine &dl)
- : _marker(PHYSICS_WORLD_MARKER)
- , _allocator(&a)
- , _impl(NULL)
- {
- _impl = CE_NEW(*_allocator, PhysicsWorldImpl)(a, rm, um, dl);
- }
- PhysicsWorld::~PhysicsWorld()
- {
- CE_DELETE(*_allocator, _impl);
- _marker = 0;
- }
- ColliderInstance PhysicsWorld::collider_create(UnitId unit, const ColliderDesc *sd, const Vector3 &scl)
- {
- return _impl->collider_create(unit, sd, scl);
- }
- void PhysicsWorld::collider_destroy(ColliderInstance collider)
- {
- _impl->collider_destroy(collider);
- }
- ColliderInstance PhysicsWorld::collider_first(UnitId unit)
- {
- return _impl->collider_first(unit);
- }
- ColliderInstance PhysicsWorld::collider_next(ColliderInstance collider)
- {
- return _impl->collider_next(collider);
- }
- ActorInstance PhysicsWorld::actor_create(UnitId unit, const ActorResource *ar, const Matrix4x4 &tm)
- {
- return _impl->actor_create(unit, ar, tm);
- }
- void PhysicsWorld::actor_destroy(ActorInstance actor)
- {
- _impl->actor_destroy(actor);
- }
- ActorInstance PhysicsWorld::actor(UnitId unit)
- {
- return _impl->actor(unit);
- }
- Vector3 PhysicsWorld::actor_world_position(ActorInstance actor) const
- {
- return _impl->actor_world_position(actor);
- }
- Quaternion PhysicsWorld::actor_world_rotation(ActorInstance actor) const
- {
- return _impl->actor_world_rotation(actor);
- }
- Matrix4x4 PhysicsWorld::actor_world_pose(ActorInstance actor) const
- {
- return _impl->actor_world_pose(actor);
- }
- void PhysicsWorld::actor_teleport_world_position(ActorInstance actor, const Vector3 &p)
- {
- _impl->actor_teleport_world_position(actor, p);
- }
- void PhysicsWorld::actor_teleport_world_rotation(ActorInstance actor, const Quaternion &r)
- {
- _impl->actor_teleport_world_rotation(actor, r);
- }
- void PhysicsWorld::actor_teleport_world_pose(ActorInstance actor, const Matrix4x4 &m)
- {
- _impl->actor_teleport_world_pose(actor, m);
- }
- Vector3 PhysicsWorld::actor_center_of_mass(ActorInstance actor) const
- {
- return _impl->actor_center_of_mass(actor);
- }
- void PhysicsWorld::actor_enable_gravity(ActorInstance actor)
- {
- _impl->actor_enable_gravity(actor);
- }
- void PhysicsWorld::actor_disable_gravity(ActorInstance actor)
- {
- _impl->actor_disable_gravity(actor);
- }
- void PhysicsWorld::actor_enable_collision(ActorInstance actor)
- {
- _impl->actor_enable_collision(actor);
- }
- void PhysicsWorld::actor_disable_collision(ActorInstance actor)
- {
- _impl->actor_disable_collision(actor);
- }
- void PhysicsWorld::actor_set_collision_filter(ActorInstance actor, StringId32 filter)
- {
- _impl->actor_set_collision_filter(actor, filter);
- }
- void PhysicsWorld::actor_set_kinematic(ActorInstance actor, bool kinematic)
- {
- _impl->actor_set_kinematic(actor, kinematic);
- }
- bool PhysicsWorld::actor_is_static(ActorInstance actor) const
- {
- return _impl->actor_is_static(actor);
- }
- bool PhysicsWorld::actor_is_dynamic(ActorInstance actor) const
- {
- return _impl->actor_is_dynamic(actor);
- }
- bool PhysicsWorld::actor_is_kinematic(ActorInstance actor) const
- {
- return _impl->actor_is_kinematic(actor);
- }
- bool PhysicsWorld::actor_is_nonkinematic(ActorInstance actor) const
- {
- return _impl->actor_is_nonkinematic(actor);
- }
- f32 PhysicsWorld::actor_linear_damping(ActorInstance actor) const
- {
- return _impl->actor_linear_damping(actor);
- }
- void PhysicsWorld::actor_set_linear_damping(ActorInstance actor, f32 rate)
- {
- _impl->actor_set_linear_damping(actor, rate);
- }
- f32 PhysicsWorld::actor_angular_damping(ActorInstance actor) const
- {
- return _impl->actor_angular_damping(actor);
- }
- void PhysicsWorld::actor_set_angular_damping(ActorInstance actor, f32 rate)
- {
- _impl->actor_set_angular_damping(actor, rate);
- }
- Vector3 PhysicsWorld::actor_linear_velocity(ActorInstance actor) const
- {
- return _impl->actor_linear_velocity(actor);
- }
- void PhysicsWorld::actor_set_linear_velocity(ActorInstance actor, const Vector3 &vel)
- {
- _impl->actor_set_linear_velocity(actor, vel);
- }
- Vector3 PhysicsWorld::actor_angular_velocity(ActorInstance actor) const
- {
- return _impl->actor_angular_velocity(actor);
- }
- void PhysicsWorld::actor_set_angular_velocity(ActorInstance actor, const Vector3 &vel)
- {
- _impl->actor_set_angular_velocity(actor, vel);
- }
- void PhysicsWorld::actor_add_impulse(ActorInstance actor, const Vector3 &impulse)
- {
- _impl->actor_add_impulse(actor, impulse);
- }
- void PhysicsWorld::actor_add_impulse_at(ActorInstance actor, const Vector3 &impulse, const Vector3 &pos)
- {
- _impl->actor_add_impulse_at(actor, impulse, pos);
- }
- void PhysicsWorld::actor_add_torque_impulse(ActorInstance actor, const Vector3 &imp)
- {
- _impl->actor_add_torque_impulse(actor, imp);
- }
- void PhysicsWorld::actor_push(ActorInstance actor, const Vector3 &vel, f32 mass)
- {
- _impl->actor_push(actor, vel, mass);
- }
- void PhysicsWorld::actor_push_at(ActorInstance actor, const Vector3 &vel, f32 mass, const Vector3 &pos)
- {
- _impl->actor_push_at(actor, vel, mass, pos);
- }
- bool PhysicsWorld::actor_is_sleeping(ActorInstance actor)
- {
- return _impl->actor_is_sleeping(actor);
- }
- void PhysicsWorld::actor_wake_up(ActorInstance actor)
- {
- _impl->actor_wake_up(actor);
- }
- JointInstance PhysicsWorld::joint_create(ActorInstance a0, ActorInstance a1, const JointDesc &jd)
- {
- return _impl->joint_create(a0, a1, jd);
- }
- void PhysicsWorld::joint_destroy(JointInstance i)
- {
- _impl->joint_destroy(i);
- }
- bool PhysicsWorld::cast_ray(RaycastHit &hit, const Vector3 &from, const Vector3 &dir, f32 len)
- {
- return _impl->cast_ray(hit, from, dir, len);
- }
- bool PhysicsWorld::cast_ray_all(Array<RaycastHit> &hits, const Vector3 &from, const Vector3 &dir, f32 len)
- {
- return _impl->cast_ray_all(hits, from, dir, len);
- }
- bool PhysicsWorld::cast_sphere(RaycastHit &hit, const Vector3 &from, f32 radius, const Vector3 &dir, f32 len)
- {
- return _impl->cast_sphere(hit, from, radius, dir, len);
- }
- bool PhysicsWorld::cast_box(RaycastHit &hit, const Vector3 &from, const Vector3 &half_extents, const Vector3 &dir, f32 len)
- {
- return _impl->cast_box(hit, from, half_extents, dir, len);
- }
- Vector3 PhysicsWorld::gravity() const
- {
- return _impl->gravity();
- }
- void PhysicsWorld::set_gravity(const Vector3 &g)
- {
- _impl->set_gravity(g);
- }
- void PhysicsWorld::update_actor_world_poses(const UnitId *begin, const UnitId *end, const Matrix4x4 *begin_world)
- {
- _impl->update_actor_world_poses(begin, end, begin_world);
- }
- void PhysicsWorld::update(f32 dt)
- {
- _impl->update(dt);
- }
- EventStream &PhysicsWorld::events()
- {
- return _impl->events();
- }
- void PhysicsWorld::debug_draw()
- {
- _impl->debug_draw();
- }
- void PhysicsWorld::enable_debug_drawing(bool enable)
- {
- _impl->enable_debug_drawing(enable);
- }
- } // namespace crown
- #endif // if CROWN_PHYSICS_BULLET
|