-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added triangle adapter. #2
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
using UnityEngine; | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
|
||
namespace DataStructures { | ||
public interface Triangle { | ||
Vector3 a { get; set; } | ||
Vector3 b { get; set; } | ||
Vector3 c { get; set; } | ||
} | ||
|
||
public class BVHRayHitTest { | ||
public BVHRayHitTest(Ray _ray) { | ||
ray = _ray; | ||
} | ||
public bool NodeTraversalTest(Bounds box) => box.IntersectRay(ray); | ||
public Ray ray { get; set; } | ||
} | ||
|
||
public class BVHTriangleAdapter : IBVHNodeAdapter<Triangle> { | ||
private BVH<Triangle> _bvh; | ||
private Dictionary<Triangle, BVHNode<Triangle>> triangeToLeafMap = new Dictionary<Triangle, BVHNode<Triangle>>(); | ||
|
||
|
||
BVH<Triangle> IBVHNodeAdapter<Triangle>.BVH { get => _bvh; set { _bvh = value; }} | ||
|
||
public void CheckMap(Triangle triangle) { | ||
if (!triangeToLeafMap.ContainsKey(triangle)) { | ||
throw new Exception("missing map for shuffled child!"); | ||
} | ||
} | ||
|
||
public BVHNode<Triangle> GetLeaf(Triangle triangle) => triangeToLeafMap[triangle]; | ||
public Vector3 GetObjectPos(Triangle triangle) { | ||
float x = (triangle.a.x + triangle.b.x + triangle.c.x) / 3.0f; | ||
float y = (triangle.a.y + triangle.b.y + triangle.c.y) / 3.0f; | ||
float z = (triangle.a.z + triangle.b.z + triangle.c.z) / 3.0f; | ||
return new Vector3(x, y, z); | ||
} | ||
|
||
public float GetRadius(Triangle triangle) { | ||
Vector3 centroid = new Vector3( | ||
(triangle.a.x + triangle.b.x + triangle.c.x) / 3.0f, | ||
(triangle.a.y + triangle.b.y + triangle.c.y) / 3.0f, | ||
(triangle.a.z + triangle.b.z + triangle.c.z) / 3.0f | ||
); | ||
return Mathf.Max( | ||
Mathf.Max(Vector3.Distance(centroid, triangle.a), Vector3.Distance(centroid, triangle.b), | ||
Vector3.Distance(centroid, triangle.c))); | ||
} | ||
|
||
public void MapObjectToBVHLeaf(Triangle triangle, BVHNode<Triangle> node) { | ||
triangeToLeafMap[triangle] = node; | ||
} | ||
|
||
public void OnPositionOrSizeChanged(Triangle changed) | ||
{ | ||
// the SSObject has changed, so notify the BVH leaf to refit for the object | ||
triangeToLeafMap[changed].RefitObjectChanged(this, changed); | ||
} | ||
|
||
public void UnmapObject(Triangle triangle) { | ||
triangeToLeafMap.Remove(triangle); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,7 @@ public class BVH<T> | |
public BVHNode<T> rootBVH; | ||
public IBVHNodeAdapter<T> nAda; | ||
public readonly int LEAF_OBJ_MAX; | ||
public readonly float MIN_NODE_VOLUME; | ||
public int nodeCount = 0; | ||
public int maxDepth = 0; | ||
|
||
|
@@ -79,6 +80,38 @@ public List<BVHNode<T>> Traverse(NodeTraversalTest hitTest) | |
return hits; | ||
} | ||
|
||
public SortedList<float, BVHNode<T>> SortedTraverse(NodeTraversalTest hitTest) { | ||
SortedList<float, BVHNode<T>> sortedHit = new SortedList<float, BVHNode<T>>(); | ||
void traverse(BVHNode<T> node, NodeTraversalTest hitTest, SortedList<float, BVHNode<T>> hitList) { | ||
if (node == null) return; | ||
if (hitTest(node.Box)) { | ||
hitList[Vector3.Magnitude(node.Box.size)] = node; | ||
traverse(node.Left, hitTest, hitList); | ||
traverse(node.Right, hitTest, hitList); | ||
} | ||
} | ||
traverse(rootBVH, hitTest, sortedHit); | ||
return sortedHit; | ||
} | ||
|
||
public bool IntersectRay(Ray ray, out BVHNode<T> nodeHit) { | ||
BVHNode<T> _hit = null; | ||
void traverse(BVHNode<T> node) { | ||
if (node == null) return; | ||
if (node.Box.IntersectRay(ray)) { | ||
if (node.IsLeaf) { | ||
_hit = node; | ||
return; | ||
} | ||
traverse(node.Left); | ||
traverse(node.Right); | ||
} | ||
} | ||
traverse(rootBVH); | ||
nodeHit = _hit; | ||
return nodeHit != null && nodeHit.IsLeaf; | ||
} | ||
|
||
/* | ||
public List<BVHNode<T> Traverse(Ray ray) | ||
{ | ||
|
@@ -159,9 +192,10 @@ public int CountBVHNodes() | |
/// <param name="nodeAdaptor"></param> | ||
/// <param name="objects"></param> | ||
/// <param name="LEAF_OBJ_MAX">WARNING! currently this must be 1 to use dynamic BVH updates</param> | ||
public BVH(IBVHNodeAdapter<T> nodeAdaptor, List<T> objects, int LEAF_OBJ_MAX = 1) | ||
public BVH(IBVHNodeAdapter<T> nodeAdaptor, List<T> objects, int LEAF_OBJ_MAX = 1, float MIN_NODE_VOLUME = 0.7f) | ||
{ | ||
this.LEAF_OBJ_MAX = LEAF_OBJ_MAX; | ||
this.MIN_NODE_VOLUME = MIN_NODE_VOLUME; | ||
nodeAdaptor.BVH = this; | ||
this.nAda = nodeAdaptor; | ||
|
||
|
@@ -202,6 +236,26 @@ public void GetAllNodeMatriciesRecursive(BVHNode<T> n, ref List<Matrix4x4> matri | |
if (n.Left != null) GetAllNodeMatriciesRecursive(n.Left, ref matricies, depth + 1); | ||
} | ||
|
||
public Matrix4x4 GetNodeMatrix(BVHNode<T> node) => Matrix4x4.Translate(node.Box.center) * Matrix4x4.Scale(node.Box.size); | ||
|
||
|
||
public void RenderNode(BVHNode<T> node) { | ||
Matrix4x4 mat = GetNodeMatrix(node); | ||
List<Matrix4x4> matrices = new List<Matrix4x4>(); | ||
matrices.Add(mat); | ||
Mesh mesh = new Mesh(); | ||
mesh.SetVertices(vertices); | ||
mesh.SetIndices(indices, MeshTopology.Lines, 0); | ||
if(_debugRenderMaterial == null) | ||
{ | ||
_debugRenderMaterial = new Material(Shader.Find("Standard")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this compatible with SRP? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will test this to make sure it is and will come back to you :) |
||
{ | ||
enableInstancing = true | ||
}; | ||
} | ||
Graphics.DrawMeshInstanced(mesh, 0, _debugRenderMaterial, matrices); | ||
} | ||
|
||
public void RenderDebug() | ||
{ | ||
if (!SystemInfo.supportsInstancing) | ||
|
@@ -225,6 +279,12 @@ public void RenderDebug() | |
enableInstancing = true | ||
}; | ||
} | ||
|
||
int iterations = (int)Mathf.Floor((float)matricies.Count / 1023.0f); | ||
for (int i = 0; i < iterations; i++) { | ||
Graphics.DrawMeshInstanced(mesh, 0, _debugRenderMaterial, matricies.GetRange(0, 1023)); | ||
matricies.RemoveRange(0, 1023); | ||
} | ||
Graphics.DrawMeshInstanced(mesh, 0, _debugRenderMaterial, matricies); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this not be removed after adding the split draw or are both calls necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both calls would be necessary as the for-loop should only execute when the limit is exceeded, which often occurs when each triangle in a scene has its own AABB. |
||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# Unity Bounding Volume Heirachy | ||
# Unity Bounding Volume Hierachy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😄 Whoops |
||
|
||
![BVH GIF](https://media.giphy.com/media/ZaomLtyboZSp9zl6WY/giphy.gif) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please double check the curly braces are following the same convention across the project
As far as I know they should be on a newline