Skip to content

Instantly share code, notes, and snippets.

@mandarinx
Created October 31, 2019 09:12
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mandarinx/3053c514e8b2a34ce9ba2dc649ddde6c to your computer and use it in GitHub Desktop.
Save mandarinx/3053c514e8b2a34ce9ba2dc649ddde6c to your computer and use it in GitHub Desktop.
Spatial partitioning

Notes, in no particular order

For our case, I chose to add a little more data to each point. It makes handling collisions easier. In your case, you might not need to store instanceId or a rotation quaternion.

In our game, entities move each frame, so we have to clear and update the cache every frame. With 4096 entities spread out across the surface of sphere, it usually takes about 0.2ms, in a release build.

Usage:

1. Update the cache.

// Clear the previous cache
SpacePartitions.Clear(instance);
// Pass references to arrays of position vectors, and the number of positions.
// We do it like this to avoid memory allocations. In our game, everything is pre-
// allocated, and we make 0 allocations at runtime.
SpacePartitions.AddPoints(instance, instanceIds, positions, rotations, num);

2. Check for overlap/collision

// Given a position and a radius, get the number of overlapping points
int len = SpacePartitions.FindOverlaps(instance, position, radius);
for (int i = 0; i < len; ++i) {
  // The overlapping points are put in a cache for fast access. Otherwise, you'd
  // have to jump around in the main cache. n is the position in the main cache.
  int n = SpacePartitions.GetOverlappingPointIndex(instance, i);
  // Use n to get the position of the overlapping entity
  Vector3 point = SpacePartitions.GetPoint(instance, n);
  // Optionally remove the point, if it shouldn't respond to more overlap checks
  SpacePartitions.RemovePoint(instance, n);
}

The system supports checking for overlaps with a radius from 1 to 3 units. The cell offset coordinates are precalculated and put in the CoordRadiusX arrays.

Further optimizations can be done by using Dictionaries instead. The arrays are only used for lookups anyway, and in that case Dictionaries are faster. O(1) vs. O(n).

The system is very simple. Preallocate everything. Partition points in a 3D grid of cells. Use simple math to calculate cell index from point and vice versa.

Adding support for a custom radius per point is easy. Change the points array to be a Vector4[] instead, and use the w field to store a radius. In the overlap method, include the points radius when checking the distance.

