/******************************************************************** Minecraft: Pocket Edition - Decompilation Project Copyright (C) 2023 iProgramInCpp The following code is licensed under the BSD 1 clause license. SPDX-License-Identifier: BSD-1-Clause ********************************************************************/ #include "AABB.hpp" AABB::AABB() { } AABB::AABB(Vec3 _min, Vec3 _max) { min = _min; max = _max; } AABB::AABB(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { min = Vec3(minX, minY, minZ); max = Vec3(maxX, maxY, maxZ); } HitResult AABB::clip(const Vec3& vec1, const Vec3& vec2) { Vec3 clipMinX, clipMinY, clipMinZ; Vec3 clipMaxX, clipMaxY, clipMaxZ; bool bClipMinX, bClipMinY, bClipMinZ; bool bClipMaxX, bClipMaxY, bClipMaxZ; bClipMinX = vec1.clipX(vec2, min.x, clipMinX) && containsX(&clipMinX); bClipMaxX = vec1.clipX(vec2, max.x, clipMaxX) && containsX(&clipMaxX); bClipMinY = vec1.clipY(vec2, min.y, clipMinY) && containsY(&clipMinY); bClipMaxY = vec1.clipY(vec2, max.y, clipMaxY) && containsY(&clipMaxY); bClipMinZ = vec1.clipZ(vec2, min.z, clipMinZ) && containsZ(&clipMinZ); bClipMaxZ = vec1.clipZ(vec2, max.z, clipMaxZ) && containsZ(&clipMaxZ); // the collided side of our AABB HitResult::eHitSide collType = HitResult::NOHIT; // the preferred vector for our collision Vec3* pVec = nullptr; if (bClipMinX) pVec = &clipMinX, collType = HitResult::MINX; if (bClipMaxX) { if (!pVec || clipMaxX.distanceToSqr(vec1) < pVec->distanceToSqr(vec1)) pVec = &clipMaxX, collType = HitResult::MAXX; } if (bClipMinY) { if (!pVec || clipMinY.distanceToSqr(vec1) < pVec->distanceToSqr(vec1)) pVec = &clipMinY, collType = HitResult::MINY; } if (bClipMaxY) { if (!pVec || clipMaxY.distanceToSqr(vec1) < pVec->distanceToSqr(vec1)) pVec = &clipMaxY, collType = HitResult::MAXY; } if (bClipMinZ) { if (!pVec || clipMinZ.distanceToSqr(vec1) < pVec->distanceToSqr(vec1)) pVec = &clipMinZ, collType = HitResult::MINZ; } if (bClipMaxZ) { if (!pVec || clipMaxZ.distanceToSqr(vec1) < pVec->distanceToSqr(vec1)) pVec = &clipMaxZ, collType = HitResult::MAXZ; } if (!pVec) { // return a nothing burger return HitResult(); } return HitResult(0, 0, 0, collType, *pVec); } float AABB::clipXCollide(const AABB& bud, float f) const { if (bud.max.y > min.y && bud.min.y < max.y && bud.max.z > min.z && bud.min.z < max.z) { if (f > 0.0f) { if (bud.max.x <= min.x) f = Mth::Min(min.x - bud.max.x, f); } if (f < 0.0f) { if (bud.min.x >= max.x) f = Mth::Max(max.x - bud.min.x, f); } } return f; } float AABB::clipYCollide(const AABB& bud, float f) const { if (bud.max.x > min.x && bud.min.x < max.x && bud.max.z > min.z && bud.min.z < max.z) { if (f > 0.0f) { if (bud.max.y <= min.y) f = Mth::Min(min.y - bud.max.y, f); } if (f < 0.0f) { if (bud.min.y >= max.y) f = Mth::Max(max.y - bud.min.y, f); } } return f; } float AABB::clipZCollide(const AABB& bud, float f) const { if (bud.max.x > min.x && bud.min.x < max.x && bud.max.y > min.y && bud.min.y < max.y) { if (f > 0.0f) { if (bud.max.z <= min.z) f = Mth::Min(min.z - bud.max.z, f); } if (f < 0.0f) { if (bud.min.z >= max.z) f = Mth::Max(max.z - bud.min.z, f); } } return f; } bool AABB::containsX(Vec3* pVec) { return pVec->y >= this->min.y && pVec->y <= this->max.y && pVec->z >= this->min.z && pVec->z <= this->max.z; } bool AABB::containsY(Vec3* pVec) { return pVec->x >= this->min.x && pVec->x <= this->max.x && pVec->z >= this->min.z && pVec->z <= this->max.z; } bool AABB::containsZ(Vec3* pVec) { return pVec->x >= this->min.x && pVec->x <= this->max.x && pVec->y >= this->min.y && pVec->y <= this->max.y; } bool AABB::intersect(const AABB& other) const { return max.x > other.min.x && min.x < other.max.x && max.y > other.min.y && min.y < other.max.y && max.z > other.min.z && min.z < other.max.z; }