I tried making an octree, but it doesn’t work very well. The problem is that when an entity is partially in one octree, and partially in another, it gets added to both. What I want is to get all the entities that don’t fit evenly into a child octree, and compare all of those against each other.
Posdim is for holding the position and the dimensions of an Entity.
BoundingCube represents a cube with a certain size at a certain position.
EDIT: I just realized that I probably shouldn’t be destroying the tree and making a new one every frame…
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Octree {
public static int octreesLoaded;
public static short minimumOctreeSize = 16;
public static short entityCountForSplit = 10;
public BoundingCube boundingCube;
public Octree parentOctree;
public Octree[] childOctrees;
public List<Entity> containedEntities = new List<Entity>();
public Octree(Octree parentOctree, List<Entity> containedEntities, BoundingCube boundingCube)
{
this.parentOctree = parentOctree;
this.containedEntities = containedEntities;
this.boundingCube = boundingCube;
octreesLoaded++;
if (boundingCube.size > minimumOctreeSize && this.containedEntities.Count >= entityCountForSplit)
{
CreateChildOctrees();
}
else
{
CheckForCollisions();
}
}
void CheckForCollisions()
{
if (containedEntities.Count >= 2)
{
for (int i = 0; i < containedEntities.Count; i++)
{
for (int j = 0; j < containedEntities.Count; j++)
{
if (containedEntities[i] != containedEntities[j])
{
if (World.IntersectsWith(containedEntities[j].posdim, containedEntities[i].posdim))
{
containedEntities[i].RunCollision(containedEntities[j]);
}
}
}
}
}
}
void CreateChildOctrees()
{
childOctrees = new Octree[8];
List<Entity>[] entityArrays = new List<Entity>[8];
for(int i = 0; i < entityArrays.Length; i++)
{
entityArrays[i] = new List<Entity>();
}
for (int i = 0; i < containedEntities.Count; i++)
{
if (InBounds(boundingCube.LeftBottomFront, containedEntities[i].posdim))
{
entityArrays[0].Add(containedEntities[i]);
}
if (InBounds(boundingCube.RightBottomFront, containedEntities[i].posdim))
{
entityArrays[1].Add(containedEntities[i]);
}
if (InBounds(boundingCube.LeftTopFront, containedEntities[i].posdim))
{
entityArrays[2].Add(containedEntities[i]);
}
if (InBounds(boundingCube.RightTopFront, containedEntities[i].posdim))
{
entityArrays[3].Add(containedEntities[i]);
}
if (InBounds(boundingCube.LeftBottomBack, containedEntities[i].posdim))
{
entityArrays[4].Add(containedEntities[i]);
}
if (InBounds(boundingCube.RightBottomBack, containedEntities[i].posdim))
{
entityArrays[5].Add(containedEntities[i]);
}
if (InBounds(boundingCube.LeftTopBack, containedEntities[i].posdim))
{
entityArrays[6].Add(containedEntities[i]);
}
if (InBounds(boundingCube.RightTopBack, containedEntities[i].posdim))
{
entityArrays[7].Add(containedEntities[i]);
}
}
childOctrees[0] = new Octree(this, entityArrays[0], boundingCube.LeftBottomFront);
childOctrees[1] = new Octree(this, entityArrays[1], boundingCube.RightBottomFront);
childOctrees[2] = new Octree(this, entityArrays[2], boundingCube.LeftTopFront);
childOctrees[3] = new Octree(this, entityArrays[3], boundingCube.RightTopFront);
childOctrees[4] = new Octree(this, entityArrays[4], boundingCube.LeftBottomBack);
childOctrees[5] = new Octree(this, entityArrays[5], boundingCube.RightBottomBack);
childOctrees[6] = new Octree(this, entityArrays[6], boundingCube.LeftTopBack);
childOctrees[7] = new Octree(this, entityArrays[7], boundingCube.RightTopBack);
}
bool InBounds(BoundingCube boundingCube, Posdim posdim)
{
if (posdim.Pos.x + posdim.Dim.x > boundingCube.Pos.x && posdim.Pos.x + posdim.Pos.x < boundingCube.Pos.x + boundingCube.size)
{
if (posdim.Pos.y + posdim.Dim.y > boundingCube.Pos.y && posdim.Pos.y + posdim.Pos.y < boundingCube.Pos.y + boundingCube.size)
{
if (posdim.Pos.z + posdim.Dim.z > boundingCube.Pos.z && posdim.Pos.z + posdim.Pos.z < boundingCube.Pos.z + boundingCube.size)
{
return true;
}
}
}
return false;
}
}