From 330c1b1e5244b3f21b110a153b395f5eb0b78012 Mon Sep 17 00:00:00 2001 From: Andy Baker Date: Fri, 11 Oct 2024 19:15:18 +0100 Subject: [PATCH] Work in progress integration of NativeTrees wrapper --- Assets/Scripts/model/core/SpatialIndex.cs | 10 +- Assets/Scripts/model/csg/CsgContext.cs | 2 +- Assets/Scripts/model/util/BurstSpatial.cs | 198 ++++++++++++++++++ .../Scripts/model/util/BurstSpatial.cs.meta | 3 + 4 files changed, 207 insertions(+), 6 deletions(-) create mode 100644 Assets/Scripts/model/util/BurstSpatial.cs create mode 100644 Assets/Scripts/model/util/BurstSpatial.cs.meta diff --git a/Assets/Scripts/model/core/SpatialIndex.cs b/Assets/Scripts/model/core/SpatialIndex.cs index 10e84a3c..5b43d246 100644 --- a/Assets/Scripts/model/core/SpatialIndex.cs +++ b/Assets/Scripts/model/core/SpatialIndex.cs @@ -110,11 +110,11 @@ public SpatialIndex(Model model, Bounds bounds) private void Setup(Bounds bounds) { - meshes = new OctreeImpl(bounds); - faces = new OctreeImpl(bounds); - edges = new OctreeImpl(bounds); - vertices = new OctreeImpl(bounds); - meshBounds = new OctreeImpl(bounds); + meshes = new BurstSpatial(); + faces = new BurstSpatial(); + edges = new BurstSpatial(); + vertices = new BurstSpatial(); + meshBounds = new BurstSpatial(); faceInfo = new Dictionary(); edgeInfo = new Dictionary(); diff --git a/Assets/Scripts/model/csg/CsgContext.cs b/Assets/Scripts/model/csg/CsgContext.cs index 7f05833c..5a7ed0af 100644 --- a/Assets/Scripts/model/csg/CsgContext.cs +++ b/Assets/Scripts/model/csg/CsgContext.cs @@ -33,7 +33,7 @@ public class CsgContext public CsgContext(Bounds bounds) { - tree = new OctreeImpl(bounds); + tree = new BurstSpatial(); } public CsgVertex CreateOrGetVertexAt(Vector3 loc) diff --git a/Assets/Scripts/model/util/BurstSpatial.cs b/Assets/Scripts/model/util/BurstSpatial.cs new file mode 100644 index 00000000..cfd6bbe4 --- /dev/null +++ b/Assets/Scripts/model/util/BurstSpatial.cs @@ -0,0 +1,198 @@ +// Copyright 2024 The Open Blocks Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.Collections.Generic; +using com.google.apps.peltzer.client.model.core; +using com.google.apps.peltzer.client.model.util; +using NativeTrees; +using UnityEngine; + +/// +/// Class wrapping NativeTrees functions which implement our collision system. +/// +public static class BurstSpatialFunction +{ + private static List> _indices = new(); + + public static int AllocSpatialPartitioner() + { + var octree = new NativeOctree(); + _indices.Add(octree); + return _indices.Count - 1; + } + + public static void SpatialPartitionerAddItem(int idx, int itemId, Vector3 center, Vector3 extents) + { + _indices[idx].InsertPoint(itemId, center); + } + + public static void SpatialPartitionerUpdateAll(int idx, object itemIds) + { + var octree = new NativeOctree(); + _indices[idx] = _indices[idx]; + } + + public static void SpatialPartitionerRemoveItem(int idx, int itemId) + { + throw new NotImplementedException(); + } + + public static int SpatialPartitionerContainedBy(int idx, Vector3 testCenter, Vector3 testExtents, int[] returnArray, int returnArrayMaxSize) + { + throw new NotImplementedException(); + } + + public static int SpatialPartitionerIntersectedBy(int idx, Vector3 testCenter, Vector3 testExtents, int[] returnArray, int returnArrayMaxSize) + { + throw new NotImplementedException(); + } + + public static int HasItem(int idx, int itemHandle) + { + throw new NotImplementedException(); + } +} + +public class BurstSpatial : CollisionSystem +{ + + // A unique handle that identifies this collision system + private int spatialPartitionId; + // Used for super cheap id allocation - we use this id and increment. + private int nextHandleId = 0; + // A mapping from the items in this system to their numeric handle + private Dictionary itemIds = new Dictionary(); + // A mapping of numeric handles to items in the system. + private Dictionary idsToItems = new Dictionary(); + // A mapping of items in the system to their Bounds. + private Dictionary itemBounds = new Dictionary(); + // A preallocated array for retrieving results + private int[] results = new int[SpatialIndex.MAX_INTERSECT_RESULTS]; + + public BurstSpatial() + { + spatialPartitionId = BurstSpatialFunction.AllocSpatialPartitioner(); + } + + /// + /// Adds an item to the CollisionSystem. + /// + public void Add(T item, Bounds bounds) + { + int id = nextHandleId++; + itemIds[item] = id; + idsToItems[id] = item; + itemBounds[item] = bounds; + BurstSpatialFunction.SpatialPartitionerAddItem(spatialPartitionId, id, bounds.center, bounds.extents); + } + public void UpdateItemBounds(T item, Bounds bounds) + { + throw new NotImplementedException(); + } + + /// + /// Updates the bounding box of an item already in the collision system. + /// + // public void UpdateItemBounds(T item, Bounds bounds) + // { + // itemIds[item].b + // BurstSpatialFunction.SpatialPartitionerUpdateAll(spatialPartitionId, itemIds); + // } + + /// + /// Remove an item from the system. + /// + /// Item to remove. + /// + /// Thrown when the item isn't in the tree. + public void Remove(T item) + { + int id = itemIds[item]; + itemIds.Remove(item); + idsToItems.Remove(id); + itemBounds.Remove(item); + BurstSpatialFunction.SpatialPartitionerUpdateAll(spatialPartitionId, itemIds); + } + + /// + /// Find items contained entirely within the given bounds. + /// This method will create a set when the number of items + /// is greater than zero. + /// + /// Containing bounds. + /// Set of items found. Null when this + /// method returns false. + /// Maximum number of items to find. + /// true if any items are found. + public bool ContainedBy(Bounds bounds, out HashSet items, + int limit = SpatialIndex.MAX_INTERSECT_RESULTS) + { + int numResults = BurstSpatialFunction.SpatialPartitionerContainedBy(spatialPartitionId, bounds.center, + bounds.extents, results, limit); + items = new HashSet(); + for (int i = 0; i < numResults; i++) + { + items.Add(idsToItems[results[i]]); + } + return items.Count > 0; + } + + /// + /// Returns whether the item is tracked in this system. + /// + public bool HasItem(T item) + { + bool inItems = itemIds.ContainsKey(item); + return inItems; + } + + /// + /// Checks whether the supplied Bounds intersects anything in the system, and returns a HashSet + /// of intersection objects. Returns true if there were any intersections. + /// + public bool IntersectedBy(Bounds bounds, out HashSet items, + int limit = SpatialIndex.MAX_INTERSECT_RESULTS) + { + int numResults = BurstSpatialFunction.SpatialPartitionerIntersectedBy(spatialPartitionId, bounds.center, + bounds.extents, results, limit); + items = new HashSet(); + for (int i = 0; i < numResults; i++) + { + items.Add(idsToItems[results[i]]); + } + return items.Count > 0; + } + + /// + /// Checks whether the supplied Bounds intersects anything in the system, and fills the supplied preallocated Hashset + /// with intersected items. Returns true if there were any intersections. + /// + public bool IntersectedByPreallocated(Bounds bounds, ref HashSet items, + int limit = SpatialIndex.MAX_INTERSECT_RESULTS) + { + int numResults = BurstSpatialFunction.SpatialPartitionerIntersectedBy(spatialPartitionId, bounds.center, + bounds.extents, results, limit); + for (int i = 0; i < numResults; i++) + { + items.Add(idsToItems[results[i]]); + } + return items.Count > 0; + } + + public Bounds BoundsForItem(T item) + { + return itemBounds[item]; + } +} diff --git a/Assets/Scripts/model/util/BurstSpatial.cs.meta b/Assets/Scripts/model/util/BurstSpatial.cs.meta new file mode 100644 index 00000000..e0a1b41e --- /dev/null +++ b/Assets/Scripts/model/util/BurstSpatial.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 37f45494c3fa46a687ef41ff65f8aabf +timeCreated: 1728471085 \ No newline at end of file