// Magica Cloth.
// Copyright (c) MagicaSoft, 2020-2022.
// https://magicasoft.jp
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;
namespace MagicaCloth
{
///
/// 3次グリッドハッシュの基礎クラス
/// このクラスを派生させて独自のグリッド判定処理などを記述してください。
///
public class GridHash
{
///
/// 頂点データ
///
public class Point
{
public int id;
public float3 pos;
}
///
/// 3次元グリッドマップ
///
protected Dictionary> gridMap;
///
/// グリッドサイズ
///
protected float gridSize = 0.1f;
//=========================================================================================
///
/// 初期化
///
///
public virtual void Create(float gridSize = 0.1f)
{
gridMap = new Dictionary>();
this.gridSize = gridSize;
}
//=========================================================================================
///
/// 頂点をグリッドに追加する
///
///
///
public virtual void AddPoint(float3 pos, int id)
{
var p = new Point()
{
id = id,
pos = pos
};
var grid = GetGridHash(pos, gridSize);
if (gridMap.ContainsKey(grid))
gridMap[grid].Add(p);
else
{
var plist = new List();
plist.Add(p);
gridMap.Add(grid, plist);
}
}
///
/// 頂点をグリッドから削除する
///
///
///
public virtual void Remove(float3 pos, int id)
{
var grid = GetGridHash(pos, gridSize);
if (gridMap.ContainsKey(grid))
{
var plist = gridMap[grid];
for (int i = 0; i < plist.Count; i++)
{
if (plist[i].id == id)
{
plist.RemoveAt(i);
break;
}
}
}
else
Debug.LogError("remove faild!");
}
///
/// クリア
///
public void Clear()
{
gridMap.Clear();
}
//=========================================================================================
///
/// 座標から3次元グリッド座標を割り出す
///
///
///
///
public static int3 GetGridPos(float3 pos, float gridSize)
{
return math.int3(math.floor(pos / gridSize));
}
///
/// 3次元グリッド座標を10ビット刻みのuint型にグリッドハッシュに変換する
/// 10ビットの範囲は+511~-512となり、グリッド座標がオーバー/アンダーする場合はループする
///
///
///
public static uint GetGridHash(int3 pos)
{
uint hash = (uint)(pos.x & 0x3ff) | (uint)(pos.y & 0x3ff) << 10 | (uint)(pos.z & 0x3ff) << 20;
return hash;
}
///
/// 座標からグリッドハッシュに変換して返す
///
///
///
///
public static uint GetGridHash(float3 pos, float gridSize)
{
int3 xyz = GetGridPos(pos, gridSize);
return GetGridHash(xyz);
}
}
}