Physics Simulation & Visualization Tool 0.1
A C++ physics simulation engine with real-time 3D visualization
Loading...
Searching...
No Matches
BoxCollider.cpp
Go to the documentation of this file.
1#include "BoxCollider.h"
2
3#include <iostream>
4#include <glm/gtx/matrix_decompose.hpp>
5
6Physics::Bounding::BoxCollider::BoxCollider(const glm::vec3 &center, const glm::vec3 &halfExtents, const glm::quat &rotation)
7 : center(center), halfExtents(halfExtents), rotation(rotation) {}
8
9bool Physics::Bounding::BoxCollider::contains(const glm::vec3 &p) const {
10 glm::vec3 local = glm::inverse(rotation) * (p - center);
11 return glm::all(glm::lessThanEqual(glm::abs(local), halfExtents));
12}
13
15 glm::vec3 local = glm::inverse(rotation) * (p - center);
16 glm::vec3 clamped = glm::clamp(local, -halfExtents, halfExtents);
17 glm::vec3 worldPoint = rotation * clamped + center;
18
19 glm::vec3 delta = local - clamped;
20 float outsideDist = glm::length(delta);
21
22 glm::vec3 localNormal;
23 float penetration;
24 if (outsideDist > 0.0f) {
25 // Point is outside: normal points from box toward point
26 localNormal = delta;
27 penetration = -outsideDist;
28 } else {
29 glm::vec3 d = halfExtents - glm::abs(local);
30 if (d.x <= d.y && d.x <= d.z) {
31 localNormal = glm::vec3((local.x > 0.0f) ? 1.0f : -1.0f, 0.0f, 0.0f);
32 penetration = d.x;
33 } else if (d.y <= d.x && d.y <= d.z) {
34 localNormal = glm::vec3(0.0f, (local.y > 0.0f) ? 1.0f : -1.0f, 0.0f);
35 penetration = d.y;
36 } else {
37 localNormal = glm::vec3(0.0f, 0.0f, (local.z > 0.0f) ? 1.0f : -1.0f);
38 penetration = d.z;
39 }
40 }
41 glm::vec3 worldNormal = glm::normalize(rotation * localNormal);
42
43 return { worldPoint, worldNormal, penetration };
44}
45
46std::optional<float> Physics::Bounding::BoxCollider::intersectRay(const Math::Ray& ray) const {
47 glm::vec3 localOrig = glm::inverse(rotation) * (ray.origin - center);
48 glm::vec3 localDir = glm::inverse(rotation) * ray.dir;
49
50 glm::vec3 invDir = 1.0f / localDir;
51 glm::vec3 tMinVec = (-halfExtents - localOrig) * invDir;
52 glm::vec3 tMaxVec = ( halfExtents - localOrig) * invDir;
53
54 glm::vec3 tsmaller = glm::min(tMinVec, tMaxVec);
55 glm::vec3 tbigger = glm::max(tMinVec, tMaxVec);
56
57 float tmin = std::max(std::max(tsmaller.x, tsmaller.y), tsmaller.z);
58 float tmax = std::min(std::min(tbigger.x, tbigger.y), tbigger.z);
59
60 bool hit = tmax >= std::max(tmin, 0.0f);
61 return hit ? std::optional{ tmin } : std::nullopt;
62}
63
64std::unique_ptr<Physics::Bounding::ICollider> Physics::Bounding::BoxCollider::getTransformed(const glm::mat4 &modelMatrix) const {
65 glm::vec3 skew, translation, scale;
66 glm::vec4 persp;
67 glm::quat rot;
68 glm::decompose(modelMatrix, scale, rot, translation, skew, persp);
69
70 return std::make_unique<BoxCollider>(scale * center + translation, halfExtents*scale, rot);
71}
72
74 glm::mat3 R = glm::mat3_cast(rotation);
75 glm::mat3 absR = glm::mat3(
76 glm::abs(R[0]),
77 glm::abs(R[1]),
78 glm::abs(R[2])
79 );
80 return center - absR * halfExtents;
81}
83 glm::mat3 R = glm::mat3_cast(rotation);
84 glm::mat3 absR = glm::mat3(
85 glm::abs(R[0]),
86 glm::abs(R[1]),
87 glm::abs(R[2])
88 );
89 return center + absR * halfExtents;
90}
91
std::optional< float > intersectRay(const Math::Ray &ray) const override
Tests ray-collider intersection.
std::unique_ptr< ICollider > getTransformed(const glm::mat4 &modelMatrix) const override
Creates a transformed copy of this collider in world space.
glm::vec3 getAABBMax() const override
bool contains(const glm::vec3 &p) const override
Tests if a point is inside the collider volume.
ContactInfo closestPoint(const glm::vec3 &p) const override
Finds the closest point on the collider surface to a given point.
glm::vec3 getAABBMin() const override
Gets the minimum, maximum corner of the axis-aligned bounding box (AABB) that contains this collider.
glm::vec3 origin
Starting point of the ray in world space.
Definition Ray.h:12
glm::vec3 dir
Direction vector (should be normalized)
Definition Ray.h:13
Represents a ray in 3D space.
Definition Ray.h:11
Contact point information from collision queries.
Definition ICollider.h:35