Monad Engine da02fba2
> Undercity Codex_
Loading...
Searching...
No Matches
KinematicCharacterController.cpp
Go to the documentation of this file.
2
3#include <BulletCollision/CollisionDispatch/btGhostObject.h>
4#include <BulletDynamics/Character/btKinematicCharacterController.h>
5#include <btBulletDynamicsCommon.h>
6
7#include "Engine.h"
8
9namespace mnd
10{
11
12KinematicCharacterController::KinematicCharacterController(float radius, float height, const glm::vec3 &position)
13 : m_height(height)
14 , m_radius(radius)
15{
18
19 // Capsule collider (standard for characters)
20 auto capsule = new btCapsuleShape(m_radius, m_height);
21
22 m_ghost = std::make_unique<btPairCachingGhostObject>();
23 btTransform start;
24 start.setIdentity();
25 start.setOrigin(btVector3(position.x, position.y, position.z));
26 m_ghost->setWorldTransform(start);
27 m_ghost->setCollisionShape(capsule);
28 m_ghost->setCollisionFlags(m_ghost->getCollisionFlags() | btCollisionObject::CF_CHARACTER_OBJECT);
29 m_ghost->setUserPointer(this);
30
31 world->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
32
33 const btScalar stepHeight = kDefaultStepHeight;
34 m_controller = std::make_unique<btKinematicCharacterController>(m_ghost.get(), capsule, stepHeight);
35
36 m_controller->setMaxSlope(btRadians(50.0F));
37 m_controller->setGravity(world->getGravity());
38
39 world->addCollisionObject(
40 m_ghost.get(),
41 btBroadphaseProxy::CharacterFilter,
42 btBroadphaseProxy::AllFilter & ~btBroadphaseProxy::SensorTrigger
43 );
44 world->addAction(m_controller.get());
45}
46
48{
50 if (m_controller)
51 {
52 world->removeAction(m_controller.get());
53 }
54 if (m_ghost)
55 {
56 world->removeCollisionObject(m_ghost.get());
57 }
58}
59
61{
62 const auto &pos = m_ghost->getWorldTransform().getOrigin();
63 // Offset upwards: camera is not at capsule center
64 const glm::vec3 offset(0.0F, m_height * 0.5F + m_radius, 0.0F);
65 return glm::vec3(pos.x(), pos.y(), pos.z()) + offset;
66}
67
69{
70 const auto &rot = m_ghost->getWorldTransform().getRotation();
71 return glm::quat(rot.w(), rot.x(), rot.y(), rot.z());
72}
73
75{
76 m_controller->setWalkDirection(btVector3(dir.x, dir.y, dir.z));
77}
78
79void KinematicCharacterController::Jump(const glm::vec3 &dir)
80{
81 if (m_controller->onGround())
82 {
83 m_controller->jump(btVector3(dir.x, dir.y, dir.z));
84 }
85}
86
88{
89 return m_controller->onGround();
90}
91
92} // namespace mnd
constexpr mnd::f32 kDefaultStepHeight
Definition Constants.h:70
CollisionObjectType m_collisionObjType
static Engine & GetInstance()
Returns the single Engine instance (created on first call).
Definition Engine.cpp:59
PhysicsManager & GetPhysicsManager()
Definition Engine.cpp:443
void Jump(const vec3 &direction)
Apply an impulse-style jump in direction (typically {0, jumpSpeed, 0}).
KinematicCharacterController(float radius, float height, const glm::vec3 &position)
void Walk(const vec3 &direction)
Apply a walk velocity in world space for this frame.
bool OnGround() const
True when the controller has a contact point beneath it.
btDiscreteDynamicsWorld * GetWorld()
Raw pointer to the underlying Bullet world (for advanced/internal use).
Capsule-shaped character controller backed by Bullet's btKinematicCharacterController.
glm::vec3 vec3
3-component float vector (e.g. world position, RGB colour, normals).
Definition Types.h:51