rename Aabb -> AABB

GitOrigin-RevId: 37b49d7a3ff2b4d0cf3e14e4339316bc72e2785e
This commit is contained in:
Colin McMillen 2020-01-30 16:58:42 -05:00
parent f78bff249c
commit 57b65f559c
5 changed files with 30 additions and 29 deletions

View File

@ -68,7 +68,7 @@ namespace SemiColinGames {
rects.Add(new DebugRect(rect, color)); rects.Add(new DebugRect(rect, color));
} }
public static void AddRect(Aabb box, Color color) { public static void AddRect(AABB box, Color color) {
Rectangle rect = new Rectangle( Rectangle rect = new Rectangle(
(int) (box.Position.X - box.HalfSize.X), (int) (box.Position.Y - box.HalfSize.Y), (int) (box.Position.X - box.HalfSize.X), (int) (box.Position.Y - box.HalfSize.Y),
(int) (box.HalfSize.X * 2), (int) (box.HalfSize.Y * 2)); (int) (box.HalfSize.X * 2), (int) (box.HalfSize.Y * 2));

View File

@ -6,17 +6,17 @@ using System;
namespace SemiColinGames { namespace SemiColinGames {
public readonly struct Hit { public readonly struct Hit {
public readonly Aabb Collider; public readonly AABB Collider;
public readonly Vector2 Position; public readonly Vector2 Position;
public readonly Vector2 Delta; public readonly Vector2 Delta;
public readonly Vector2 Normal; public readonly Vector2 Normal;
public readonly float Time; // ranges from [0, 1]. public readonly float Time; // ranges from [0, 1].
public Hit(Aabb collider, Vector2 position, Vector2 delta, Vector2 normal) : public Hit(AABB collider, Vector2 position, Vector2 delta, Vector2 normal) :
this(collider, position, delta, normal, 0.0f) { this(collider, position, delta, normal, 0.0f) {
} }
public Hit(Aabb collider, Vector2 position, Vector2 delta, Vector2 normal, float time) { public Hit(AABB collider, Vector2 position, Vector2 delta, Vector2 normal, float time) {
Collider = collider; Collider = collider;
Position = position; Position = position;
Delta = delta; Delta = delta;
@ -37,7 +37,7 @@ namespace SemiColinGames {
} }
} }
public readonly struct Aabb { public readonly struct AABB {
public readonly Vector2 Position; // centroid public readonly Vector2 Position; // centroid
public readonly Vector2 HalfSize; public readonly Vector2 HalfSize;
@ -51,12 +51,12 @@ namespace SemiColinGames {
} }
} }
public Aabb(Vector2 position, Vector2 halfSize) { public AABB(Vector2 position, Vector2 halfSize) {
Position = position; Position = position;
HalfSize = halfSize; HalfSize = halfSize;
} }
public Hit? Intersect(Aabb box) { public Hit? Intersect(AABB box) {
float dx = box.Position.X - Position.X; float dx = box.Position.X - Position.X;
float px = box.HalfSize.X + HalfSize.X - Math.Abs(dx); float px = box.HalfSize.X + HalfSize.X - Math.Abs(dx);
if (px <= 0) { if (px <= 0) {
@ -121,7 +121,7 @@ namespace SemiColinGames {
return new Hit(this, hitPos, hitDelta, normal, hitTime); return new Hit(this, hitPos, hitDelta, normal, hitTime);
} }
public Sweep Sweep(Aabb box, Vector2 delta) { public Sweep Sweep(AABB box, Vector2 delta) {
// fast-path case if the other box is static // fast-path case if the other box is static
if (delta.X == 0 && delta.Y == 0) { if (delta.X == 0 && delta.Y == 0) {
Hit? staticHit = Intersect(box); Hit? staticHit = Intersect(box);

View File

@ -46,25 +46,26 @@ namespace SemiColinGames {
public Point Position { get { return position; } } public Point Position { get { return position; } }
public void Update(float modelTime, History<Input> input, Aabb[] collisionTargets) { public void Update(float modelTime, History<Input> input, AABB[] collisionTargets) {
Aabb BoxOffset(Point position, int yOffset) { AABB BoxOffset(Point position, int yOffset) {
return new Aabb(new Vector2(position.X, position.Y + yOffset), halfSize); return new AABB(new Vector2(position.X, position.Y + yOffset), halfSize);
} }
Aabb Box(Point position) { AABB Box(Point position) {
return BoxOffset(position, 0); return BoxOffset(position, 0);
} }
Vector2 movement = HandleInput(modelTime, input); Vector2 movement = HandleInput(modelTime, input);
// Broad test: remove all collision targets nowhere near the player. // Broad test: remove all collision targets nowhere near the player.
var candidates = new List<Aabb>(); // TODO: don't allocate a list here.
var candidates = new List<AABB>();
// Expand the box in the direction of movement. The center is the midpoint of the line // Expand the box in the direction of movement. The center is the midpoint of the line
// between the player's current position and their desired movement. The width increases by // between the player's current position and their desired movement. The width increases by
// the magnitude of the movement in each direction. We add 1 to each dimension just to be // the magnitude of the movement in each direction. We add 1 to each dimension just to be
// sure (the only downside is a small number of false-positive AABBs, which should be // sure (the only downside is a small number of false-positive AABBs, which should be
// discarded by later tests anyhow.) // discarded by later tests anyhow.)
Aabb largeBox = new Aabb( AABB largeBox = new AABB(
new Vector2(position.X + movement.X / 2, position.Y + movement.Y / 2), new Vector2(position.X + movement.X / 2, position.Y + movement.Y / 2),
new Vector2(halfSize.X + Math.Abs(movement.X) + 1, halfSize.Y + Math.Abs(movement.Y) + 1)); new Vector2(halfSize.X + Math.Abs(movement.X) + 1, halfSize.Y + Math.Abs(movement.Y) + 1));
foreach (var box in collisionTargets) { foreach (var box in collisionTargets) {
@ -80,7 +81,7 @@ namespace SemiColinGames {
int dy = movePoints[i].Y - movePoints[i - 1].Y; int dy = movePoints[i].Y - movePoints[i - 1].Y;
if (dy != 0) { if (dy != 0) {
Point newPosition = new Point(position.X, position.Y + dy); Point newPosition = new Point(position.X, position.Y + dy);
Aabb player = Box(newPosition); AABB player = Box(newPosition);
bool reject = false; bool reject = false;
foreach (var box in candidates) { foreach (var box in candidates) {
if (box.Intersect(player) != null) { if (box.Intersect(player) != null) {
@ -94,7 +95,7 @@ namespace SemiColinGames {
} }
if (dx != 0) { if (dx != 0) {
Point newPosition = new Point(position.X + dx, position.Y); Point newPosition = new Point(position.X + dx, position.Y);
Aabb player = Box(newPosition); AABB player = Box(newPosition);
bool reject = false; bool reject = false;
foreach (var box in candidates) { foreach (var box in candidates) {
if (box.Intersect(player) != null) { if (box.Intersect(player) != null) {
@ -109,7 +110,7 @@ namespace SemiColinGames {
} }
bool standingOnGround = false; bool standingOnGround = false;
Aabb groundIntersect = BoxOffset(position, 1); AABB groundIntersect = BoxOffset(position, 1);
foreach (var box in candidates) { foreach (var box in candidates) {
if (groundIntersect.Intersect(box) != null) { if (groundIntersect.Intersect(box) != null) {
standingOnGround = true; standingOnGround = true;

View File

@ -166,21 +166,21 @@ namespace SemiColinGames {
// Because we added tiles from left to right, the CollisionTargets are sorted by x-position. // Because we added tiles from left to right, the CollisionTargets are sorted by x-position.
// We maintain this invariant so that it's possible to efficiently find CollisionTargets that // We maintain this invariant so that it's possible to efficiently find CollisionTargets that
// are nearby a given x-position. // are nearby a given x-position.
CollisionTargets = new Aabb[tiles.Length + 2]; CollisionTargets = new AABB[tiles.Length + 2];
// Add a synthetic collisionTarget on the left side of the world. // Add a synthetic collisionTarget on the left side of the world.
CollisionTargets[0] = new Aabb(new Vector2(-1, 0), new Vector2(1, float.MaxValue)); CollisionTargets[0] = new AABB(new Vector2(-1, 0), new Vector2(1, float.MaxValue));
// Now add all the normal collisionTargets for every static terrain tile. // Now add all the normal collisionTargets for every static terrain tile.
Vector2 halfSize = new Vector2(TileSize / 2, TileSize / 2); Vector2 halfSize = new Vector2(TileSize / 2, TileSize / 2);
for (int i = 0; i < tiles.Length; i++) { for (int i = 0; i < tiles.Length; i++) {
Vector2 center = new Vector2( Vector2 center = new Vector2(
tiles[i].Position.Left + halfSize.X, tiles[i].Position.Top + halfSize.Y); tiles[i].Position.Left + halfSize.X, tiles[i].Position.Top + halfSize.Y);
CollisionTargets[i + 1] = new Aabb(center, halfSize); CollisionTargets[i + 1] = new AABB(center, halfSize);
} }
// Add a final synthetic collisionTarget on the right side of the world. // Add a final synthetic collisionTarget on the right side of the world.
CollisionTargets[tiles.Length + 1] = new Aabb( CollisionTargets[tiles.Length + 1] = new AABB(
new Vector2(Width + 1, 0), new Vector2(1, float.MaxValue)); new Vector2(Width + 1, 0), new Vector2(1, float.MaxValue));
} }
@ -190,6 +190,6 @@ namespace SemiColinGames {
} }
} }
public Aabb[] CollisionTargets { get; } public AABB[] CollisionTargets { get; }
} }
} }

View File

@ -7,13 +7,13 @@ namespace SemiColinGames.Tests {
public class GeometryTests { public class GeometryTests {
[TestMethod] [TestMethod]
public void TestIntersectSegmentNotColliding() { public void TestIntersectSegmentNotColliding() {
Aabb box = new Aabb(new Vector2(0, 0), new Vector2(8, 8)); AABB box = new AABB(new Vector2(0, 0), new Vector2(8, 8));
Assert.IsNull(box.IntersectSegment(new Vector2(-16, -16), new Vector2(32, 0))); Assert.IsNull(box.IntersectSegment(new Vector2(-16, -16), new Vector2(32, 0)));
} }
[TestMethod] [TestMethod]
public void TestIntersectSegmentHit() { public void TestIntersectSegmentHit() {
Aabb box = new Aabb(new Vector2(0, 0), new Vector2(8, 8)); AABB box = new AABB(new Vector2(0, 0), new Vector2(8, 8));
var point = new Vector2(-16, 4); var point = new Vector2(-16, 4);
var delta = new Vector2(32, 0); var delta = new Vector2(32, 0);
Hit? maybeHit = box.IntersectSegment(point, delta); Hit? maybeHit = box.IntersectSegment(point, delta);
@ -36,7 +36,7 @@ namespace SemiColinGames.Tests {
[TestMethod] [TestMethod]
public void TestIntersectSegmentFromInsideBox() { public void TestIntersectSegmentFromInsideBox() {
Aabb box = new Aabb(new Vector2(0, 0), new Vector2(8, 8)); AABB box = new AABB(new Vector2(0, 0), new Vector2(8, 8));
var point = new Vector2(-4, 4); var point = new Vector2(-4, 4);
var delta = new Vector2(32, 0); var delta = new Vector2(32, 0);
Hit? maybeHit = box.IntersectSegment(point, delta); Hit? maybeHit = box.IntersectSegment(point, delta);
@ -59,7 +59,7 @@ namespace SemiColinGames.Tests {
[TestMethod] [TestMethod]
public void TestIntersectSegmentWithPadding() { public void TestIntersectSegmentWithPadding() {
Aabb box = new Aabb(new Vector2(0, 0), new Vector2(8, 8)); AABB box = new AABB(new Vector2(0, 0), new Vector2(8, 8));
var point = new Vector2(-16, 4); var point = new Vector2(-16, 4);
var delta = new Vector2(32, 0); var delta = new Vector2(32, 0);
int padding = 4; int padding = 4;
@ -83,7 +83,7 @@ namespace SemiColinGames.Tests {
[TestMethod] [TestMethod]
public void TestIntersectSegmentFromTwoDirections() { public void TestIntersectSegmentFromTwoDirections() {
Aabb box = new Aabb(new Vector2(0, 0), new Vector2(32, 32)); AABB box = new AABB(new Vector2(0, 0), new Vector2(32, 32));
var farPos = new Vector2(64, 0); var farPos = new Vector2(64, 0);
var farToNearDelta = new Vector2(-32, 0); var farToNearDelta = new Vector2(-32, 0);
Assert.IsNull(box.IntersectSegment(farPos, farToNearDelta)); Assert.IsNull(box.IntersectSegment(farPos, farToNearDelta));
@ -95,7 +95,7 @@ namespace SemiColinGames.Tests {
[TestMethod] [TestMethod]
public void TestIntersectSegmentXAxisAligned() { public void TestIntersectSegmentXAxisAligned() {
Aabb box = new Aabb(new Vector2(0, 0), new Vector2(16, 16)); AABB box = new AABB(new Vector2(0, 0), new Vector2(16, 16));
var pos = new Vector2(-32, 0); var pos = new Vector2(-32, 0);
var delta = new Vector2(64, 0); var delta = new Vector2(64, 0);
Hit? maybeHit = box.IntersectSegment(pos, delta); Hit? maybeHit = box.IntersectSegment(pos, delta);
@ -110,7 +110,7 @@ namespace SemiColinGames.Tests {
[TestMethod] [TestMethod]
public void TestIntersectSegmentYAxisAligned() { public void TestIntersectSegmentYAxisAligned() {
Aabb box = new Aabb(new Vector2(0, 0), new Vector2(16, 16)); AABB box = new AABB(new Vector2(0, 0), new Vector2(16, 16));
var pos = new Vector2(0, -32); var pos = new Vector2(0, -32);
var delta = new Vector2(0, 64); var delta = new Vector2(0, 64);
Hit? maybeHit = box.IntersectSegment(pos, delta); Hit? maybeHit = box.IntersectSegment(pos, delta);