// Subdivides this PartitioningGrid, splitting it at the specified point (which ought to be insidwe this grid's AABB) public void Subdivide(Vec3 split) { this.split = split; int max_child_subd = max_subdivisions - 1; children = new PartitioningGrid[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++) { children[i, j, k] = new PartitioningGrid(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] } } }, max_child_subd); } } } }
// Subdivides this PartitioningGrid, splitting it at the specified point (which ought to be insidwe this grid's AABB) public void Subdivide(Vec3 split) { this.split = split; int max_child_subd = max_subdivisions - 1; children = new PartitioningGrid[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++) { children[i, j, k] = new PartitioningGrid(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] } } }, max_child_subd); } }
// Populates the provided PartioningGrid with items (the triangle indices of this triangle) in the specified category // The category should be either 0 or 1, as it is used as an array index and will indicate which of the two objects this triangle goes with public void PopulateGrid(PartitioningGrid grid, int category) { int num_triangles = t_v.GetLength(0); for (int i = 0; i < num_triangles; i++) grid.InsertItem(category, i, AABB.FitPointList(new List<Vec3>(new Vec3[] { verts[t_v[i, 0]], verts[t_v[i, 1]], verts[t_v[i, 2]] }))); }
// 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>()); }