void OnDestroy() { if (octreeNode != null) { HxVolumetricCamera.AllParticleSystems.Remove(this); HxVolumetricCamera.RemoveParticletOctree(this); octreeNode = null; } }
/// <summary> /// Create a bounds octree. /// </summary> /// <param name="origin">Position of the centre of the initial node.</param> /// <param name="initialSize">Starting node size.</param> /// <param name="overlap">Percentage overlap between nodes (0-1).</param> /// <param name="minNodeSize">Cannot split past this node size.</param> public HxOctree(Vector3 origin = new Vector3(), float initialSize = 10f, float overlap = 0f, float minNodeSize = 1f) { Count = 0; InitialSize = Mathf.Max(minNodeSize, initialSize); MinNodeSize = Mathf.Min(minNodeSize, initialSize); Overlap = Mathf.Clamp(overlap, 0f, 1f); Root = new HxOctreeNode <T>(InitialSize, overlap, MinNodeSize, origin, null); NodeMap = new Dictionary <T, HxOctreeNode <T> .NodeObject>(); }
// Use this for initialization void OnEnable() { CalculateBounds(); if (DensityOctree == null) { DensityOctree = new HxOctree <HxDensityVolume>(); } HxVolumetricCamera.AllDensityVolumes.Add(this); octreeNode = DensityOctree.Add(this, minBounds, maxBounds); }
/// <summary> /// Remove an object and try to shrink the octree. /// </summary> public bool Remove(T value) { if (Root.Remove(value)) { NodeMap.Remove(value); Count--; Root = Root.TryShrink(InitialSize); return(true); } return(false); }
public void Add(NodeObject node) { if (Objects.Count < MaxObjectCount || Size < MinSize * 2f) { node.Node = this; Objects.Add(node); } else { int index; if (Children == null) { float childSize = Size / 2f; float offset = Size / 4f; Children = new HxOctreeNode <T> [8]; Children[0] = new HxOctreeNode <T>(childSize, Overlap, MinSize, Origin + new Vector3(-1, 1, -1) * offset, this); Children[1] = new HxOctreeNode <T>(childSize, Overlap, MinSize, Origin + new Vector3(1, 1, -1) * offset, this); Children[2] = new HxOctreeNode <T>(childSize, Overlap, MinSize, Origin + new Vector3(-1, 1, 1) * offset, this); Children[3] = new HxOctreeNode <T>(childSize, Overlap, MinSize, Origin + new Vector3(1, 1, 1) * offset, this); Children[4] = new HxOctreeNode <T>(childSize, Overlap, MinSize, Origin + new Vector3(-1, -1, -1) * offset, this); Children[5] = new HxOctreeNode <T>(childSize, Overlap, MinSize, Origin + new Vector3(1, -1, -1) * offset, this); Children[6] = new HxOctreeNode <T>(childSize, Overlap, MinSize, Origin + new Vector3(-1, -1, 1) * offset, this); Children[7] = new HxOctreeNode <T>(childSize, Overlap, MinSize, Origin + new Vector3(1, -1, 1) * offset, this); // Reconfigure the objects in this node to the appropriate child nodes for (int i = Objects.Count - 1; i >= 0; i--) { NodeObject obj = Objects[i]; index = OctantIndex(obj.Center); if (BoundsContains(Children[index].BoundsMin, Children[index].BoundsMax, obj.BoundsMin, obj.BoundsMax)) { Children[index].Add(obj); Objects.Remove(obj); } } } // add the new object index = OctantIndex(node.Center); if (BoundsContains(Children[index].BoundsMin, Children[index].BoundsMax, node.BoundsMin, node.BoundsMax)) { Children[index].Add(node); } else { node.Node = this; Objects.Add(node); } } }
void ExpandRoot(Vector3 center) { Vector3 direction = Root.Origin - center; int xDir = direction.x < 0 ? -1 : 1; int yDir = direction.y < 0 ? -1 : 1; int zDir = direction.z < 0 ? -1 : 1; HxOctreeNode <T> oldRoot = Root; float halfSize = Root.Size / 2f; Vector3 newOrigin = Root.Origin - new Vector3(xDir, yDir, zDir) * halfSize; // Expand the root node to a new one that includes the old one as a child Root = new HxOctreeNode <T>(Root.Size * 2f, Overlap, MinNodeSize, newOrigin, null); oldRoot.Parent = Root; int index = 0; if (xDir > 0) { index += 1; } if (zDir > 0) { index += 2; } if (yDir < 0) { index += 4; } HxOctreeNode <T>[] children = new HxOctreeNode <T> [8]; for (int i = 0; i < 8; i++) { if (i == index) { children[i] = oldRoot; } else { xDir = (i % 2 == 0) ? -1 : 1; yDir = (i > 3) ? -1 : 1; zDir = (i < 2 || (i > 3 && i < 6)) ? -1 : 1; children[i] = new HxOctreeNode <T>(oldRoot.Size, Overlap, MinNodeSize, newOrigin + new Vector3(xDir, yDir, zDir) * halfSize, Root); } } Root.Children = children; }
void Init(float size, float overlap, float minSize, Vector3 origin, HxOctreeNode <T> parent) { Parent = parent; Size = size; MinSize = minSize; Overlap = overlap; Origin = origin; SizeWithOverlap = (1f + Overlap) * Size; Vector3 extents = new Vector3(SizeWithOverlap, SizeWithOverlap, SizeWithOverlap) / 2f; BoundsMin = Origin - extents; BoundsMax = Origin + extents; Vector3 childExtents = (Vector3.one * (Size / 2f) * (1f + Overlap)) / 2f; float offset = Size / 4f; ChildrenBoundsMin = new Vector3[8]; ChildrenBoundsMax = new Vector3[8]; Vector3 o; o = Origin + new Vector3(-1, 1, -1) * offset; ChildrenBoundsMin[0] = o - childExtents; ChildrenBoundsMax[0] = o + childExtents; o = Origin + new Vector3(1, 1, -1) * offset; ChildrenBoundsMin[1] = o - childExtents; ChildrenBoundsMax[1] = o + childExtents; o = Origin + new Vector3(-1, 1, 1) * offset; ChildrenBoundsMin[2] = o - childExtents; ChildrenBoundsMax[2] = o + childExtents; o = Origin + new Vector3(1, 1, 1) * offset; ChildrenBoundsMin[3] = o - childExtents; ChildrenBoundsMax[3] = o + childExtents; o = Origin + new Vector3(-1, -1, -1) * offset; ChildrenBoundsMin[4] = o - childExtents; ChildrenBoundsMax[4] = o + childExtents; o = Origin + new Vector3(1, -1, -1) * offset; ChildrenBoundsMin[5] = o - childExtents; ChildrenBoundsMax[5] = o + childExtents; o = Origin + new Vector3(-1, -1, 1) * offset; ChildrenBoundsMin[6] = o - childExtents; ChildrenBoundsMax[6] = o + childExtents; o = Origin + new Vector3(1, -1, 1) * offset; ChildrenBoundsMin[7] = o - childExtents; ChildrenBoundsMax[7] = o + childExtents; }
void CheckLightType() { if (lastType != GetLightType()) { if (lastType == LightType.Directional) { octreeNode = HxVolumetricCamera.AddLightOctree(this, minBounds, maxBounds); HxVolumetricCamera.ActiveDirectionalLights.Remove(this); } else if (GetLightType() == LightType.Directional && (lastType == LightType.Point || lastType == LightType.Spot)) { HxVolumetricCamera.RemoveLightOctree(this); octreeNode = null; HxVolumetricCamera.ActiveDirectionalLights.Add(this); } } lastType = GetLightType(); }
void OnEnable() { particleRenderer = GetComponent <Renderer>(); LastBounds = particleRenderer.bounds; minBounds = LastBounds.min; maxBounds = LastBounds.max; if (octreeNode == null) { #if UNITY_EDITOR if (Application.isPlaying == false) { GetComponent <ParticleSystem>().Simulate(0); } #endif HxVolumetricCamera.AllParticleSystems.Add(this); octreeNode = HxVolumetricCamera.AddParticleOctree(this, minBounds, maxBounds); } }
public HxOctreeNode <T> .NodeObject Add(T value, Vector3 boundsMin, Vector3 boundsMax) { int counter = 0; while (!HxOctreeNode <T> .BoundsContains(Root.BoundsMin, Root.BoundsMax, boundsMin, boundsMax)) { ExpandRoot((boundsMin + boundsMax) / 2f); if (++counter > 16) { Debug.LogError("The octree could not contain the bounds."); return(null); } } var node = new HxOctreeNode <T> .NodeObject(value, boundsMin, boundsMax); NodeMap[value] = node; Root.Add(node); Count++; return(node); }
public void Move(HxOctreeNode <T> .NodeObject value, Vector3 boundsMin, Vector3 boundsMax) { if (value == null) { Debug.Log("null"); } value.BoundsMin = boundsMin; value.BoundsMax = boundsMax; var currentNode = value.Node; if (!HxOctreeNode <T> .BoundsContains(currentNode.BoundsMin, currentNode.BoundsMax, boundsMin, boundsMax)) { currentNode.Remove(value.Value); int counter = 0; while (!HxOctreeNode <T> .BoundsContains(currentNode.BoundsMin, currentNode.BoundsMax, boundsMin, boundsMax)) { if (currentNode.Parent != null) { currentNode = currentNode.Parent; } else // current node is the root, expand it { counter++; ExpandRoot((boundsMin + boundsMax) / 2f); currentNode = Root; if (counter > 16) { Debug.LogError("The octree could not contain the bounds."); return; } } } currentNode.Add(value); } // Root = Root.TryShrink(InitialSize); }
public void TryShrink() { Root = Root.TryShrink(InitialSize); }
// Methods private void Init(float size, float overlap, float minSize, Vector3 origin, HxOctreeNode <T> parent) { }
} // Dummy constructor public HxOctreeNode(float size, float overlap, float minSize, Vector3 origin, HxOctreeNode <T> parent) { }
public HxOctreeNode(float size, float overlap, float minSize, Vector3 origin, HxOctreeNode <T> parent) { ID = _idCtr++; Init(size, overlap, minSize, origin, parent); }
public void Move(HxOctreeNode <T> value, Vector3 boundsMin, Vector3 boundsMax) { }