Skip to content

Instantly share code, notes, and snippets.

@gamemachine
Created March 26, 2019 04:54
Show Gist options
  • Select an option

  • Save gamemachine/6cd940aa5bda954711c48086605e62cb to your computer and use it in GitHub Desktop.

Select an option

Save gamemachine/6cd940aa5bda954711c48086605e62cb to your computer and use it in GitHub Desktop.
using Unity.Collections;
using Unity.Mathematics;
namespace AiGame
{
public struct NativeSpatialGrid
{
private const float Goffset = 10000f;
public int Id;
private int Max;
private int CellSize;
private float ConvFactor;
private int Width;
public NativeMultiHashMap<int, NativeGridValue> Entities;
public NativeArray<NativeGridValue> Results;
public NativeArray<int> CellIds;
public NativeSpatialGrid(int id, int max, int cellSize, NativeMultiHashMap<int, NativeGridValue> entities, NativeArray<NativeGridValue> results, NativeArray<int> cellIds)
{
Id = id;
Max = max;
CellSize = cellSize;
ConvFactor = 1.0f / CellSize;
Width = (int)(Max / CellSize);
Entities = entities;
Results = results;
CellIds = cellIds;
}
public void Set(NativeGridValue entity)
{
int cellId = Hash(entity.Position.x + Goffset, entity.Position.z + Goffset);
Entities.Add(cellId, entity);
}
public int Query(float x, float y, float z, float maxDistance)
{
float3 origin = new float3(x, y, z);
int resultIndex = 0;
int cellCount = CellsWithinBounds(x + Goffset, z + Goffset);
for (int i = 0; i < cellCount; i++)
{
int cellId = CellIds[i];
NativeGridValue entity;
NativeMultiHashMapIterator<int> iterator;
bool found = Entities.TryGetFirstValue(cellId, out entity, out iterator);
while (found)
{
float distance = math.distance(entity.Position, origin);
if (distance <= maxDistance)
{
Results[resultIndex] = entity;
resultIndex++;
if (resultIndex > Results.Length - 1)
{
return resultIndex;
}
}
found = Entities.TryGetNextValue(out entity, ref iterator);
}
}
return resultIndex;
}
private int CellsWithinBounds(float x, float y)
{
int index = 0;
int offset = CellSize;
int startX = (int)(x - offset);
int startY = (int)(y - offset);
int endX = (int)(x + offset);
int endY = (int)(y + offset);
for (int rowNum = startX; rowNum <= endX; rowNum += offset)
{
for (int colNum = startY; colNum <= endY; colNum += offset)
{
if (rowNum >= 0 && colNum >= 0)
{
int hash = Hash(rowNum, colNum);
CellIds[index] = hash;
index++;
}
}
}
return index;
}
private int Hash(float x, float z)
{
return (int)((x * ConvFactor)) + (int)((z * ConvFactor)) * Width;
}
}
}
using Unity.Collections;
namespace AiGame
{
public class NativeSpatialGridData
{
public NativeMultiHashMap<int, NativeGridValue> Entities;
public NativeArray<NativeGridValue> Results;
public NativeArray<int> CellIds;
public NativeSpatialGridData(int allocateSize = 2048)
{
CellIds = new NativeArray<int>(24, Allocator.Persistent);
Results = new NativeArray<NativeGridValue>(1024, Allocator.Persistent);
Entities = new NativeMultiHashMap<int, NativeGridValue>(allocateSize, Allocator.Persistent);
}
public void Clear()
{
Entities.Clear();
}
public void Dispose()
{
if (Entities.IsCreated) Entities.Dispose();
if (CellIds.IsCreated) CellIds.Dispose();
if (Results.IsCreated) Results.Dispose();
}
}
}
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
namespace AiGame
{
public struct NativeGridValue : IComponentData
{
public int Id;
public float3 Position;
public Bounds Bounds;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment