PixelBullet  0.0.1
A C++ game engine
Loading...
Searching...
No Matches
physics_world_internal.h
1#pragma once
2
3#include "pixelbullet/physics/physics_world.h"
4
5#include <Jolt/Jolt.h>
6
7#include <Jolt/Core/JobSystemSingleThreaded.h>
8#include <Jolt/Core/TempAllocator.h>
9#include <Jolt/Physics/Body/BodyID.h>
10#include <Jolt/Physics/Body/MotionType.h>
11#include <Jolt/Physics/Collision/BroadPhase/BroadPhaseLayer.h>
12#include <Jolt/Physics/Collision/ContactListener.h>
13#include <Jolt/Physics/Collision/ObjectLayer.h>
14#include <Jolt/Physics/Collision/Shape/Shape.h>
15#include <Jolt/Physics/PhysicsSystem.h>
16
17#include <glm/gtc/quaternion.hpp>
18
19#include <cstdint>
20#include <memory>
21#include <optional>
22#include <unordered_map>
23#include <unordered_set>
24#include <vector>
25
26namespace pixelbullet
27{
28namespace physics_internal
29{
30class JoltRuntime
31{
32public:
33 JoltRuntime();
34 ~JoltRuntime();
35};
36
37namespace object_layers
38{
39constexpr JPH::ObjectLayer k_non_moving = 0;
40constexpr JPH::ObjectLayer k_moving = 1;
41} // namespace object_layers
42
43namespace broad_phase_layers
44{
45constexpr JPH::BroadPhaseLayer k_non_moving(0);
46constexpr JPH::BroadPhaseLayer k_moving(1);
47constexpr uint32_t k_count = 2;
48} // namespace broad_phase_layers
49
50class BroadPhaseLayerInterfaceImpl final : public JPH::BroadPhaseLayerInterface
51{
52public:
53 [[nodiscard]] JPH::uint GetNumBroadPhaseLayers() const override;
54 [[nodiscard]] JPH::BroadPhaseLayer GetBroadPhaseLayer(JPH::ObjectLayer layer) const override;
55};
56
57class ObjectLayerPairFilterImpl final : public JPH::ObjectLayerPairFilter
58{
59public:
60 [[nodiscard]] bool ShouldCollide(JPH::ObjectLayer layer1, JPH::ObjectLayer layer2) const override;
61};
62
63class ObjectVsBroadPhaseLayerFilterImpl final : public JPH::ObjectVsBroadPhaseLayerFilter
64{
65public:
66 [[nodiscard]] bool ShouldCollide(JPH::ObjectLayer layer1, JPH::BroadPhaseLayer layer2) const override;
67};
68
69[[nodiscard]] JPH::Quat ToJoltQuat(const glm::quat& rotation);
70[[nodiscard]] JPH::RVec3 ToJoltRVec3(const glm::vec3& value);
71[[nodiscard]] JPH::Vec3 ToJoltVec3(const glm::vec3& value);
72template <typename TVector>
73[[nodiscard]] glm::vec3 ToGlmVec3(const TVector& value)
74{
75 return glm::vec3(static_cast<float>(value.GetX()), static_cast<float>(value.GetY()), static_cast<float>(value.GetZ()));
76}
77[[nodiscard]] glm::quat ToGlmQuat(const JPH::Quat& value);
78[[nodiscard]] JPH::EMotionType ToJoltMotionType(RigidBodyMotionType type);
79[[nodiscard]] JPH::ObjectLayer ResolveObjectLayer(const PhysicsBodyCreateInfo& create_info);
80[[nodiscard]] uint32_t BuildBodyKey(JPH::BodyID body_id);
81
82[[nodiscard]] std::optional<PhysicsBodyPose> SanitizePose(const PhysicsBodyPose& pose);
83[[nodiscard]] bool IsValidColliderDescription(const PhysicsColliderDescription& collider);
84[[nodiscard]] bool IsValidBodyCreateInfo(const PhysicsBodyCreateInfo& create_info);
85[[nodiscard]] JPH::ShapeRefC CreateShape(const PhysicsColliderDescription& collider);
86} // namespace physics_internal
87
88struct PhysicsWorldImpl;
89
90class PhysicsWorldContactListener final : public JPH::ContactListener
91{
92public:
93 explicit PhysicsWorldContactListener(PhysicsWorldImpl& owner);
94
95 void OnContactAdded(const JPH::Body& body1, const JPH::Body& body2, const JPH::ContactManifold&, JPH::ContactSettings&) override;
96 void OnContactRemoved(const JPH::SubShapeIDPair& sub_shape_pair) override;
97
98private:
99 PhysicsWorldImpl& owner_;
100};
101
102struct PhysicsWorldImpl
103{
104 struct Slot
105 {
106 JPH::BodyID body_id;
107 uint32_t generation = 0;
108 bool occupied = false;
109 bool is_trigger = false;
110 };
111
112 PhysicsWorldImpl();
113
114 [[nodiscard]] bool ValidateHandle(PhysicsBodyHandle handle, uint32_t& slot_index) const;
115 [[nodiscard]] PhysicsBodyHandle MakeHandle(uint32_t slot_index) const;
116 [[nodiscard]] std::optional<uint32_t> FindSlotIndex(JPH::BodyID body_id) const;
117 void QueueDirectedTriggerEvent(uint32_t trigger_slot_index, uint32_t other_slot_index, PhysicsTriggerEventType type);
118 void QueueTriggerEvents(JPH::BodyID body1, JPH::BodyID body2, PhysicsTriggerEventType type);
119 void QueueTriggerExitEventsForSlot(uint32_t slot_index);
120 [[nodiscard]] uint32_t AcquireSlot(JPH::BodyID body_id, bool is_trigger);
121 void ReleaseSlot(uint32_t slot_index);
122 void ResetAfterClear();
123
125 physics_internal::BroadPhaseLayerInterfaceImpl broad_phase_layer_interface;
126 physics_internal::ObjectLayerPairFilterImpl object_layer_pair_filter;
127 physics_internal::ObjectVsBroadPhaseLayerFilterImpl object_vs_broad_phase_filter;
128 JPH::PhysicsSystem physics_system;
129 JPH::TempAllocatorMalloc temp_allocator;
130 JPH::JobSystemSingleThreaded job_system;
131 PhysicsWorldContactListener contact_listener;
132 std::vector<Slot> slots;
133 std::vector<uint32_t> free_slots;
134 std::unordered_map<uint32_t, uint32_t> body_keys_to_slots;
135 std::unordered_set<uint64_t> active_trigger_overlaps;
136 std::vector<PhysicsTriggerEvent> pending_trigger_events;
137};
138} // namespace pixelbullet
Definition physics_world_internal.h:91
Definition physics_world_internal.h:31
Definition physics_world_internal.h:58
Definition physics_types.h:76
Definition physics_types.h:25
Definition physics_types.h:37
Definition physics_types.h:45
Definition physics_world_internal.h:105
Definition physics_world_internal.h:103