96 lines
2.8 KiB
C#
96 lines
2.8 KiB
C#
/* Original source Farseer Physics Engine:
|
|
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
|
* Microsoft Permissive License (Ms-PL) v1.1
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using nkast.Aether.Physics2D.Common;
|
|
|
|
namespace tainicom.Aether.Physics2D.Fluids
|
|
{
|
|
/// <summary>
|
|
/// Grid used by particle system to keep track of neightbor particles.
|
|
/// </summary>
|
|
public class HashGrid
|
|
{
|
|
private Dictionary<ulong, List<FluidParticle>> _hash = new Dictionary<ulong, List<FluidParticle>>();
|
|
private Stack<List<FluidParticle>> _bucketPool = new Stack<List<FluidParticle>>();
|
|
|
|
public HashGrid()
|
|
{
|
|
GridSize = 1.0f;
|
|
}
|
|
|
|
public float GridSize { get; set; }
|
|
|
|
private static ulong HashKey(int x, int y)
|
|
{
|
|
return ((ulong)x * 2185031351ul) ^ ((ulong)y * 4232417593ul);
|
|
}
|
|
|
|
private ulong HashKey(Vector2 position)
|
|
{
|
|
return HashKey(
|
|
(int)Math.Floor(position.X / GridSize),
|
|
(int)Math.Floor(position.Y / GridSize)
|
|
);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
foreach (KeyValuePair<ulong, List<FluidParticle>> pair in _hash)
|
|
{
|
|
pair.Value.Clear();
|
|
_bucketPool.Push(pair.Value);
|
|
}
|
|
_hash.Clear();
|
|
}
|
|
|
|
public void Add(FluidParticle particle)
|
|
{
|
|
ulong key = HashKey(particle.Position);
|
|
List<FluidParticle> bucket;
|
|
if (!_hash.TryGetValue(key, out bucket))
|
|
{
|
|
if (_bucketPool.Count > 0)
|
|
{
|
|
bucket = _bucketPool.Pop();
|
|
}
|
|
else
|
|
{
|
|
bucket = new List<FluidParticle>();
|
|
}
|
|
_hash.Add(key, bucket);
|
|
}
|
|
bucket.Add(particle);
|
|
}
|
|
|
|
public void Find(ref Vector2 position, List<FluidParticle> neighbours)
|
|
{
|
|
int ix = (int)Math.Floor(position.X / GridSize);
|
|
int iy = (int)Math.Floor(position.Y / GridSize);
|
|
|
|
// Check all 9 neighbouring cells
|
|
for (int x = ix - 1; x <= ix + 1; ++x)
|
|
{
|
|
for (int y = iy - 1; y <= iy + 1; ++y)
|
|
{
|
|
ulong key = HashKey(x, y);
|
|
List<FluidParticle> bucket;
|
|
if (_hash.TryGetValue(key, out bucket))
|
|
{
|
|
for (int i = 0; i < bucket.Count; ++i)
|
|
{
|
|
if (bucket[i] != null)
|
|
{
|
|
neighbours.Add(bucket[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|