Skip to content
This repository has been archived by the owner on Nov 25, 2024. It is now read-only.

Commit

Permalink
Rearrange some stuff in Raycast.cs
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver-makes-code committed Oct 16, 2023
1 parent d15a323 commit 907b3ff
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 57 deletions.
6 changes: 2 additions & 4 deletions Common/Util/PositionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ public static ivec3 WorldToChunkPosition(this dvec3 worldPosition) {
public static ivec3 BlockToChunkPosition(this ivec3 worldPosition)
=> WorldToChunkPosition(worldPosition);

public static ivec3 WorldToBlockPosition(this dvec3 worldPosition) {
var floored = dvec3.Floor(worldPosition);
return new((int)floored.x, (int)floored.y, (int)floored.z);
}
public static ivec3 WorldToBlockPosition(this dvec3 worldPosition)
=> (ivec3)dvec3.Floor(worldPosition);

public static dvec3 ChunkToWorldPosition(this ivec3 chunkPosition)
=> (dvec3)chunkPosition * ChunkSize;
Expand Down
92 changes: 39 additions & 53 deletions Common/World/Raycast.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,13 @@
// Based off of this paper: http://www.cse.yorku.ca/~amana/research/grid.pdf

using System.Reflection.Metadata.Ecma335;
using System.Security.Cryptography;
using FastNoiseOO.Generators;
using GlmSharp;
using Voxel.Common.Util;
using Voxel.Common.World.Views;

namespace Voxel.Common.World;

public static class Raycast {
private static double Mod1(double a)
=> (a % 1 + 1) % 1;

private static double GetTMax(double start, double tDelta, double step)
=> FixNaN(tDelta * (step > 0 ? 1 - Mod1(start) : Mod1(start)));

private static double FixNaN(double d)
=> double.IsNaN(d) ? 0 : d;

public static HitResult? Cast(this BlockView world, dvec3 start, dvec3 end, ivec3 looking) {
var startPos = start.WorldToBlockPosition();

if (world.GetBlock(startPos).IsSolidBlock)
return new(startPos, start);

public static HitResult? Cast(this BlockView world, dvec3 start, dvec3 end, ivec3 looking) {
var delta = end - start;

double
Expand Down Expand Up @@ -54,33 +37,13 @@ private static double FixNaN(double d)
var yAxis = stepY > 0 ? ivec3.UnitY : -ivec3.UnitY;
var zAxis = stepZ > 0 ? ivec3.UnitZ : -ivec3.UnitZ;

var endPos = (ivec3)end;
var endPos = end.WorldToBlockPosition();
var axis = looking;

while (true) {
ivec3 axis;

switch (tMaxX < tMaxY) {
case true when tMaxX < tMaxZ:
axis = xAxis;
x += stepX;
tMaxX += tDeltaX;
break;
case false when tMaxY < tMaxZ:
axis = yAxis;
y += stepY;
tMaxY += tDeltaY;
break;
default:
axis = zAxis;
z += stepZ;
tMaxZ += tDeltaZ;
break;
}

var blockPos = new dvec3(x, y, z).WorldToBlockPosition();

if (world.GetBlock(blockPos).IsSolidBlock) {

// TODO: Account for non-cubic colliders at some point
// Gets the one integer intersection coordinate
// axis * blockPos isolates one coordinate from blockPos
Expand All @@ -93,36 +56,59 @@ private static double FixNaN(double d)
double time = (start.x - worldPos.x) / direction.x;
worldPos.y = (int)(direction.y * time);
worldPos.z = (int)(direction.z * time);
return new(blockPos, worldPos, axis);
}
// intersect with a xz plane
else if (axis.y != 0) {
// 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);
return new(blockPos, worldPos, axis);
}
// intersect with a xy plane
else if (axis.z != 0) {
if (axis.z != 0) {
double time = (start.z - worldPos.z) / direction.z;
worldPos.x = (int)(direction.x * time);
worldPos.y = (int)(direction.y * time);
return new(blockPos, worldPos, axis);
}
else continue;

return new(blockPos, worldPos);
}

if (blockPos == endPos)
return null;

switch (tMaxX < tMaxY) {
case true when tMaxX < tMaxZ:
axis = xAxis;
x += stepX;
tMaxX += tDeltaX;
break;
case false when tMaxY < tMaxZ:
axis = yAxis;
y += stepY;
tMaxY += tDeltaY;
break;
default:
axis = zAxis;
z += stepZ;
tMaxZ += tDeltaZ;
break;
}
}
}

private static double Mod1(double a)
=> (a % 1 + 1) % 1;

public record struct HitResult {
public readonly ivec3 BlockPos;
public readonly dvec3 WorldPos;
private static double GetTMax(double start, double tDelta, double step)
=> FixNaN(tDelta * (step > 0 ? 1 - Mod1(start) : Mod1(start)));

public HitResult(ivec3 block, dvec3 world) {
BlockPos = block;
WorldPos = world;
}
private static double FixNaN(double d)
=> double.IsNaN(d) ? 0 : d;

public record struct HitResult(ivec3 BlockPos, dvec3 WorldPos, ivec3 Axis) {
public readonly ivec3 BlockPos = BlockPos;
public readonly dvec3 WorldPos = WorldPos;
public readonly ivec3 Axis = Axis;
}
}

0 comments on commit 907b3ff

Please sign in to comment.