This commit is contained in:
Jan Racek
2026-03-27 21:29:01 +01:00
parent 85eb7e59d9
commit bfab154547
42 changed files with 118 additions and 1013 deletions

View File

@@ -55,12 +55,6 @@ void SpatialGrid::worldToGrid(const psyqo::Vec3& pos, int& gx, int& gy, int& gz)
if (gz >= GRID_SIZE) gz = GRID_SIZE - 1;
}
int SpatialGrid::getCellIndex(const psyqo::Vec3& pos) const {
int gx, gy, gz;
worldToGrid(pos, gx, gy, gz);
return gx + gy * GRID_SIZE + gz * GRID_SIZE * GRID_SIZE;
}
void SpatialGrid::insert(uint16_t objectIndex, const AABB& bounds) {
int minGx, minGy, minGz;
int maxGx, maxGy, maxGz;
@@ -308,98 +302,4 @@ bool CollisionSystem::testAABB(const AABB& a, const AABB& b,
return true;
}
bool CollisionSystem::areColliding(uint16_t indexA, uint16_t indexB) const {
for (int i = 0; i < m_resultCount; i++) {
if ((m_results[i].objectA == indexA && m_results[i].objectB == indexB) ||
(m_results[i].objectA == indexB && m_results[i].objectB == indexA)) {
return true;
}
}
return false;
}
bool CollisionSystem::raycast(const psyqo::Vec3& origin, const psyqo::Vec3& direction,
psyqo::FixedPoint<12> maxDistance,
psyqo::Vec3& hitPoint, psyqo::Vec3& hitNormal,
uint16_t& hitObjectIndex) const {
auto closestT = maxDistance;
bool hit = false;
const FP zero(0);
const FP one(1);
const FP negOne(-1);
const FP largeVal(1000);
const FP negLargeVal(-1000);
FP epsilon;
epsilon.value = 4;
for (int i = 0; i < m_colliderCount; i++) {
const CollisionData& collider = m_colliders[i];
if (collider.type == CollisionType::None) continue;
const AABB& box = collider.bounds;
auto tMin = negLargeVal;
auto tMax = largeVal;
if (direction.x != zero) {
auto invD = one / direction.x;
auto t1 = (box.min.x - origin.x) * invD;
auto t2 = (box.max.x - origin.x) * invD;
if (t1 > t2) { auto tmp = t1; t1 = t2; t2 = tmp; }
if (t1 > tMin) tMin = t1;
if (t2 < tMax) tMax = t2;
} else if (origin.x < box.min.x || origin.x > box.max.x) {
continue;
}
if (direction.y != zero) {
auto invD = one / direction.y;
auto t1 = (box.min.y - origin.y) * invD;
auto t2 = (box.max.y - origin.y) * invD;
if (t1 > t2) { auto tmp = t1; t1 = t2; t2 = tmp; }
if (t1 > tMin) tMin = t1;
if (t2 < tMax) tMax = t2;
} else if (origin.y < box.min.y || origin.y > box.max.y) {
continue;
}
if (direction.z != zero) {
auto invD = one / direction.z;
auto t1 = (box.min.z - origin.z) * invD;
auto t2 = (box.max.z - origin.z) * invD;
if (t1 > t2) { auto tmp = t1; t1 = t2; t2 = tmp; }
if (t1 > tMin) tMin = t1;
if (t2 < tMax) tMax = t2;
} else if (origin.z < box.min.z || origin.z > box.max.z) {
continue;
}
if (tMin > tMax || tMax < zero) continue;
auto t = (tMin >= zero) ? tMin : tMax;
if (t < closestT && t >= zero) {
closestT = t;
hitObjectIndex = collider.gameObjectIndex;
hit = true;
hitPoint = psyqo::Vec3{
origin.x + direction.x * t,
origin.y + direction.y * t,
origin.z + direction.z * t
};
if ((hitPoint.x - box.min.x).abs() < epsilon) hitNormal = psyqo::Vec3{negOne, zero, zero};
else if ((hitPoint.x - box.max.x).abs() < epsilon) hitNormal = psyqo::Vec3{one, zero, zero};
else if ((hitPoint.y - box.min.y).abs() < epsilon) hitNormal = psyqo::Vec3{zero, negOne, zero};
else if ((hitPoint.y - box.max.y).abs() < epsilon) hitNormal = psyqo::Vec3{zero, one, zero};
else if ((hitPoint.z - box.min.z).abs() < epsilon) hitNormal = psyqo::Vec3{zero, zero, negOne};
else hitNormal = psyqo::Vec3{zero, zero, one};
}
}
return hit;
}
} // namespace psxsplash