riversong code showcase
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public static class DirectionVectors
|
||||
{
|
||||
public static readonly int2[] Directions4 =
|
||||
{
|
||||
new(1, 0),
|
||||
new(-1, 0),
|
||||
new(0, 1),
|
||||
new(0, -1)
|
||||
};
|
||||
|
||||
public static readonly int2[] Directions8 =
|
||||
{
|
||||
new(1, 0),
|
||||
new(-1, 0),
|
||||
new(0, 1),
|
||||
new(0, -1),
|
||||
new(1, 1),
|
||||
new(1, -1),
|
||||
new(-1, 1),
|
||||
new(-1, -1)
|
||||
};
|
||||
}
|
||||
}
|
||||
134
Source/Riversong/Game/CommonServices/TileMath/Directions.cs
Normal file
134
Source/Riversong/Game/CommonServices/TileMath/Directions.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public enum Directions
|
||||
{
|
||||
North,
|
||||
|
||||
NorthWest,
|
||||
|
||||
West,
|
||||
|
||||
SouthWest,
|
||||
|
||||
South,
|
||||
|
||||
SouthEast,
|
||||
|
||||
East,
|
||||
|
||||
NorthEast
|
||||
}
|
||||
|
||||
public enum DirectionsMask4
|
||||
{
|
||||
None = 0,
|
||||
|
||||
North = 1 << 0,
|
||||
|
||||
West = 1 << 1,
|
||||
|
||||
South = 1 << 2,
|
||||
|
||||
East = 1 << 3
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum DirectionsMask8
|
||||
{
|
||||
None = 0,
|
||||
|
||||
North = 1 << 0,
|
||||
|
||||
NorthWest = 1 << 1,
|
||||
|
||||
West = 1 << 2,
|
||||
|
||||
SouthWest = 1 << 3,
|
||||
|
||||
South = 1 << 4,
|
||||
|
||||
SouthEast = 1 << 5,
|
||||
|
||||
East = 1 << 6,
|
||||
|
||||
NorthEast = 1 << 7
|
||||
}
|
||||
|
||||
public static class DirectionsExtensions
|
||||
{
|
||||
public static int2 ToVector(this Directions direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case Directions.North:
|
||||
return new int2(0, 1);
|
||||
|
||||
case Directions.NorthWest:
|
||||
return new int2(-1, 1);
|
||||
|
||||
case Directions.West:
|
||||
return new int2(-1, 0);
|
||||
|
||||
case Directions.SouthWest:
|
||||
return new int2(-1, -1);
|
||||
|
||||
case Directions.South:
|
||||
return new int2(0, -1);
|
||||
|
||||
case Directions.SouthEast:
|
||||
return new int2(1, -1);
|
||||
|
||||
case Directions.East:
|
||||
return new int2(1, 0);
|
||||
|
||||
case Directions.NorthEast:
|
||||
return new int2(1, 1);
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public static Quaternion ToQuaternion(this Directions direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case Directions.North:
|
||||
return Quaternion.identity;
|
||||
|
||||
case Directions.NorthWest:
|
||||
return Quaternion.LookRotation(new Vector3(-1, 0, 1));
|
||||
|
||||
case Directions.West:
|
||||
return Quaternion.LookRotation(Vector3.left);
|
||||
|
||||
case Directions.SouthWest:
|
||||
return Quaternion.LookRotation(new Vector3(-1, 0, -1));
|
||||
|
||||
case Directions.South:
|
||||
return Quaternion.LookRotation(Vector3.back);
|
||||
|
||||
case Directions.SouthEast:
|
||||
return Quaternion.LookRotation(new Vector3(1, 0, -1));
|
||||
|
||||
case Directions.East:
|
||||
return Quaternion.LookRotation(Vector3.right);
|
||||
|
||||
case Directions.NorthEast:
|
||||
return Quaternion.LookRotation(new Vector3(1, 0, 1));
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public static int2 Rotate(this Directions direction, int2 v)
|
||||
{
|
||||
return TileMath.Rotate(v, direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Source/Riversong/Game/CommonServices/TileMath/ITileSpace.cs
Normal file
18
Source/Riversong/Game/CommonServices/TileMath/ITileSpace.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public interface ITileSpace
|
||||
{
|
||||
float TileSize { get; }
|
||||
|
||||
int2 WorldToTile(Vector3 position);
|
||||
|
||||
Vector3 TileToWorld(int2 tile, float tileX = 0.5f, float tileY = 0.5f);
|
||||
|
||||
int GetElevation(float y);
|
||||
|
||||
Vector3 GetRectWorldCenter(in TileRect rect);
|
||||
}
|
||||
}
|
||||
136
Source/Riversong/Game/CommonServices/TileMath/TileMath.cs
Normal file
136
Source/Riversong/Game/CommonServices/TileMath/TileMath.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public static class TileMath
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int2 Rotate(int2 v, Directions direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case Directions.North:
|
||||
return new int2(v.x, v.y);
|
||||
|
||||
case Directions.West:
|
||||
return new int2(v.y, -v.x);
|
||||
|
||||
case Directions.South:
|
||||
return new int2(-v.x, -v.y);
|
||||
|
||||
case Directions.East:
|
||||
return new int2(-v.y, v.x);
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public static TileRect GetBuildingRect(int2 rectCenter, Directions direction, int width, int height)
|
||||
{
|
||||
int dx;
|
||||
int dy;
|
||||
|
||||
var sx = (width - 1) >> 1;
|
||||
var sy = (height - 1) >> 1;
|
||||
|
||||
if (width == height || direction == Directions.North)
|
||||
{
|
||||
dx = -sx;
|
||||
dy = -sy;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case Directions.West:
|
||||
dx = sy - (height - 1);
|
||||
dy = -sx;
|
||||
(width, height) = (height, width);
|
||||
break;
|
||||
|
||||
case Directions.South:
|
||||
dx = sx - (width - 1);
|
||||
dy = sy - (height - 1);
|
||||
break;
|
||||
|
||||
case Directions.East:
|
||||
dx = -sy;
|
||||
dy = sx - (width - 1);
|
||||
(width, height) = (height, width);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
return new TileRect(rectCenter + new int2(dx, dy), width, height);
|
||||
}
|
||||
|
||||
public static void WalkLine(int2 startTile, int2 endTile, Action<int2> tileAction)
|
||||
{
|
||||
var dx = endTile.x - startTile.x;
|
||||
var dy = endTile.y - startTile.y;
|
||||
if (math.abs(dx) >= math.abs(dy))
|
||||
endTile.y = startTile.y;
|
||||
else
|
||||
endTile.x = startTile.x;
|
||||
|
||||
var tile = startTile;
|
||||
var d = math.sign(endTile - startTile);
|
||||
|
||||
while (true)
|
||||
{
|
||||
tileAction.Invoke(tile);
|
||||
|
||||
if (math.all(tile == endTile)) break;
|
||||
|
||||
tile += d;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int StepCount(int2 tile, int2 otherTile)
|
||||
{
|
||||
var delta = math.abs(tile - otherTile);
|
||||
return math.max(delta.x, delta.y);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int StepCount(int2 tile, in TileRect rect)
|
||||
{
|
||||
var left = math.max(rect.Min.x - tile.x, 0);
|
||||
var right = math.max(tile.x - rect.Max.x, 0);
|
||||
var dx = math.max(left, right);
|
||||
|
||||
var bottom = math.max(rect.Min.y - tile.y, 0);
|
||||
var top = math.max(tile.y - rect.Max.y, 0);
|
||||
var dy = math.max(bottom, top);
|
||||
|
||||
return math.max(dx, dy);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int StepCount(in TileRect rect, int2 tile)
|
||||
{
|
||||
return StepCount(tile, rect);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int StepCount(in TileRect rect, in TileRect otherRect)
|
||||
{
|
||||
var left = math.max(otherRect.Min.x - rect.Max.x, 0);
|
||||
var right = math.max(rect.Min.x - otherRect.Max.x, 0);
|
||||
var dx = math.max(left, right);
|
||||
|
||||
var bottom = math.max(otherRect.Min.y - rect.Max.y, 0);
|
||||
var top = math.max(rect.Min.y - otherRect.Max.y, 0);
|
||||
var dy = math.max(bottom, top);
|
||||
|
||||
return math.max(dx, dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Source/Riversong/Game/CommonServices/TileMath/TileRange.cs
Normal file
88
Source/Riversong/Game/CommonServices/TileMath/TileRange.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public struct TileRange : IEnumerable<int2>
|
||||
{
|
||||
public int2 Min;
|
||||
|
||||
public int2 Max;
|
||||
|
||||
private TileRange(int2 min, int2 max)
|
||||
{
|
||||
Min = min;
|
||||
Max = max;
|
||||
}
|
||||
|
||||
public static TileRange From(in TileRect rect)
|
||||
{
|
||||
return new TileRange(rect.Min, rect.Max);
|
||||
}
|
||||
|
||||
public static TileRange From(int2 min, int2 max)
|
||||
{
|
||||
return From(new TileRect(min, max));
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(Min, Max);
|
||||
}
|
||||
|
||||
IEnumerator<int2> IEnumerable<int2>.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public struct Enumerator : IEnumerator<int2>
|
||||
{
|
||||
public int2 Min;
|
||||
|
||||
public int2 Max;
|
||||
|
||||
public int2 Current { get; private set; }
|
||||
|
||||
object IEnumerator.Current => Current;
|
||||
|
||||
public Enumerator(int2 min, int2 max) : this()
|
||||
{
|
||||
Min = min;
|
||||
Max = max;
|
||||
Reset();
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (Current.x < Max.x)
|
||||
{
|
||||
Current = new int2(Current.x + 1, Current.y);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Current.y < Max.y)
|
||||
{
|
||||
Current = new int2(Min.x, Current.y + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Current = new int2(Min.x - 1, Min.y);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
71
Source/Riversong/Game/CommonServices/TileMath/TileRect.cs
Normal file
71
Source/Riversong/Game/CommonServices/TileMath/TileRect.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public struct TileRect
|
||||
{
|
||||
public static readonly TileRect Empty = new(int2.zero, int2.zero);
|
||||
|
||||
public static readonly TileRect Everything = new(int.MinValue, int.MaxValue);
|
||||
|
||||
private int2 _min;
|
||||
|
||||
private int2 _max;
|
||||
|
||||
public int2 Min
|
||||
{
|
||||
readonly get => _min;
|
||||
set
|
||||
{
|
||||
_min = value;
|
||||
_max = math.max(_min, _max);
|
||||
}
|
||||
}
|
||||
|
||||
public int2 Max
|
||||
{
|
||||
readonly get => _max;
|
||||
set
|
||||
{
|
||||
_max = value;
|
||||
_min = math.min(_min, _max);
|
||||
}
|
||||
}
|
||||
|
||||
public int Width => _max.x - _min.x + 1;
|
||||
|
||||
public int Height => _max.y - _min.y + 1;
|
||||
|
||||
public int2 Center => (_min + _max) / 2;
|
||||
|
||||
public TileRect(int2 min, int2 max)
|
||||
{
|
||||
_min = math.min(min, max);
|
||||
_max = math.max(min, max);
|
||||
}
|
||||
|
||||
public TileRect(int2 min, int width, int height) : this(min, min + new int2(width - 1, height - 1))
|
||||
{
|
||||
}
|
||||
|
||||
public readonly bool Contains(int2 tile)
|
||||
{
|
||||
return tile.x >= Min.x && tile.x <= Max.x && tile.y >= Min.y && tile.y <= Max.y;
|
||||
}
|
||||
|
||||
public readonly bool Intersects(TileRect other)
|
||||
{
|
||||
return !(other.Max.x < Min.x || other.Min.x > Max.x || other.Max.y < Min.y || other.Min.y > Max.y);
|
||||
}
|
||||
|
||||
public readonly TileRect Inflate(int amount)
|
||||
{
|
||||
return amount == int.MaxValue ? Everything : new TileRect(Min - amount, Max + amount);
|
||||
}
|
||||
|
||||
public static TileRect OneTile(int2 tile)
|
||||
{
|
||||
return new TileRect(tile, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Source/Riversong/Game/CommonServices/TileMath/TileSpace.cs
Normal file
38
Source/Riversong/Game/CommonServices/TileMath/TileSpace.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public class TileSpace : ITileSpace
|
||||
{
|
||||
public float TileSize { get; set; }
|
||||
|
||||
public World World { get; set; }
|
||||
|
||||
public int2 WorldToTile(Vector3 position)
|
||||
{
|
||||
var tileX = Mathf.FloorToInt(position.x / TileSize);
|
||||
var tileY = Mathf.FloorToInt(position.z / TileSize);
|
||||
return new int2(tileX, tileY);
|
||||
}
|
||||
|
||||
public Vector3 TileToWorld(int2 tile, float tileX = 0.5f, float tileY = 0.5f)
|
||||
{
|
||||
tileX = Mathf.Clamp01(tileX);
|
||||
tileY = Mathf.Clamp01(tileY);
|
||||
return new Vector3((tile.x + tileX) * TileSize, World.Heightmap.GetValue(tile), (tile.y + tileY) * TileSize);
|
||||
}
|
||||
|
||||
public int GetElevation(float y)
|
||||
{
|
||||
return Mathf.RoundToInt(y);
|
||||
}
|
||||
|
||||
public Vector3 GetRectWorldCenter(in TileRect rect)
|
||||
{
|
||||
var worldCenter = TileToWorld(rect.Min, 0, 0);
|
||||
worldCenter += new Vector3(rect.Width, 0, rect.Height) * (0.5f * TileSize);
|
||||
return worldCenter;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user