// Utility function to figure out how well a subdivision point splits stuff public int[,,] CheckSubdivision(Vec3 split) { int[, ,] results = new int[2, 2, 2]; double[][] array = new double[][] { new double[] { bounds.array[0][0], split.x, bounds.array[0][1] }, new double[] { bounds.array[1][0], split.y, bounds.array[1][1] }, new double[] { bounds.array[2][0], split.z, bounds.array[2][1] } }; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { AABB subregion = new AABB { array = new double[][] { new double[] { array[0][i], array[0][i + 1] }, new double[] { array[1][j], array[1][j + 1] }, new double[] { array[2][k], array[2][k + 1] } } }; foreach (Item item in items) { if (AABB.CheckIntersection(item.aabb, subregion)) { results[i, j, k]++; } } } } } return(results); }
// Interesting constructor // Does the populating of the tree and whatnot automatically, given the objects to populate it with public ModelIntersectTree(CSGModel a, CSGModel b) { AABB a_box = a.ComputeAABB(); AABB b_box = b.ComputeAABB(); if (!AABB.CheckIntersection(a_box, b_box)) { return; } AABB intersection = AABB.Intersection(a_box, b_box); BoundsInit(intersection, 5); foreach (Octree.Item item in a.GetSourceTriangleOctreeData()) { if (item.obj is CSGSourceTriangle) { allItems[0].Add((item.obj as CSGSourceTriangle).id); InsertItem(0, item); } } foreach (Octree.Item item in b.GetSourceTriangleOctreeData()) { if (item.obj is CSGSourceTriangle) { allItems[1].Add((item.obj as CSGSourceTriangle).id); InsertItem(1, item); } } }
/// <summary> /// 求se 与三角形边的交点,se在三角形平面上,其中 s在三角形内部,e 在三角形外部,一定有交点的。 /// </summary> /// <param name="s"></param> /// <param name="e"></param> /// <returns></returns> public bool GetLineIntersectPoint(Vector3 s, Vector3 e, ref Vector3 ret) { if (AABB.CheckIntersection(this.Parent.Normal, this.P1, this.P2, s, e, ref ret) == true) { return(true); } else if (AABB.CheckIntersection(this.Parent.Normal, this.P2, this.P3, s, e, ref ret) == true) { return(true); } else if (AABB.CheckIntersection(this.Parent.Normal, this.P3, this.P1, s, e, ref ret) == true) { return(true); } return(false); }
// Inserts an item into the category-th list (possibly of children, based on the item's bounding box) public void InsertItem(int category, Octree.Item item) { if (AABB.CheckIntersection(item.aabb, bounds)) { items[category].Add(item); if (children != null) { foreach (ModelIntersectTree grid in children) { grid.InsertItem(category, item); } } if (children == null && max_subdivisions > 0) { Subdivide(); } } }
/// <summary> /// 求se 与多边形边的交点,se在多边形平面上,其中 s在多边形内部,e 在多边形外部,一定有交点的。用于切换多边形处理 /// </summary> /// <param name="s"></param> /// <param name="e"></param> /// <returns></returns> public bool GetLineIntersectPoint(Vector3 s, Vector3 e, ref Vector3 ret) { if (m_ListPt == null || m_ListPt.Count < 3) { return(false); } for (int i = 0; i < m_ListPt.Count - 1; i++) { if (AABB.CheckIntersection(this.Normal, m_ListPt[i].Pos, m_ListPt[i + 1].Pos, s, e, ref ret) == true) { return(true); } } if (AABB.CheckIntersection(this.Normal, m_ListPt[m_ListPt.Count - 1].Pos, m_ListPt[0].Pos, s, e, ref ret) == true) { return(true); } return(false); }
// Inserts an item into the category-th list (possibly of children, based on the item's bounding box) public void InsertItem(Item item) { if (AABB.CheckIntersection(item.aabb, bounds)) { items.Add(item); if (children != null) { foreach (Octree grid in children) { grid.InsertItem(item); } } else if (ConditionallySubdivide()) { Subdivide(); } } }
// Inserts an item into the category-th list (possibly of children, based on the item's bounding box) public void InsertItem(int category, int item, AABB box) { if (AABB.CheckIntersection(box, bounds)) { items[category].Add(item); if (children == null && max_subdivisions > 0) { Subdivide(); } if (children != null) { foreach (PartitioningGrid grid in children) { grid.InsertItem(category, item, box); } } } max_encountered_item[category] = Math.Max(max_encountered_item[category], item); }
// Do the CSG stuff // This is a virtual function, just in case someone thinks they can do it better public virtual void Compute() { first_blob = ModelInput.FromBasicModelData(first_in, first_xform); second_blob = ModelInput.FromBasicModelData(second_in, second_xform); /* * CSGModel derp1 = ModelUtil.ModelFromBMD(first_in, first_xform); * CSGModel derp2 = ModelUtil.ModelFromBMD(second_in, second_xform); * int count = 0; * ModelIntersectTree.CullIntersections(derp1, derp2, * (i, j) => * { * count++; * }); */ AABB aa_box = first_blob.AABB; AABB bb_box = second_blob.AABB; if (AABB.CheckIntersection(aa_box, bb_box)) // check whether their bounding boxes even intersect... if they don't, most of the math can be skipped! { AABB intersection = AABB.Intersection(aa_box, bb_box); PartitioningGrid grid = new PartitioningGrid(intersection, 5); first_blob.PopulateGrid(grid, 0); second_blob.PopulateGrid(grid, 1); List <TrianglePair> pairs = new List <TrianglePair>(); grid.ForLeafLevelPairs( (first, second) => { pairs.Add(new TrianglePair { a = first, b = second }); }); Snip(first_blob, second_blob, pairs); } else { Snip(first_blob, second_blob, new List <TrianglePair>()); } }