using OpenTK.Mathematics; namespace Voxel { public struct AABB { public Vector3 Min; public Vector3 Max; public AABB(Vector3 min, Vector3 max) { Min = min; Max = max; } public AABB Copy() { return new AABB(Min, Max); } public static AABB FromCenter(Vector3 center, float width, float height, float depth) { Vector3 half = new Vector3(width / 2f, 0, depth / 2f); return new AABB(center - half, center + new Vector3(half.X, height, half.Z)); } public AABB Expand(float x, float y, float z) { AABB returnValue = Copy(); if (x > 0) returnValue.Max.X += x; else returnValue.Min.X += x; if (y > 0) returnValue.Max.Y += y; else returnValue.Min.Y += y; if (z > 0) returnValue.Max.Z += z; else returnValue.Min.Z += z; return returnValue; } public AABB Grow(float x, float y, float z) { AABB returnValue = Copy(); returnValue.Min.X -= x; returnValue.Min.Y -= y; returnValue.Min.Z -= z; returnValue.Max.X += x; returnValue.Max.Y += y; returnValue.Max.Z += z; return returnValue; } public void Move(float x, float y, float z) { Min.X += x; Max.X += x; Min.Y += y; Max.Y += y; Min.Z += z; Max.Z += z; } public bool Contains(Vector3 point) { return (point.X >= Min.X && point.X <= Max.X) && (point.Y >= Min.Y && point.Y <= Max.Y) && (point.Z >= Min.Z && point.Z <= Max.Z); } public bool IntersectsX(AABB against) { return Min.X < against.Max.X && Max.X > against.Min.X; } public bool IntersectsY(AABB against) { return Min.Y < against.Max.Y && Max.Y > against.Min.Y; } public bool IntersectsZ(AABB against) { return Min.Z < against.Max.Z && Max.Z > against.Min.Z; } public bool Intersects(AABB against) { return IntersectsX(against) && IntersectsY(against) && IntersectsZ(against); } public float GetClipX(AABB against, float deltaX) { if (IntersectsY(against) && IntersectsZ(against)) { if (deltaX > 0 && Max.X <= against.Min.X) { float clip = against.Min.X - Max.X; if (deltaX > clip) deltaX = clip; } if (deltaX < 0 && Min.X >= against.Max.X) { float clip = against.Max.X - Min.X; if (deltaX < clip) deltaX = clip; } return deltaX; } return deltaX; } public float GetClipY(AABB against, float deltaY) { if (IntersectsX(against) && IntersectsZ(against)) { if (deltaY > 0 && Max.Y <= against.Min.Y) { float clip = against.Min.Y - Max.Y; if (deltaY > clip) deltaY = clip; } if (deltaY < 0 && Min.Y >= against.Max.Y) { float clip = against.Max.Y - Min.Y; if (deltaY < clip) deltaY = clip; } return deltaY; } return deltaY; } public float GetClipZ(AABB against, float deltaZ) { if (IntersectsX(against) && IntersectsY(against)) { if (deltaZ > 0 && Max.Z <= against.Min.Z) { float clip = against.Min.Z - Max.Z; if (deltaZ > clip) deltaZ = clip; } if (deltaZ < 0 && Min.Z >= against.Max.Z) { float clip = against.Max.Z - Min.Z; if (deltaZ < clip) deltaZ = clip; } return deltaZ; } return deltaZ; } public Vector3 GetCenter() { return new Vector3( (Min.X + Max.X) / 2, Min.Y, (Min.Z + Max.Z) / 2 ); } } }