From 565273d4890abc6d2da12449a378ee4b9855e143 Mon Sep 17 00:00:00 2001 From: Emily Date: Mon, 16 Oct 2023 18:44:51 -0400 Subject: [PATCH] Fix Raycast and implement tests --- Common/World/Raycast.cs | 14 +++++++------- Test/Tests/BlockViewSuite.cs | 17 ++++++++++++++++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Common/World/Raycast.cs b/Common/World/Raycast.cs index 7eba0bd..8841fcd 100644 --- a/Common/World/Raycast.cs +++ b/Common/World/Raycast.cs @@ -53,28 +53,28 @@ public static class Raycast { // Gets the one integer intersection coordinate // axis * blockPos isolates one coordinate from blockPos // adding (-1, -1, -1) * the min of axis and (0, 0, 0) offsets the integer coordinate if the vector is intersecting from the other side - var worldPos = axis * blockPos + -ivec3.Ones * ivec3.Min(axis, ivec3.Zero); + dvec3 worldPos = ivec3.Abs(axis) * blockPos + -ivec3.Ones * ivec3.Min(axis, ivec3.Zero); var direction = delta.Normalized; // intersect with a yz plane if (axis.x != 0) { double time = (start.x - worldPos.x) / direction.x; - worldPos.y = (int)(direction.y * time); - worldPos.z = (int)(direction.z * time); + worldPos.y = start.y + direction.y * time; + worldPos.z = start.z + direction.z * time; return new(blockPos, worldPos, axis); } // intersect with an xz plane if (axis.y != 0) { double time = (start.y - worldPos.y) / direction.y; - worldPos.x = (int)(direction.x * time); - worldPos.z = (int)(direction.z * time); + worldPos.x = start.x + direction.x * time; + worldPos.z = start.z + direction.z * time; return new(blockPos, worldPos, axis); } // intersect with a xy plane if (axis.z != 0) { double time = (start.z - worldPos.z) / direction.z; - worldPos.x = (int)(direction.x * time); - worldPos.y = (int)(direction.y * time); + worldPos.x = start.x + direction.x * time; + worldPos.y = start.y + direction.y * time; return new(blockPos, worldPos, axis); } } diff --git a/Test/Tests/BlockViewSuite.cs b/Test/Tests/BlockViewSuite.cs index b8f1e82..06f7cbc 100644 --- a/Test/Tests/BlockViewSuite.cs +++ b/Test/Tests/BlockViewSuite.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using GlmSharp; using Voxel.Common.Tile; +using Voxel.Common.Util; using Voxel.Common.World; using Voxel.Test.Mocks; @@ -11,9 +13,22 @@ public class BlockViewSuite : TestSuite { protected override Dictionary DefineTests() => new() { ["Raycast"] = () => { + // Mock block view with all tiles below 0 solid var mock = new BlockViewMock(pos => pos.y < 0 ? Blocks.Stone : Blocks.Air); - Console.WriteLine(mock.Cast(new(0.5, 10.2, 0.8), new(5.333, -9.4, -5.1674))); + var rng = new Random(0); + double RandomCoord() + => rng.NextDouble() * 200d - 100d; + + // Test downward casts + for (int i = 0; i < 100; i++) { + // world pos on the top surface of the tested block + var randomPos = new dvec3(RandomCoord(), 0, RandomCoord()); + + var hit = mock.Cast(randomPos + dvec3.UnitY, randomPos - dvec3.UnitY); + Assert(hit?.BlockPos == randomPos.WorldToBlockPosition() - ivec3.UnitY, "Hit correct block"); + Assert((hit?.WorldPos - randomPos)?.Length < 0.0001f, $"Hit correct world position"); + } } }; }