using UnityEngine;
namespace TerrorSquid.Collisions {
public static class CoordsRadius1 {
public static readonly Vector3[] coords = {
new Vector3(-1, -1, -1).normalized,
new Vector3(0, -1, -1).normalized,
new Vector3(1, -1, -1).normalized,
new Vector3(-1, -1, 0).normalized,
new Vector3(0, -1, 0).normalized,
new Vector3(1, -1, 0).normalized,
new Vector3(-1, -1, 1).normalized,
new Vector3(0, -1, 1).normalized,
new Vector3(1, -1, 1).normalized,
new Vector3(-1, 0, -1).normalized,
new Vector3(0, 0, -1).normalized,
new Vector3(1, 0, -1).normalized,
new Vector3(-1, 0, 0).normalized,
new Vector3(0, 0, 0).normalized,
new Vector3(1, 0, 0).normalized,
new Vector3(-1, 0, 1).normalized,
new Vector3(0, 0, 1).normalized,
new Vector3(1, 0, 1).normalized,
new Vector3(-1, 1, -1).normalized,
new Vector3(0, 1, -1).normalized,
new Vector3(1, 1, -1).normalized,
new Vector3(-1, 1, 0).normalized,
new Vector3(0, 1, 0).normalized,
new Vector3(1, 1, 0).normalized,
new Vector3(-1, 1, 1).normalized,
new Vector3(0, 1, 1).normalized,
new Vector3(1, 1, 1).normalized
};
}
public static class CoordsRadius2 {
public static readonly Vector3[] coords = {
new Vector3(-1, -2, -1).normalized,
new Vector3(0, -2, -1).normalized,
new Vector3(1, -2, -1).normalized,
new Vector3(-1, -2, 0).normalized,
new Vector3(0, -2, 0).normalized,
new Vector3(1, -2, 0).normalized,
new Vector3(-1, -2, 1).normalized,
new Vector3(0, -2, 1).normalized,
new Vector3(1, -2, 1).normalized,
new Vector3(-1, -1, -2).normalized,
new Vector3(0, -1, -2).normalized,
new Vector3(1, -1, -2).normalized,
new Vector3(-2, -1, -1).normalized,
new Vector3(-1, -1, -1).normalized,
new Vector3(0, -1, -1).normalized,
new Vector3(1, -1, -1).normalized,
new Vector3(2, -1, -1).normalized,
new Vector3(-2, -1, 0).normalized,
new Vector3(-1, -1, 0).normalized,
new Vector3(0, -1, 0).normalized,
new Vector3(1, -1, 0).normalized,
new Vector3(2, -1, 0).normalized,
new Vector3(-2, -1, 1).normalized,
new Vector3(-1, -1, 1).normalized,
new Vector3(0, -1, 1).normalized,
new Vector3(1, -1, 1).normalized,
new Vector3(2, -1, 1).normalized,
new Vector3(-1, -1, 2).normalized,
new Vector3(0, -1, 2).normalized,
new Vector3(1, -1, 2).normalized,
new Vector3(-1, 0, -2).normalized,
new Vector3(0, 0, -2).normalized,
new Vector3(1, 0, -2).normalized,
new Vector3(-2, 0, -1).normalized,
new Vector3(-1, 0, -1).normalized,
new Vector3(0, 0, -1).normalized,
new Vector3(1, 0, -1).normalized,
new Vector3(2, 0, -1).normalized,
new Vector3(-2, 0, 0).normalized,
new Vector3(-1, 0, 0).normalized,
new Vector3(0, 0, 0).normalized,
new Vector3(1, 0, 0).normalized,
new Vector3(2, 0, 0).normalized,
new Vector3(-2, 0, 1).normalized,
new Vector3(-1, 0, 1).normalized,
new Vector3(0, 0, 1).normalized,
new Vector3(1, 0, 1).normalized,
new Vector3(2, 0, 1).normalized,
new Vector3(-1, 0, 2).normalized,
new Vector3(0, 0, 2).normalized,
new Vector3(1, 0, 2).normalized,
new Vector3(-1, 1, -2).normalized,
new Vector3(0, 1, -2).normalized,
new Vector3(1, 1, -2).normalized,
new Vector3(-2, 1, -1).normalized,
new Vector3(-1, 1, -1).normalized,
new Vector3(0, 1, -1).normalized,
new Vector3(1, 1, -1).normalized,
new Vector3(2, 1, -1).normalized,
new Vector3(-2, 1, 0).normalized,
new Vector3(-1, 1, 0).normalized,
new Vector3(0, 1, 0).normalized,
new Vector3(1, 1, 0).normalized,
new Vector3(2, 1, 0).normalized,
new Vector3(-2, 1, 1).normalized,
new Vector3(-1, 1, 1).normalized,
new Vector3(0, 1, 1).normalized,
new Vector3(1, 1, 1).normalized,
new Vector3(2, 1, 1).normalized,
new Vector3(-1, 1, 2).normalized,
new Vector3(0, 1, 2).normalized,
new Vector3(1, 1, 2).normalized,
new Vector3(-1, 2, -1).normalized,
new Vector3(0, 2, -1).normalized,
new Vector3(1, 2, -1).normalized,
new Vector3(-1, 2, 0).normalized,
new Vector3(0, 2, 0).normalized,
new Vector3(1, 2, 0).normalized,
new Vector3(-1, 2, 1).normalized,
new Vector3(0, 2, 1).normalized,
new Vector3(1, 2, 1).normalized
};
}
public static class CoordsRadius3 {
public static readonly Vector3[] coords = {
new Vector3(-1, -3, -2).normalized,
new Vector3(0, -3, -2).normalized,
new Vector3(1, -3, -2).normalized,
new Vector3(-2, -3, -1).normalized,
new Vector3(-1, -3, -1).normalized,
new Vector3(0, -3, -1).normalized,
new Vector3(1, -3, -1).normalized,
new Vector3(2, -3, -1).normalized,
new Vector3(-2, -3, 0).normalized,
new Vector3(-1, -3, 0).normalized,
new Vector3(0, -3, 0).normalized,
new Vector3(1, -3, 0).normalized,
new Vector3(2, -3, 0).normalized,
new Vector3(-2, -3, 1).normalized,
new Vector3(-1, -3, 1).normalized,
new Vector3(0, -3, 1).normalized,
new Vector3(1, -3, 1).normalized,
new Vector3(2, -3, 1).normalized,
new Vector3(-1, -3, 2).normalized,
new Vector3(0, -3, 2).normalized,
new Vector3(1, -3, 2).normalized,
new Vector3(-1, -2, -3).normalized,
new Vector3(0, -2, -3).normalized,
new Vector3(1, -2, -3).normalized,
new Vector3(-2, -2, -2).normalized,
new Vector3(-1, -2, -2).normalized,
new Vector3(0, -2, -2).normalized,
new Vector3(1, -2, -2).normalized,
new Vector3(2, -2, -2).normalized,
new Vector3(-3, -2, -1).normalized,
new Vector3(-2, -2, -1).normalized,
new Vector3(-1, -2, -1).normalized,
new Vector3(0, -2, -1).normalized,
new Vector3(1, -2, -1).normalized,
new Vector3(2, -2, -1).normalized,
new Vector3(3, -2, -1).normalized,
new Vector3(-3, -2, 0).normalized,
new Vector3(-2, -2, 0).normalized,
new Vector3(-1, -2, 0).normalized,
new Vector3(0, -2, 0).normalized,
new Vector3(1, -2, 0).normalized,
new Vector3(2, -2, 0).normalized,
new Vector3(3, -2, 0).normalized,
new Vector3(-3, -2, 1).normalized,
new Vector3(-2, -2, 1).normalized,
new Vector3(-1, -2, 1).normalized,
new Vector3(0, -2, 1).normalized,
new Vector3(1, -2, 1).normalized,
new Vector3(2, -2, 1).normalized,
new Vector3(3, -2, 1).normalized,
new Vector3(-2, -2, 2).normalized,
new Vector3(-1, -2, 2).normalized,
new Vector3(0, -2, 2).normalized,
new Vector3(1, -2, 2).normalized,
new Vector3(2, -2, 2).normalized,
new Vector3(-1, -2, 3).normalized,
new Vector3(0, -2, 3).normalized,
new Vector3(1, -2, 3).normalized,
new Vector3(-2, -1, -3).normalized,
new Vector3(-1, -1, -3).normalized,
new Vector3(0, -1, -3).normalized,
new Vector3(1, -1, -3).normalized,
new Vector3(2, -1, -3).normalized,
new Vector3(-3, -1, -2).normalized,
new Vector3(-2, -1, -2).normalized,
new Vector3(-1, -1, -2).normalized,
new Vector3(0, -1, -2).normalized,
new Vector3(1, -1, -2).normalized,
new Vector3(2, -1, -2).normalized,
new Vector3(3, -1, -2).normalized,
new Vector3(-3, -1, -1).normalized,
new Vector3(-2, -1, -1).normalized,
new Vector3(-1, -1, -1).normalized,
new Vector3(0, -1, -1).normalized,
new Vector3(1, -1, -1).normalized,
new Vector3(2, -1, -1).normalized,
new Vector3(3, -1, -1).normalized,
new Vector3(-3, -1, 0).normalized,
new Vector3(-2, -1, 0).normalized,
new Vector3(-1, -1, 0).normalized,
new Vector3(0, -1, 0).normalized,
new Vector3(1, -1, 0).normalized,
new Vector3(2, -1, 0).normalized,
new Vector3(3, -1, 0).normalized,
new Vector3(-3, -1, 1).normalized,
new Vector3(-2, -1, 1).normalized,
new Vector3(-1, -1, 1).normalized,
new Vector3(0, -1, 1).normalized,
new Vector3(1, -1, 1).normalized,
new Vector3(2, -1, 1).normalized,
new Vector3(3, -1, 1).normalized,
new Vector3(-3, -1, 2).normalized,
new Vector3(-2, -1, 2).normalized,
new Vector3(-1, -1, 2).normalized,
new Vector3(0, -1, 2).normalized,
new Vector3(1, -1, 2).normalized,
new Vector3(2, -1, 2).normalized,
new Vector3(3, -1, 2).normalized,
new Vector3(-2, -1, 3).normalized,
new Vector3(-1, -1, 3).normalized,
new Vector3(0, -1, 3).normalized,
new Vector3(1, -1, 3).normalized,
new Vector3(2, -1, 3).normalized,
new Vector3(-2, 0, -3).normalized,
new Vector3(-1, 0, -3).normalized,
new Vector3(0, 0, -3).normalized,
new Vector3(1, 0, -3).normalized,
new Vector3(2, 0, -3).normalized,
new Vector3(-3, 0, -2).normalized,
new Vector3(-2, 0, -2).normalized,
new Vector3(-1, 0, -2).normalized,
new Vector3(0, 0, -2).normalized,
new Vector3(1, 0, -2).normalized,
new Vector3(2, 0, -2).normalized,
new Vector3(3, 0, -2).normalized,
new Vector3(-3, 0, -1).normalized,
new Vector3(-2, 0, -1).normalized,
new Vector3(-1, 0, -1).normalized,
new Vector3(0, 0, -1).normalized,
new Vector3(1, 0, -1).normalized,
new Vector3(2, 0, -1).normalized,
new Vector3(3, 0, -1).normalized,
new Vector3(-3, 0, 0).normalized,
new Vector3(-2, 0, 0).normalized,
new Vector3(-1, 0, 0).normalized,
new Vector3(0, 0, 0).normalized,
new Vector3(1, 0, 0).normalized,
new Vector3(2, 0, 0).normalized,
new Vector3(3, 0, 0).normalized,
new Vector3(-3, 0, 1).normalized,
new Vector3(-2, 0, 1).normalized,
new Vector3(-1, 0, 1).normalized,
new Vector3(0, 0, 1).normalized,
new Vector3(1, 0, 1).normalized,
new Vector3(2, 0, 1).normalized,
new Vector3(3, 0, 1).normalized,
new Vector3(-3, 0, 2).normalized,
new Vector3(-2, 0, 2).normalized,
new Vector3(-1, 0, 2).normalized,
new Vector3(0, 0, 2).normalized,
new Vector3(1, 0, 2).normalized,
new Vector3(2, 0, 2).normalized,
new Vector3(3, 0, 2).normalized,
new Vector3(-2, 0, 3).normalized,
new Vector3(-1, 0, 3).normalized,
new Vector3(0, 0, 3).normalized,
new Vector3(1, 0, 3).normalized,
new Vector3(2, 0, 3).normalized,
new Vector3(-2, 1, -3).normalized,
new Vector3(-1, 1, -3).normalized,
new Vector3(0, 1, -3).normalized,
new Vector3(1, 1, -3).normalized,
new Vector3(2, 1, -3).normalized,
new Vector3(-3, 1, -2).normalized,
new Vector3(-2, 1, -2).normalized,
new Vector3(-1, 1, -2).normalized,
new Vector3(0, 1, -2).normalized,
new Vector3(1, 1, -2).normalized,
new Vector3(2, 1, -2).normalized,
new Vector3(3, 1, -2).normalized,
new Vector3(-3, 1, -1).normalized,
new Vector3(-2, 1, -1).normalized,
new Vector3(-1, 1, -1).normalized,
new Vector3(0, 1, -1).normalized,
new Vector3(1, 1, -1).normalized,
new Vector3(2, 1, -1).normalized,
new Vector3(3, 1, -1).normalized,
new Vector3(-3, 1, 0).normalized,
new Vector3(-2, 1, 0).normalized,
new Vector3(-1, 1, 0).normalized,
new Vector3(0, 1, 0).normalized,
new Vector3(1, 1, 0).normalized,
new Vector3(2, 1, 0).normalized,
new Vector3(3, 1, 0).normalized,
new Vector3(-3, 1, 1).normalized,
new Vector3(-2, 1, 1).normalized,
new Vector3(-1, 1, 1).normalized,
new Vector3(0, 1, 1).normalized,
new Vector3(1, 1, 1).normalized,
new Vector3(2, 1, 1).normalized,
new Vector3(3, 1, 1).normalized,
new Vector3(-3, 1, 2).normalized,
new Vector3(-2, 1, 2).normalized,
new Vector3(-1, 1, 2).normalized,
new Vector3(0, 1, 2).normalized,
new Vector3(1, 1, 2).normalized,
new Vector3(2, 1, 2).normalized,
new Vector3(3, 1, 2).normalized,
new Vector3(-2, 1, 3).normalized,
new Vector3(-1, 1, 3).normalized,
new Vector3(0, 1, 3).normalized,
new Vector3(1, 1, 3).normalized,
new Vector3(2, 1, 3).normalized,
new Vector3(-1, 2, -3).normalized,
new Vector3(0, 2, -3).normalized,
new Vector3(1, 2, -3).normalized,
new Vector3(-2, 2, -2).normalized,
new Vector3(-1, 2, -2).normalized,
new Vector3(0, 2, -2).normalized,
new Vector3(1, 2, -2).normalized,
new Vector3(2, 2, -2).normalized,
new Vector3(-3, 2, -1).normalized,
new Vector3(-2, 2, -1).normalized,
new Vector3(-1, 2, -1).normalized,
new Vector3(0, 2, -1).normalized,
new Vector3(1, 2, -1).normalized,
new Vector3(2, 2, -1).normalized,
new Vector3(3, 2, -1).normalized,
new Vector3(-3, 2, 0).normalized,
new Vector3(-2, 2, 0).normalized,
new Vector3(-1, 2, 0).normalized,
new Vector3(0, 2, 0).normalized,
new Vector3(1, 2, 0).normalized,
new Vector3(2, 2, 0).normalized,
new Vector3(3, 2, 0).normalized,
new Vector3(-3, 2, 1).normalized,
new Vector3(-2, 2, 1).normalized,
new Vector3(-1, 2, 1).normalized,
new Vector3(0, 2, 1).normalized,
new Vector3(1, 2, 1).normalized,
new Vector3(2, 2, 1).normalized,
new Vector3(3, 2, 1).normalized,
new Vector3(-2, 2, 2).normalized,
new Vector3(-1, 2, 2).normalized,
new Vector3(0, 2, 2).normalized,
new Vector3(1, 2, 2).normalized,
new Vector3(2, 2, 2).normalized,
new Vector3(-1, 2, 3).normalized,
new Vector3(0, 2, 3).normalized,
new Vector3(1, 2, 3).normalized,
new Vector3(-1, 3, -2).normalized,
new Vector3(0, 3, -2).normalized,
new Vector3(1, 3, -2).normalized,
new Vector3(-2, 3, -1).normalized,
new Vector3(-1, 3, -1).normalized,
new Vector3(0, 3, -1).normalized,
new Vector3(1, 3, -1).normalized,
new Vector3(2, 3, -1).normalized,
new Vector3(-2, 3, 0).normalized,
new Vector3(-1, 3, 0).normalized,
new Vector3(0, 3, 0).normalized,
new Vector3(1, 3, 0).normalized,
new Vector3(2, 3, 0).normalized,
new Vector3(-2, 3, 1).normalized,
new Vector3(-1, 3, 1).normalized,
new Vector3(0, 3, 1).normalized,
new Vector3(1, 3, 1).normalized,
new Vector3(2, 3, 1).normalized,
new Vector3(-1, 3, 2).normalized,
new Vector3(0, 3, 2).normalized,
new Vector3(1, 3, 2).normalized
};
}
}
using System.Collections.Generic;
using UnityEngine;
using Debug = UnityEngine.Debug;
namespace TerrorSquid.Collisions {
public class SpacePartitions {
public const int NUM_CELLS = SIDE_LEN * SIDE_LEN * SIDE_LEN;
public const int SIDE_LEN = 14;
public const int POINTS_PER_CELL = 128;
private const int SIDE_AREAL = SIDE_LEN * SIDE_LEN;
private const float OFFSET = SIDE_LEN * 0.5f;
// Based on a maximum overlap radius of 3,
// the diameter is 7. 3 for each side and
// 1 for the center cell.
private const int MAX_DIAM = 7;
private readonly int[] instanceIds = new int[POINTS_PER_CELL * NUM_CELLS];
private readonly Vector3[] points = new Vector3[POINTS_PER_CELL * NUM_CELLS];
private readonly Quaternion[] localSphereRot = new Quaternion[POINTS_PER_CELL * NUM_CELLS];
private readonly int[] numPointsPerCell = new int[NUM_CELLS];
private readonly int[] overlapCells = new int[MAX_DIAM * MAX_DIAM * MAX_DIAM];
private readonly int[] overlappingPoints = new int[POINTS_PER_CELL * MAX_DIAM * MAX_DIAM * MAX_DIAM];
private readonly HashSet<int> markedOverlappingCells = new HashSet<int>();
private int numOverlapCells;
public int NumOverlappingCells => numOverlapCells;
public static void Clear(SpacePartitions spacePartitions) {
for (int i = 0; i < NUM_CELLS; ++i) {
spacePartitions.numPointsPerCell[i] = 0;
}
}
public static void AddPoints(SpacePartitions partitions,
int[] instanceIds,
Vector3[] points,
Quaternion[] localSphereRots,
int count) {
for (int i = 0; i < count; ++i) {
if (!IsValidPoint(points[i])) {
continue;
}
int cell = GetCellIndex(points[i]);
int pointCount = partitions.numPointsPerCell[cell];
if (pointCount == POINTS_PER_CELL) {
Debug.LogError($"Too many points in cell {cell}. Increase POINTS_PER_CELL. Currently at {POINTS_PER_CELL}");
continue;
}
int pos = cell * POINTS_PER_CELL + pointCount;
partitions.instanceIds[pos] = instanceIds[i];
partitions.points[pos] = points[i];
partitions.localSphereRot[pos] = localSphereRots[i];
partitions.numPointsPerCell[cell] += 1;
}
}
public static void RemovePoint(SpacePartitions partitions, int index) {
// Position at an invalid position. That'll cause the bounds check to fail, as if
// the point doesn't exist
partitions.points[index] = Vector3.up * SIDE_LEN * SIDE_LEN;
}
public static int FindOverlaps(SpacePartitions partitions,
Vector3 point,
float radius) {
partitions.numOverlapCells = 0;
partitions.markedOverlappingCells.Clear();
radius = Mathf.Min(radius, 3);
int numOverlapPoints = 0;
int r = Mathf.CeilToInt(radius);
Vector3[] coords;
switch (r) {
case 2: coords = CoordsRadius2.coords; break;
case 3: coords = CoordsRadius3.coords; break;
default: coords = CoordsRadius1.coords; break;
}
int numCoords = coords.Length;
for (int i = 0; i < numCoords; ++i) {
CacheOverlappingCell(partitions, point + coords[i]);
}
for (int i = 0; i < partitions.numOverlapCells; ++i) {
int cellIndex = partitions.overlapCells[i];
int cellOffset = cellIndex * POINTS_PER_CELL;
int len = partitions.numPointsPerCell[cellIndex];
for (int j = 0; j < len; ++j) {
Vector3 other = partitions.points[cellOffset + j];
if (Vector3.SqrMagnitude(other - point) <= radius * radius) {
partitions.overlappingPoints[numOverlapPoints] = cellOffset + j;
++numOverlapPoints;
}
}
}
return numOverlapPoints;
}
private static void CacheOverlappingCell(SpacePartitions partitions, Vector3 point) {
if (!IsValidPoint(point)) {
return;
}
int cell = GetCellIndex(point);
if (partitions.markedOverlappingCells.Contains(cell)) {
return;
}
partitions.markedOverlappingCells.Add(cell);
partitions.overlapCells[partitions.numOverlapCells] = cell;
++partitions.numOverlapCells;
}
// returns the index of the overlapping point
// provide an index local to the overlappingPoints array
public static int GetOverlappingPointIndex(SpacePartitions partitions, int overlapPointIndex) {
return partitions.overlappingPoints[overlapPointIndex];
}
public static int GetInstanceId(SpacePartitions partitions, int index) {
return partitions.instanceIds[index];
}
public static Vector3 GetPoint(SpacePartitions partitions, int index) {
return partitions.points[index];
}
public static Quaternion GetLocalSphereRotation(SpacePartitions partitions, int index) {
return partitions.localSphereRot[index];
}
public static Vector3 GetOverlappingCellCoord(SpacePartitions spacePartitions, int overlapCellIndex) {
return GetCellCoord(spacePartitions.overlapCells[overlapCellIndex]);
}
public static Vector3 GetCellCoord(int cellIndex) {
int y = Mathf.FloorToInt(cellIndex / SIDE_AREAL);
int yvol = y * SIDE_AREAL;
int z = Mathf.FloorToInt((cellIndex - yvol) / SIDE_LEN);
int zvol = z * SIDE_LEN;
int x = cellIndex - yvol - zvol;
return new Vector3(x - OFFSET,
y - OFFSET,
z - OFFSET);
}
public static int GetCellIndex(Vector3 point) {
return Mathf.FloorToInt(point.y + OFFSET) * SIDE_AREAL +
Mathf.FloorToInt(point.z + OFFSET) * SIDE_LEN +
Mathf.FloorToInt(point.x + OFFSET);
}
public static bool IsValidPoint(Vector3 point) {
int x = Mathf.FloorToInt(point.x);
int y = Mathf.FloorToInt(point.y);
int z = Mathf.FloorToInt(point.z);
return x >= -OFFSET && x < OFFSET
&& y >= -OFFSET && y < OFFSET
&& z >= -OFFSET && z < OFFSET;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment