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;
19 glm::vec3 delta = local - clamped;
20 float outsideDist = glm::length(delta);
22 glm::vec3 localNormal;
24 if (outsideDist > 0.0f) {
27 penetration = -outsideDist;
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);
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);
37 localNormal = glm::vec3(0.0f, 0.0f, (local.z > 0.0f) ? 1.0f : -1.0f);
41 glm::vec3 worldNormal = glm::normalize(rotation * localNormal);
43 return { worldPoint, worldNormal, penetration };
47 glm::vec3 localOrig = glm::inverse(rotation) * (ray.
origin - center);
48 glm::vec3 localDir = glm::inverse(rotation) * ray.
dir;
50 glm::vec3 invDir = 1.0f / localDir;
51 glm::vec3 tMinVec = (-halfExtents - localOrig) * invDir;
52 glm::vec3 tMaxVec = ( halfExtents - localOrig) * invDir;
54 glm::vec3 tsmaller = glm::min(tMinVec, tMaxVec);
55 glm::vec3 tbigger = glm::max(tMinVec, tMaxVec);
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);
60 bool hit = tmax >= std::max(tmin, 0.0f);
61 return hit ? std::optional{ tmin } : std::nullopt;
65 glm::vec3 skew, translation, scale;
68 glm::decompose(modelMatrix, scale, rot, translation, skew, persp);
70 return std::make_unique<BoxCollider>(scale * center + translation, halfExtents*scale, rot);