1
This commit is contained in:
10
Src/Unity/Scripts/Quadtree/Items/GameObjectItem.cs
Normal file
10
Src/Unity/Scripts/Quadtree/Items/GameObjectItem.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace Quadtree.Items
|
||||
{
|
||||
public abstract class GameObjectItem : GameObjectItemBase<GameObjectItem, Node<GameObjectItem>>
|
||||
{
|
||||
protected override GameObjectItem This() => this;
|
||||
}
|
||||
}
|
11
Src/Unity/Scripts/Quadtree/Items/GameObjectItem.cs.meta
Normal file
11
Src/Unity/Scripts/Quadtree/Items/GameObjectItem.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3bb93ae6561edaa49a599f7ccf090da1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
152
Src/Unity/Scripts/Quadtree/Items/GameObjectItemBase.cs
Normal file
152
Src/Unity/Scripts/Quadtree/Items/GameObjectItemBase.cs
Normal file
@@ -0,0 +1,152 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Quadtree.Items
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom item interface for GameObject quadtree items.
|
||||
/// </summary>
|
||||
public abstract class GameObjectItemBase<TItem, TNode> : MonoBehaviour, IItem<TItem, TNode>
|
||||
where TItem : IItem<TItem, TNode>
|
||||
where TNode : INode<TItem, TNode>
|
||||
{
|
||||
/// <summary>
|
||||
/// Game object's bounds from last update call.
|
||||
/// </summary>
|
||||
private Bounds _lastBounds;
|
||||
|
||||
/// <summary>
|
||||
/// Game object's bounds from last update call.
|
||||
/// </summary>
|
||||
private Bounds _safeBounds;
|
||||
|
||||
//==========================================================================dd==
|
||||
// MonoBehaviour METHODS
|
||||
//==========================================================================dd==
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Root = null;
|
||||
ItemInitialized = false;
|
||||
ParentNode.Remove(This());
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
var currentBounds = GetBounds();
|
||||
if (currentBounds != _lastBounds)
|
||||
{
|
||||
// the object has moved or changed size
|
||||
var forceInsertionEvaluation = false;
|
||||
if (!currentBounds.Intersects(_safeBounds)
|
||||
|| (currentBounds.size - _lastBounds.size).magnitude > 0)
|
||||
{
|
||||
// ...far enough to force re-insertion
|
||||
forceInsertionEvaluation = true;
|
||||
_safeBounds = currentBounds;
|
||||
}
|
||||
|
||||
// current object bounds are not the same as last update
|
||||
// initiate tree update from currently
|
||||
ParentNode?.Update(This(), forceInsertionEvaluation);
|
||||
_lastBounds = currentBounds;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================dd==
|
||||
// CORE TREE ITEM METHODS
|
||||
//==========================================================================dd==
|
||||
|
||||
/// <summary>
|
||||
/// <c>True</c> if the item has been initialized.
|
||||
/// </summary>
|
||||
protected internal bool ItemInitialized = false;
|
||||
|
||||
public IQuadtreeRoot<TItem, TNode> Root { get; set; }
|
||||
|
||||
public TNode ParentNode { get; set; }
|
||||
|
||||
public abstract Bounds GetBounds();
|
||||
|
||||
public void QuadTree_Root_Initialized(IQuadtreeRoot<TItem, TNode> root)
|
||||
{
|
||||
Root = root;
|
||||
|
||||
if (ItemInitialized)
|
||||
{
|
||||
// the item has been initialized before the tree root
|
||||
root.Insert(This());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns reference to corresponding game object.
|
||||
/// </summary>
|
||||
///
|
||||
/// <returns>Game object instance.</returns>
|
||||
public abstract GameObject GetGameObject();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the item instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This may be called either before or after the initialization of the tree root.
|
||||
/// </remarks>
|
||||
protected virtual void Init()
|
||||
{
|
||||
// designate item as initialized
|
||||
ItemInitialized = true;
|
||||
|
||||
// set initial last bounds
|
||||
_lastBounds = GetBounds();
|
||||
// set initial safe bounds
|
||||
_safeBounds = _lastBounds;
|
||||
|
||||
if (Root == null)
|
||||
{
|
||||
if (TryGetComponent(out GameObjectQuadtreeRoot quadtreeRoot) && quadtreeRoot.Initialized)
|
||||
{
|
||||
Root = (IQuadtreeRoot<TItem, TNode>)quadtreeRoot;
|
||||
}
|
||||
}
|
||||
|
||||
if (Root != null)
|
||||
{
|
||||
// the tree root has been initialized before the item
|
||||
Root.Insert(This());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overloaded in sub-classes to return correct instance of the item.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is necessary due to generic typechecking -- <c>this</c> in context of the abstract generic class does not reference TItem itself.
|
||||
/// </remarks>
|
||||
///
|
||||
/// <returns>Instance of the item</returns>
|
||||
protected abstract TItem This();
|
||||
|
||||
/// <summary>
|
||||
/// Returns unique identifier of the item.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is extremely important to override this method because nodes are using HashSets to store items and the items are changing during the updates and so are the hash codes which can result in program not working properly.
|
||||
/// </remarks>
|
||||
///
|
||||
/// <returns>Unique identifier</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return GetInstanceID();
|
||||
}
|
||||
}
|
||||
}
|
11
Src/Unity/Scripts/Quadtree/Items/GameObjectItemBase.cs.meta
Normal file
11
Src/Unity/Scripts/Quadtree/Items/GameObjectItemBase.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34e0c8684cc1c224a91b831b8c99c968
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
29
Src/Unity/Scripts/Quadtree/Items/IItem.cs
Normal file
29
Src/Unity/Scripts/Quadtree/Items/IItem.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Quadtree.Items
|
||||
{
|
||||
/// <summary>
|
||||
/// Mandatory interface of any quadtree item.
|
||||
/// </summary>
|
||||
public interface IItem<TItem, TNode>
|
||||
where TItem : IItem<TItem, TNode>
|
||||
where TNode : INode<TItem, TNode>
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns object bounds.
|
||||
/// </summary>
|
||||
///
|
||||
/// <returns>Object box bounds.</returns>
|
||||
Bounds GetBounds();
|
||||
|
||||
/// <summary>
|
||||
/// Node which currently contains the item.
|
||||
/// </summary>
|
||||
TNode ParentNode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Receiver method for broadcasted tree initialization message.
|
||||
/// </summary>
|
||||
void QuadTree_Root_Initialized(IQuadtreeRoot<TItem, TNode> root);
|
||||
}
|
||||
}
|
11
Src/Unity/Scripts/Quadtree/Items/IItem.cs.meta
Normal file
11
Src/Unity/Scripts/Quadtree/Items/IItem.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e6be24bac4fd4a409194655d1cf0665
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
46
Src/Unity/Scripts/Quadtree/Items/RendererItem.cs
Normal file
46
Src/Unity/Scripts/Quadtree/Items/RendererItem.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Quadtree.Items
|
||||
{
|
||||
/// <summary>
|
||||
/// Boundaries of this quadtree item are determined by present <c>UnityEngine.Renderer</c> component.
|
||||
/// </summary>
|
||||
[ExecuteInEditMode]
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(Renderer))]
|
||||
[AddComponentMenu("Spatial partitioning/Quadtree/Items/Renderer-based Item")]
|
||||
public class RendererItem : GameObjectItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the item should be automatically inserted into the tree upon its initialization.
|
||||
/// </summary>
|
||||
///
|
||||
/// <seealso cref="QuadtreeMonoRoot{TItem}.Insert(TItem)"/>
|
||||
[SerializeField]
|
||||
protected bool InsertOnInitialization = true;
|
||||
|
||||
private Renderer _renderer;
|
||||
|
||||
//==========================================================================dd==
|
||||
// Quadtree ITEM METHODS
|
||||
//==========================================================================dd==
|
||||
|
||||
/// <summary>
|
||||
/// Finds and locally stores this <c>GameObject</c>'s <c>Renderer</c> component instance.
|
||||
/// </summary>
|
||||
protected override void Init()
|
||||
{
|
||||
// load game object renderer component
|
||||
_renderer = GetComponent<Renderer>();
|
||||
|
||||
base.Init();
|
||||
}
|
||||
|
||||
public override Bounds GetBounds()
|
||||
{
|
||||
return _renderer.bounds;
|
||||
}
|
||||
|
||||
public override GameObject GetGameObject() => gameObject;
|
||||
}
|
||||
}
|
11
Src/Unity/Scripts/Quadtree/Items/RendererItem.cs.meta
Normal file
11
Src/Unity/Scripts/Quadtree/Items/RendererItem.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b92b133d7eeb95b4d95b27cf8ef679b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user