/// <summary> /// constructor clears everything /// </summary> /// <param name="aabb"></param> public Cell(AABox aabb) { mAABox = aabb; mTriangleIndices = new List <int>(); mChildCellIndices = new int[NumChildren]; Clear(); }
public void Clear(bool NOTUSED) { positions = null; triBoxes = null; tris = null; nodes = null; boundingBox = null; }
public static bool OverlapTest(AABox box0, AABox box1) { return(((box0.minPos.Z >= box1.maxPos.Z) || (box0.maxPos.Z <= box1.minPos.Z) || (box0.minPos.Y >= box1.maxPos.Y) || (box0.maxPos.Y <= box1.minPos.Y) || (box0.minPos.X >= box1.maxPos.X) || (box0.maxPos.X <= box1.minPos.X)) ? false : true); }
public static bool OverlapTest(AABox box0, AABox box1, float tol) { return(((box0.minPos.Z >= box1.maxPos.Z + tol) || (box0.maxPos.Z <= box1.minPos.Z - tol) || (box0.minPos.Y >= box1.maxPos.Y + tol) || (box0.maxPos.Y <= box1.minPos.Y - tol) || (box0.minPos.X >= box1.maxPos.X + tol) || (box0.maxPos.X <= box1.minPos.X - tol)) ? false : true); }
// Missing: SweptSpherePlaneOverlap #region SegmentAABoxOverlap /// <summary> /// Indicates if a segment overlaps an AABox /// </summary> /// <param name="seg"></param> /// <param name="AABox"></param> /// <returns>bool</returns> public static bool SegmentAABoxOverlap(Segment seg, AABox AABox) { Vector3 p0 = seg.Origin; Vector3 p1 = seg.GetEnd(); float[] faceOffsets = new float[2]; // The AABox faces are aligned with the world directions. Loop // over the 3 directions and do the two tests. for (int iDir = 0; iDir < 3; iDir++) { int jDir = (iDir + 1) % 3; int kDir = (iDir + 2) % 3; // one plane goes through the origin, one is offset faceOffsets[0] = JiggleUnsafe.Get(AABox.MinPos, iDir); faceOffsets[1] = JiggleUnsafe.Get(AABox.MaxPos, iDir); for (int iFace = 0; iFace < 2; iFace++) { // distance of each point from to the face plane float dist0 = JiggleUnsafe.Get(ref p0, iDir) - faceOffsets[iFace]; float dist1 = JiggleUnsafe.Get(ref p1, iDir) - faceOffsets[iFace]; float frac = -1.0f; if (dist0 * dist1 < -JiggleMath.Epsilon) { frac = -dist0 / (dist1 - dist0); } else if (System.Math.Abs(dist0) < JiggleMath.Epsilon) { frac = 0.0f; } else if (System.Math.Abs(dist1) < JiggleMath.Epsilon) { frac = 1.0f; } if (frac >= 0.0f) { //Assert(frac <= 1.0f); Vector3 pt = seg.GetPoint(frac); // check the point is within the face rectangle if ((JiggleUnsafe.Get(ref pt, jDir) > JiggleUnsafe.Get(AABox.MinPos, jDir) - JiggleMath.Epsilon) && (JiggleUnsafe.Get(ref pt, jDir) < JiggleUnsafe.Get(AABox.MaxPos, jDir) + JiggleMath.Epsilon) && (JiggleUnsafe.Get(ref pt, kDir) > JiggleUnsafe.Get(AABox.MinPos, kDir) - JiggleMath.Epsilon) && (JiggleUnsafe.Get(ref pt, kDir) < JiggleUnsafe.Get(AABox.MaxPos, kDir) + JiggleMath.Epsilon)) { return(true); } } } } return(false); }
public static bool SegmentAABoxOverlap(Segment seg, AABox AABox) { var p0 = seg.Origin; var p1 = seg.GetEnd(); var faceOffsets = new float[2]; for (var iDir = 0; iDir < 3; iDir++) { var jDir = (iDir + 1) % 3; var kDir = (iDir + 2) % 3; faceOffsets[0] = JiggleUnsafe.Get(AABox.MinPos, iDir); faceOffsets[1] = JiggleUnsafe.Get(AABox.MaxPos, iDir); for (var iFace = 0; iFace < 2; iFace++) { var dist0 = JiggleUnsafe.Get(ref p0, iDir) - faceOffsets[iFace]; var dist1 = JiggleUnsafe.Get(ref p1, iDir) - faceOffsets[iFace]; var frac = -1.0f; if (dist0 * dist1 < -JiggleMath.Epsilon) { frac = -dist0 / (dist1 - dist0); } else if (System.Math.Abs(dist0) < JiggleMath.Epsilon) { frac = 0.0f; } else if (System.Math.Abs(dist1) < JiggleMath.Epsilon) { frac = 1.0f; } if (frac >= 0.0f) { var pt = seg.GetPoint(frac); if (JiggleUnsafe.Get(ref pt, jDir) > JiggleUnsafe.Get(AABox.MinPos, jDir) - JiggleMath.Epsilon && JiggleUnsafe.Get(ref pt, jDir) < JiggleUnsafe.Get(AABox.MaxPos, jDir) + JiggleMath.Epsilon && JiggleUnsafe.Get(ref pt, kDir) > JiggleUnsafe.Get(AABox.MinPos, kDir) - JiggleMath.Epsilon && JiggleUnsafe.Get(ref pt, kDir) < JiggleUnsafe.Get(AABox.MaxPos, kDir) + JiggleMath.Epsilon) { return(true); } } } } return(false); }
/// <summary> /// Indicates if a segment overlaps an AABox /// </summary> /// <param name="seg"></param> /// <param name="AABox"></param> /// <returns>bool</returns> public static bool SegmentAABoxOverlap(Segment seg, AABox AABox) { Vector3 p0 = seg.Origin; Vector3 p1 = seg.GetEnd(); float[] faceOffsets = new float[2]; // The AABox faces are aligned with the world directions. Loop // over the 3 directions and do the two tests. for (int iDir = 0; iDir < 3; iDir++) { int jDir = (iDir + 1) % 3; int kDir = (iDir + 2) % 3; // one plane goes through the origin, one is offset faceOffsets[0] = JiggleUnsafe.Get(AABox.MinPos, iDir); faceOffsets[1] = JiggleUnsafe.Get(AABox.MaxPos, iDir); for (int iFace = 0; iFace < 2; iFace++) { // distance of each point from to the face plane float dist0 = JiggleUnsafe.Get(ref p0, iDir) - faceOffsets[iFace]; float dist1 = JiggleUnsafe.Get(ref p1, iDir) - faceOffsets[iFace]; float frac = -1.0f; if (dist0 * dist1 < -JiggleMath.Epsilon) frac = -dist0 / (dist1 - dist0); else if (System.Math.Abs(dist0) < JiggleMath.Epsilon) frac = 0.0f; else if (System.Math.Abs(dist1) < JiggleMath.Epsilon) frac = 1.0f; if (frac >= 0.0f) { //Assert(frac <= 1.0f); Vector3 pt = seg.GetPoint(frac); // check the point is within the face rectangle if ((JiggleUnsafe.Get(ref pt, jDir) > JiggleUnsafe.Get(AABox.MinPos, jDir) - JiggleMath.Epsilon) && (JiggleUnsafe.Get(ref pt, jDir) < JiggleUnsafe.Get(AABox.MaxPos, jDir) + JiggleMath.Epsilon) && (JiggleUnsafe.Get(ref pt, kDir) > JiggleUnsafe.Get(AABox.MinPos, kDir) - JiggleMath.Epsilon) && (JiggleUnsafe.Get(ref pt, kDir) < JiggleUnsafe.Get(AABox.MaxPos, kDir) + JiggleMath.Epsilon)) { return true; } } } } return false; }
public override void GetBoundingBox(out AABox box) { box = octree.BoundingBox.Clone() as AABox; box.Transform = Transform; }
public void BuildOctree( int _maxTrisPerCellNOTUSED, float _minCellSizeNOTUSED) { // create tri and tri bounding box arrays triBoxes = new BoundingBox[tris.Length]; // create an infinite size root box rootNodeBox = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity), new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity)); for (int i = 0; i < tris.Length; i++) { triBoxes[i].Min = Vector3.Min(positions[tris[i].I0], Vector3.Min(positions[tris[i].I1], positions[tris[i].I2])); triBoxes[i].Max = Vector3.Max(positions[tris[i].I0], Vector3.Max(positions[tris[i].I1], positions[tris[i].I2])); // get size of the root box rootNodeBox.Min = Vector3.Min(rootNodeBox.Min, triBoxes[i].Min); rootNodeBox.Max = Vector3.Max(rootNodeBox.Max, triBoxes[i].Max); } boundingBox = new AABox(rootNodeBox.Min, rootNodeBox.Max); List<BuildNode> buildNodes = new List<BuildNode>(); buildNodes.Add(new BuildNode()); buildNodes[0].box = rootNodeBox; BoundingBox[] children = new BoundingBox[8]; for (int triNum = 0; triNum < tris.Length; triNum++) { int nodeIndex = 0; BoundingBox box = rootNodeBox; while (box.Contains(triBoxes[triNum]) == ContainmentType.Contains) { int childCon = -1; for (int i = 0; i < 8; ++i) { children[i] = CreateAABox(box, (EChild)i); if (children[i].Contains(triBoxes[triNum]) == ContainmentType.Contains) { // this box contains the tri, it can be the only one that does, // so we can stop our child search now and recurse into it childCon = i; break; } } // no child contains this tri completely, so it belong in this node if (childCon == -1) { buildNodes[nodeIndex].triIndices.Add(triNum); break; } else { // do we already have this child int childIndex = -1; for (int index = 0; index < buildNodes[nodeIndex].nodeIndices.Count; ++index) { if (buildNodes[buildNodes[nodeIndex].nodeIndices[index]].childType == childCon) { childIndex = index; break; } } if (childIndex == -1) { // nope create child BuildNode parentNode = buildNodes[nodeIndex]; BuildNode newNode = new BuildNode(); newNode.childType = childCon; newNode.box = children[childCon]; buildNodes.Add(newNode); nodeIndex = buildNodes.Count - 1; box = children[childCon]; parentNode.nodeIndices.Add(nodeIndex); } else { nodeIndex = buildNodes[nodeIndex].nodeIndices[childIndex]; box = children[childCon]; } } } } Debug.Assert(buildNodes.Count < 0xFFFF); // now convert to the tighter Node from BuildNodes nodes = new Node[buildNodes.Count]; nodeStack = new UInt16[buildNodes.Count]; for (int i = 0; i < nodes.Length; i++) { nodes[i].nodeIndices = new UInt16[buildNodes[i].nodeIndices.Count]; for (int index = 0; index < nodes[i].nodeIndices.Length; ++index) { nodes[i].nodeIndices[index] = (UInt16)buildNodes[i].nodeIndices[index]; } nodes[i].triIndices = new int[buildNodes[i].triIndices.Count]; buildNodes[i].triIndices.CopyTo(nodes[i].triIndices); nodes[i].box = buildNodes[i].box; } buildNodes = null; }
/// <summary> /// constructor clears everything /// </summary> /// <param name="aabb"></param> public Cell(AABox aabb) { mAABox = aabb; mTriangleIndices = new List<int>(); mChildCellIndices = new int[NumChildren]; Clear(); }
public void Clear( bool NOTUSED ) { positions = null; triBoxes = null; tris = null; nodes = null; boundingBox = null; }
/// <summary> /// Initializes a new CollisionSystem which uses a grid to speed up collision detection. /// Use this system for larger scenes with many objects. /// </summary> /// <param name="nx">Number of GridEntries in X Direction.</param> /// <param name="ny">Number of GridEntries in Y Direction.</param> /// <param name="nz">Number of GridEntries in Z Direction.</param> /// <param name="dx">Size of a single GridEntry in X Direction.</param> /// <param name="dy">Size of a single GridEntry in Y Direction.</param> /// <param name="dz">Size of a single GridEntry in Z Direction.</param> public CollisionSystemGrid(int nx, int ny, int nz, float dx, float dy, float dz) { this.nx = nx; this.ny = ny; this.nz = nz; this.dx = dx; this.dy = dy; this.dz = dz; this.sizeX = nx * dx; this.sizeY = ny * dy; this.sizeZ = nz * dz; this.minDelta = System.Math.Min(System.Math.Min(dx, dy), dz); int numEntries = nx * ny * nz * 2; // we allocate twice as many as need for collision skins gridEntries = new List<GridEntry>(numEntries); gridBoxes = new List<AABox>(numEntries); tempGridLists = new List<GridEntry>(numEntries); freeGrids = new Stack<GridEntry>(numEntries); for (int i = 0; i < numEntries; ++i) { GridEntry entry = new GridEntry(); entry.GridIndex = -2; freeGrids.Push(entry); } for (int i = 0; i < (nx * ny * nz); ++i) { GridEntry gridEntry = freeGrids.Pop(); gridEntry.GridIndex = i; gridEntries.Add(gridEntry); gridBoxes.Add(null); } overflowEntries = freeGrids.Pop(); overflowEntries.GridIndex = -1; for (int iX = 0; iX < nx; ++iX) { for (int iY = 0; iY < ny; ++iY) { for (int iZ = 0; iZ < nz; ++iZ) { AABox box = new AABox(); box.AddPoint(new Vector3(iX * dx, iY * dy, iZ + dz)); box.AddPoint(new Vector3(iX * dx + dx, iY * dy + dy, iZ * dz + dz)); int index = CalcIndex(iX, iY, iZ); gridBoxes[index] = box; } } } }
/// <summary> /// GetBoundingBox /// </summary> /// <param name="box"></param> public override void GetBoundingBox(out AABox box) { box = octree.BoundingBox.Clone() as AABox; box.Transform = Transform; }
/// <summary> /// OverlapTest /// </summary> /// <param name="box0"></param> /// <param name="box1"></param> /// <returns>bool</returns> public static bool OverlapTest(AABox box0, AABox box1) { return ((box0.minPos.Z >= box1.maxPos.Z) || (box0.maxPos.Z <= box1.minPos.Z) || (box0.minPos.Y >= box1.maxPos.Y) || (box0.maxPos.Y <= box1.minPos.Y) || (box0.minPos.X >= box1.maxPos.X) || (box0.maxPos.X <= box1.minPos.X)) ? false : true; }
/// <summary> /// Returns a bounding box that covers this primitive. Default returns a huge box, so /// implement this in the derived class for efficiency /// </summary> public virtual void GetBoundingBox(out AABox box) { box = AABox.HugeBox; }
/// <summary> /// GetBoundingBox /// </summary> /// <param name="box"></param> public override void GetBoundingBox(out AABox box) { box = new AABox(this.Min, this.Max); }
public override void GetBoundingBox(out AABox box) { if (octree == null) { BoundingBox bounds = kdTree.GetRoot().boundingBox; box = new AABox(bounds.Min, bounds.Max); box.Transform = Transform; } else { box = octree.BoundingBox.GetBoundingBox(); } }
/// <summary> /// AddAABox /// </summary> /// <param name="aabox"></param> /// <param name="bb"></param> public static void AddAABox(AABox aabox, ref BoundingBox bb) { bb.Min = Vector3Extensions.Min(aabox.MinPos, bb.Min); bb.Max = Vector3Extensions.Max(aabox.MaxPos, bb.Max); }
/// <summary> /// OverlapTest /// </summary> /// <param name="box0"></param> /// <param name="box1"></param> /// <param name="tol"></param> /// <returns>bool</returns> public static bool OverlapTest(AABox box0, AABox box1, float tol) { return ((box0.minPos.Z >= box1.maxPos.Z + tol) || (box0.maxPos.Z <= box1.minPos.Z - tol) || (box0.minPos.Y >= box1.maxPos.Y + tol) || (box0.maxPos.Y <= box1.minPos.Y - tol) || (box0.minPos.X >= box1.maxPos.X + tol) || (box0.maxPos.X <= box1.minPos.X - tol)) ? false : true; }
public void BuildOctree(int _maxTrisPerCellNOTUSED, float _minCellSizeNOTUSED) { triBoxes = new BoundingBox[tris.Length]; rootNodeBox = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity), new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity)); for (var i = 0; i < tris.Length; i++) { triBoxes[i].Min = Vector3.Min(positions[tris[i].I0], Vector3.Min(positions[tris[i].I1], positions[tris[i].I2])); triBoxes[i].Max = Vector3.Max(positions[tris[i].I0], Vector3.Max(positions[tris[i].I1], positions[tris[i].I2])); rootNodeBox.Min = Vector3.Min(rootNodeBox.Min, triBoxes[i].Min); rootNodeBox.Max = Vector3.Max(rootNodeBox.Max, triBoxes[i].Max); } BoundingBox = new AABox(rootNodeBox.Min, rootNodeBox.Max); var buildNodes = new List <BuildNode>(); buildNodes.Add(new BuildNode()); buildNodes[0].box = rootNodeBox; var children = new BoundingBox[8]; for (var triNum = 0; triNum < tris.Length; triNum++) { var nodeIndex = 0; var box = rootNodeBox; while (box.Contains(triBoxes[triNum]) == ContainmentType.Contains) { var childCon = -1; for (var i = 0; i < 8; ++i) { children[i] = CreateAABox(box, (EChild)i); if (children[i].Contains(triBoxes[triNum]) == ContainmentType.Contains) { childCon = i; break; } } if (childCon == -1) { buildNodes[nodeIndex].triIndices.Add(triNum); break; } else { var childIndex = -1; for (var index = 0; index < buildNodes[nodeIndex].nodeIndices.Count; ++index) { if (buildNodes[buildNodes[nodeIndex].nodeIndices[index]].childType == childCon) { childIndex = index; break; } } if (childIndex == -1) { var parentNode = buildNodes[nodeIndex]; var newNode = new BuildNode(); newNode.childType = childCon; newNode.box = children[childCon]; buildNodes.Add(newNode); nodeIndex = buildNodes.Count - 1; box = children[childCon]; parentNode.nodeIndices.Add(nodeIndex); } else { nodeIndex = buildNodes[nodeIndex].nodeIndices[childIndex]; box = children[childCon]; } } } } Debug.Assert(buildNodes.Count < 0xFFFF); nodes = new Node[buildNodes.Count]; nodeStack = new ushort[buildNodes.Count]; for (var i = 0; i < nodes.Length; i++) { nodes[i].nodeIndices = new ushort[buildNodes[i].nodeIndices.Count]; for (var index = 0; index < nodes[i].nodeIndices.Length; ++index) { nodes[i].nodeIndices[index] = (ushort)buildNodes[i].nodeIndices[index]; } nodes[i].triIndices = new int[buildNodes[i].triIndices.Count]; buildNodes[i].triIndices.CopyTo(nodes[i].triIndices); nodes[i].box = buildNodes[i].box; } buildNodes = null; }
/// <summary> /// AddAABox /// </summary> /// <param name="aabox"></param> /// <param name="bb"></param> static public void AddAABox(AABox aabox, ref BoundingBox bb) { bb.Min = Vector3Extensions.Min(aabox.MinPos, bb.Min); bb.Max = Vector3Extensions.Max(aabox.MaxPos, bb.Max); }
/// <summary> /// BuildOctree /// </summary> /// <param name="_maxTrisPerCellNOTUSED"></param> /// <param name="_minCellSizeNOTUSED"></param> public void BuildOctree(int _maxTrisPerCellNOTUSED, float _minCellSizeNOTUSED) { // create tri and tri bounding box arrays triBoxes = new BoundingBox[tris.Length]; // create an infinite size root box rootNodeBox = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity), new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity)); for (int i = 0; i < tris.Length; i++) { triBoxes[i].Min = Vector3.Min(positions[tris[i].I0], Vector3.Min(positions[tris[i].I1], positions[tris[i].I2])); triBoxes[i].Max = Vector3.Max(positions[tris[i].I0], Vector3.Max(positions[tris[i].I1], positions[tris[i].I2])); // get size of the root box rootNodeBox.Min = Vector3.Min(rootNodeBox.Min, triBoxes[i].Min); rootNodeBox.Max = Vector3.Max(rootNodeBox.Max, triBoxes[i].Max); } boundingBox = new AABox(rootNodeBox.Min, rootNodeBox.Max); List <BuildNode> buildNodes = new List <BuildNode>(); buildNodes.Add(new BuildNode()); buildNodes[0].box = rootNodeBox; BoundingBox[] children = new BoundingBox[8]; for (int triNum = 0; triNum < tris.Length; triNum++) { int nodeIndex = 0; BoundingBox box = rootNodeBox; while (box.Contains(triBoxes[triNum]) == ContainmentType.Contains) { int childCon = -1; for (int i = 0; i < 8; ++i) { children[i] = CreateAABox(box, (EChild)i); if (children[i].Contains(triBoxes[triNum]) == ContainmentType.Contains) { // this box contains the tri, it can be the only one that does, // so we can stop our child search now and recurse into it childCon = i; break; } } // no child contains this tri completely, so it belong in this node if (childCon == -1) { buildNodes[nodeIndex].triIndices.Add(triNum); break; } else { // do we already have this child int childIndex = -1; for (int index = 0; index < buildNodes[nodeIndex].nodeIndices.Count; ++index) { if (buildNodes[buildNodes[nodeIndex].nodeIndices[index]].childType == childCon) { childIndex = index; break; } } if (childIndex == -1) { // nope create child BuildNode parentNode = buildNodes[nodeIndex]; BuildNode newNode = new BuildNode(); newNode.childType = childCon; newNode.box = children[childCon]; buildNodes.Add(newNode); nodeIndex = buildNodes.Count - 1; box = children[childCon]; parentNode.nodeIndices.Add(nodeIndex); } else { nodeIndex = buildNodes[nodeIndex].nodeIndices[childIndex]; box = children[childCon]; } } } } Debug.Assert(buildNodes.Count < 0xFFFF); // now convert to the tighter Node from BuildNodes nodes = new Node[buildNodes.Count]; nodeStack = new UInt16[buildNodes.Count]; for (int i = 0; i < nodes.Length; i++) { nodes[i].nodeIndices = new UInt16[buildNodes[i].nodeIndices.Count]; for (int index = 0; index < nodes[i].nodeIndices.Length; ++index) { nodes[i].nodeIndices[index] = (UInt16)buildNodes[i].nodeIndices[index]; } nodes[i].triIndices = new int[buildNodes[i].triIndices.Count]; buildNodes[i].triIndices.CopyTo(nodes[i].triIndices); nodes[i].box = buildNodes[i].box; } buildNodes = null; }
static public void AddAABox(AABox aabox, ref BoundingBox bb) { AddPoint(aabox.MaxPos, ref bb); AddPoint(aabox.MinPos, ref bb); }
public static void AddAABox(AABox aabox, ref BoundingBox bb) { AddPoint(aabox.MaxPos, ref bb); AddPoint(aabox.MinPos, ref bb); }