private int FindLevelByPosition(Bounds3 bounds) { var furthestMax = Functions.MaximumComponent(Functions.Abs(bounds.Maximum)); var furthestMin = Functions.MaximumComponent(Functions.Abs(bounds.Minimum)); return((int)Math.Ceiling(Functions.Log2(Math.Max(furthestMax, furthestMin)))); }
/// <summary> /// Adds an item with the given bounds into the octree. /// </summary> /// <param name="bounds">The bounds of the item.</param> /// <param name="value">The item to add.</param> /// <returns></returns> public BoundsOctreeItem <T> Add(Bounds3 bounds, T value) { var item = new BoundsOctreeItem <T>(bounds, value); if (children == null) { CreateInitialOctree(item); return(item); } if (Level < item.Level) { Expand(item); } var octant = GetOctant(bounds.Center); if (children[octant] == null) { children[octant] = new BoundingOctreeNode <T>(Level, GetOriginIndex3(octant)); } children[octant].Add(item); return(item); }
public void InitInterior(int axis, BVHBuildNode c0, BVHBuildNode c1) { children[0] = c0; children[1] = c1; bounds = c0.bounds.Union(c1.bounds); splitAxis = axis; }
public BoundsOctreeItem(Bounds3 bounds, T value) { Bounds = bounds; Value = value; Level = Math.Max(FindLevelBySize(bounds), FindLevelByPosition(bounds)); Node = null; }
public Box3(Bounds3 bounds) { var origin = bounds.Minimum + (bounds.Maximum - bounds.Minimum) / 2; Extents = bounds.Maximum - origin; Transform = Matrix4.Translation(origin); }
public void TestIntersectsNegative() { var bounds = new Bounds3(Vector3.Zero, Vector3.One); var segment = new Segment3(new Vector3(0, 0, 2.1f), new Vector3(2.1f, 2.1f, 0)); Assert.That(bounds.Intersects(segment) == false); }
public void TestIntersectsPositive() { var bounds = new Bounds3(Vector3.Zero, Vector3.One); var segment = new Segment3(new Vector3(0, 0, 1.9f), new Vector3(1.9f, 1.9f, 0)); Assert.That(bounds.Intersects(segment) == true); }
public List <T> GetContaining(Bounds3 bounds) { var list = new List <T>(); Root.AppendContaining(list, bounds); return(list); }
public Bounds3 Union(Bounds3 other) { Bounds3 newBounds = new Bounds3(); newBounds.pMax = Vector3.Max(pMax, other.pMax); newBounds.pMin = Vector3.Min(pMin, other.pMin); return(newBounds); }
public void InitInterior(int axis, BVHBuildNode child1, BVHBuildNode child2) { Children[0] = child1; Children[1] = child2; PrimitiveCount = 0; Bounds = child1.Bounds.Union(child2.Bounds); SplitAxis = axis; }
/// <summary> /// Creates the bounding box for the specified octant. /// </summary> /// <param name="bounds"></param> /// <param name="octant"></param> /// <returns></returns> private static Bounds3 GetChildBounds(Bounds3 bounds, Boolean3 octant) { Vector3 center = bounds.Center; Vector3 half = bounds.Size / 2; Vector3 corner = center + (half * octant.ToVector3()); return(Bounds3.FromVectors(center, corner)); }
public BoundingSphere GetBoundingSphere() { if (_boundingSphere.Radius == 0) { Bounds3 bounds = Vehicle.Chassis.Actor.Shapes[0].WorldSpaceBounds; _boundingSphere = new BoundingSphere(Vector3.Zero, bounds.Size.Length()); } _boundingSphere.Center = Vehicle.Position; return(_boundingSphere); }
public Bounds3 Union(Vector3 vec) { Bounds3 newBounds = new Bounds3(); newBounds.pMin.x = Mathf.Min(pMin.x, vec.x); newBounds.pMin.y = Mathf.Min(pMin.y, vec.y); newBounds.pMin.z = Mathf.Min(pMin.z, vec.z); newBounds.pMax.x = Mathf.Max(pMax.x, vec.x); newBounds.pMax.y = Mathf.Max(pMax.y, vec.y); newBounds.pMax.z = Mathf.Max(pMax.z, vec.z); return(newBounds); }
public TrigleFace(Vector3f pointa, Vector3f pointb, Vector3f pointc) { v0 = pointa; v1 = pointb; v2 = pointc; e1 = v1 - v0; e2 = v2 - v0; BoundBox = new Bounds3(v0, v1, v2); CenterPoint = (v0 + v1 + v2) / 3.0f; }
public BoundingOctreeNode(int level, Index3 index) { Level = level; Index = index; var side = Functions.Pow(2, level); var minimum = (Vector3)index * side; var maximum = minimum + new Vector3(side); Bounds = new Bounds3(minimum, maximum); Center = Bounds.Center; Expansion = Bounds3.Expand(Bounds, 2, Center); }
// List of BVHPrimitive infos including each triangle of the object // Start/end/total nodes for recursive split of the list private BVHBuildNode BuildRecursiveBVH(ref List <BVHPrimitiveInfo> primitiveInfos, int start, int end, ref int totalNodes) { BVHBuildNode node = new BVHBuildNode(); totalNodes++; Bounds3 bounds = new Bounds3(); bounds.pMin = Vector3.positiveInfinity; bounds.pMax = Vector3.negativeInfinity; // Calculate bounds of the parent BVH node from its children for (int i = start; i < end; i++) { bounds = bounds.Union(primitiveInfos[i].bounds); } int nPrimitives = end - start; // Create leaf if (nPrimitives == 1) { node.InitLeaf(primitiveInfos[start].triangleNo, bounds); return(node); } else { Bounds3 centroidBounds = new Bounds3(); centroidBounds.pMin = Vector3.positiveInfinity; centroidBounds.pMax = Vector3.negativeInfinity; for (int i = start; i < end; i++) { centroidBounds = centroidBounds.Union(primitiveInfos[i].center); } int dim = centroidBounds.MaximumExtend(); int mid = (start + end) / 2; // Order Primitives in axis 'dim' and split the list into 2 equal sized lists EqualCounts(ref primitiveInfos, dim, start, end); node.InitInterior(dim, BuildRecursiveBVH(ref primitiveInfos, start, mid, ref totalNodes), BuildRecursiveBVH(ref primitiveInfos, mid, end, ref totalNodes) ); return(node); } }
private void CreateInitialOctree(BoundsOctreeItem <T> item) { Level = item.Level; var side = Functions.Pow(2, Level); Bounds = new Bounds3(-side, -side, -side, side, side, side); children = new BoundingOctreeNode <T> [8]; var octant = GetOctant(item.Bounds.Center); children[octant] = new BoundingOctreeNode <T>(Level, GetOriginIndex3(octant)); children[octant].Add(item); }
public PrimitiveList(IEnumerable <Primitive> primitives) { Primitives = new List <Primitive>(primitives); // Cache the world space bounds if (Primitives.Any()) { worldBounds = Primitives.First().WorldBounds; foreach (var p in Primitives.Skip(1)) { worldBounds = worldBounds.Union(p.WorldBounds); } } }
public void CalculateCenter() { int count = 0; Bounds = new Bounds3(new Vector3(9999, 9999, 9999), new Vector3(-9999, -9999, -9999)); foreach (Face x in Faces) { foreach (Vector3 v in x.Vertices) { count++; Vector3 transformed = Model.TranslateVertex(Translate, Rotate, Pivot, v); Center += transformed; Bounds += transformed; } } Center /= count; }
public void SetTrigles(TrigleFace[] trigles) { this.trigles = trigles; if (trigles != null && trigles.Length > 0) { Bounds3 bounds = trigles[0].BoundBox; foreach (var item in trigles) { bounds = Bounds3.Union(bounds, item.BoundBox); //item.material = _material; } this.BoundBox = bounds; } else { this.BoundBox = new Bounds3(); } CenterPoint = (BoundBox.pMin + BoundBox.pMax) * 0.5f; BVH = BVH.Build(trigles.AsSpan()); }
public void AppendContaining(IList <T> list, Bounds3 bounds) { // append all items within the bounds foreach (var item in Items) { if (bounds.Contains(item.Position)) { list.Add(item); } } // recurse for all children that intersects the bounds. if (!IsLeaf) { foreach (var child in children) { if (child.Bounds.Intersects(bounds)) { child.AppendContaining(list, bounds); } } } }
static void Main(string[] args) { for (int j = 0; j < 50; j++) { var octree = new BoundingOctree <object>(); for (int i = 0; i < 1000; i++) { var bounds = Bounds3.FromVectors(Functions.Random.NextVector3(-1000, 1000), Functions.Random.NextVector3(-1000, 1000)); octree.Add(bounds, i); } Logger.LogError(octree); } // Network.NetworkTimeProtocol.Test(); using (var engine = new Engine.CoreEngine()) { engine.Process = new ProgramEngine(engine); engine.Run(); } }
/// <summary> /// Determines whether the specified bounds instersects this sphere. /// </summary> /// <param name="bounds"></param> /// <returns></returns> public bool Intersects(Bounds3 bounds) { Functions.Clamp(ref Position, ref bounds.Minimum, ref bounds.Maximum, out var closest); var distance = Vector3.Distance(Position, closest); return distance < Radius; }
// Create MeshData and MeshBoundingBox of the object private void ParseSceneMesh(Transform meshObject) { MeshData newMeshData = new MeshData(); newMeshData._TriangleIndexStart = _SceneData._SizeOfTriangleList; newMeshData._VertexIndexStart = _SceneData._SizeOfVertexList; newMeshData._BVHNodeOffset = _SceneData._SizeOfBVHNodeList; Mesh mesh = meshObject.GetComponent <MeshFilter>().mesh; Vector3[] newVertexList = mesh.vertices; for (int i = 0; i < newVertexList.Length; i++) { newVertexList[i] = meshObject.rotation * newVertexList[i]; newVertexList[i] = meshObject.localScale.x * newVertexList[i]; newVertexList[i] = meshObject.position + newVertexList[i]; } _SceneData._VertexList.AddRange(newVertexList); _SceneData._SizeOfVertexList += mesh.vertexCount; List <Triangle> newMeshTriangles = new List <Triangle>(); List <BVHPrimitiveInfo> primitiveInfos = new List <BVHPrimitiveInfo>(); int iterator = 0; while (iterator < mesh.triangles.Length) { Triangle newTriangle = new Triangle(); // Set new triangles indices newTriangle.indices.x = mesh.triangles[iterator]; newTriangle.indices.y = mesh.triangles[iterator + 1]; newTriangle.indices.z = mesh.triangles[iterator + 2]; Vector3 p0 = newVertexList[(int)newTriangle.indices.x]; Vector3 p1 = newVertexList[(int)newTriangle.indices.y]; Vector3 p2 = newVertexList[(int)newTriangle.indices.z]; // Set new triangles bounds Bounds3 triBounds = new Bounds3(); triBounds.pMax = Vector3.Max(p0, p1); triBounds.pMax = Vector3.Max(triBounds.pMax, p2); triBounds.pMin = Vector3.Min(p0, p1); triBounds.pMin = Vector3.Min(triBounds.pMin, p2); BVHPrimitiveInfo newInfo = new BVHPrimitiveInfo(newMeshTriangles.Count, triBounds); primitiveInfos.Add(newInfo); iterator += 3; newMeshTriangles.Add(newTriangle); } BVHAcc BVHAccObj = new BVHAcc(ref primitiveInfos); foreach (LinearBVHNode node in BVHAccObj.LinearBVHArr) { LinearBVHNode newLinearNode = new LinearBVHNode(); newLinearNode.bounds = node.bounds; newLinearNode.primitiveOffset = node.primitiveOffset; newLinearNode.secondChildOffset = node.secondChildOffset; //Debug.Log("Primitiveoffset: " + node.primitiveOffset); //Debug.Log("SecondChildoffset: " + node.secondChildOffset); _SceneData._BVHNodeList.Add(newLinearNode); _SceneData._SizeOfBVHNodeList++; } _SceneData._TriangleList.AddRange(newMeshTriangles); _SceneData._SizeOfTriangleList = _SceneData._TriangleList.Count; newMeshData._TriangleIndexEnd = _SceneData._SizeOfTriangleList; AddMaterialData(meshObject); newMeshData._MaterialID = _SceneData._MaterialCount - 1; _SceneData._MeshDataList.Add(newMeshData); _SceneData._MeshCount++; //Debug.Log("Mesh Count: " + _SceneData._MeshCount); //Debug.Log("BVHNode Count: " + _SceneData._SizeOfBVHNodeList); //Debug.Log("BVHNode offset: " + _SceneData._MeshDataList[0]._BVHNodeOffset); }
/// <summary> /// /// </summary> public Octant(Octant <T> parent, Bounds3 bounds) { Bounds = bounds; Influence = Bounds3.FromCenter(bounds.Center, bounds.Size * 3); }
public Octree(Vector3 center, float side) { Bounds = Bounds3.FromCenter(center, new Vector3(side)); Root = new Octant <T>(null, Bounds); }
public BVHPrimitiveInfo(int triNo, Bounds3 bound) { triangleNo = triNo; bounds = bound; center = 0.5f * bounds.pMax + 0.5f * bounds.pMin; }
protected override INotifyExpression <T[, , ]> ApplyParametersCore(IDictionary <string, object> parameters, IDictionary <INotifiable, INotifiable> trace) { return(new ObservableNewArray3Expression <T>(Bounds1.ApplyParameters(parameters, trace), Bounds2.ApplyParameters(parameters, trace), Bounds3.ApplyParameters(parameters, trace))); }
public Viewport(float x, float y, float width, float height, float minZ = 0, float maxZ = 1) { Bounds = new Bounds3(x, y, minZ, x + width, y + height, maxZ); }
public override INotifyExpression <T[, , ]> ApplyParameters(IDictionary <string, object> parameters) { return(new ObservableNewArray3Expression <T>(Bounds1.ApplyParameters(parameters), Bounds2.ApplyParameters(parameters), Bounds3.ApplyParameters(parameters))); }