private Tuple<Point3D, Vector3D>[] GetVisualizationOfHull_Plate(AxisForDouble axis1, AxisForDouble axis2, AxisForDouble axis3, Vector3D rayDirection) { //WARNING: Make sure rayDirection is long enough to pass through the entire hullD List<Tuple<Point3D, Vector3D>> retVal = new List<Tuple<Point3D, Vector3D>>(); double percent; Point3D? contactPoint; Vector3D? contactNormal; int faceID; foreach (Point3D point in AxisForDouble.Iterate(axis1, axis2, axis3)) { if (RayCast(out percent, out contactPoint, out contactNormal, out faceID, point, point + rayDirection)) { retVal.Add(Tuple.Create(contactPoint.Value, contactNormal.Value)); } } return retVal.ToArray(); }
/// <summary> /// This iterates over three axiis as points /// WARNING: It's up to the caller to make sure each of the three axiis is unique (one for X, one for Y, one for Z) /// </summary> public static IEnumerable<Point3D> Iterate(AxisForDouble axis1, AxisForDouble axis2, AxisForDouble axis3) { foreach (double v1 in axis1.Iterate()) { foreach (double v2 in axis2.Iterate()) { foreach (double v3 in axis3.Iterate()) { double x = 0, y = 0, z = 0; axis1.SetCorrespondingValue(ref x, ref y, ref z, v1); axis2.SetCorrespondingValue(ref x, ref y, ref z, v2); axis3.SetCorrespondingValue(ref x, ref y, ref z, v3); yield return new Point3D(x, y, z); } } } }
/// <summary> /// This is a helper method to visualize the collision hull. It fires rays toward the hull, and returns where those rays hit /// </summary> /// <returns> /// Item1=Position /// Item2=Normal /// </returns> public Tuple<Point3D, Vector3D>[] GetVisualizationOfHull(int steps = 10) { Point3D aabbMin, aabbMax; CalculateAproximateAABB(out aabbMin, out aabbMax); List<Tuple<Point3D, Vector3D>> retVal = new List<Tuple<Point3D, Vector3D>>(); //TODO: Adjust the steps to get a square dpi int xSteps = steps; int ySteps = steps; int zSteps = steps; // XY AxisForDouble axis1 = new AxisForDouble(Axis.X, aabbMin.X, aabbMax.X, xSteps); AxisForDouble axis2 = new AxisForDouble(Axis.Y, aabbMin.Y, aabbMax.Y, ySteps); Vector3D direction = new Vector3D(0, 0, aabbMax.Z - aabbMin.Z); retVal.AddRange(GetVisualizationOfHull_Plate(axis1, axis2, new AxisForDouble(Axis.Z, aabbMin.Z), direction)); retVal.AddRange(GetVisualizationOfHull_Plate(axis1, axis2, new AxisForDouble(Axis.Z, aabbMax.Z), -direction)); // XZ axis1 = new AxisForDouble(Axis.X, aabbMin.X, aabbMax.X, xSteps); axis2 = new AxisForDouble(Axis.Z, aabbMin.Z, aabbMax.Z, zSteps); direction = new Vector3D(0, aabbMax.Y - aabbMin.Y, 0); retVal.AddRange(GetVisualizationOfHull_Plate(axis1, axis2, new AxisForDouble(Axis.Y, aabbMin.Y), direction)); retVal.AddRange(GetVisualizationOfHull_Plate(axis1, axis2, new AxisForDouble(Axis.Y, aabbMax.Y), -direction)); // YZ axis1 = new AxisForDouble(Axis.Y, aabbMin.Y, aabbMax.Y, ySteps); axis2 = new AxisForDouble(Axis.Z, aabbMin.Z, aabbMax.Z, zSteps); direction = new Vector3D(aabbMax.X - aabbMin.X, 0, 0); retVal.AddRange(GetVisualizationOfHull_Plate(axis1, axis2, new AxisForDouble(Axis.X, aabbMin.X), direction)); retVal.AddRange(GetVisualizationOfHull_Plate(axis1, axis2, new AxisForDouble(Axis.X, aabbMax.X), -direction)); return retVal.ToArray(); }
/// <summary> /// This iterates over two axiis as points /// WARNING: It's up to the caller to make sure each of the two axiis is unique (one for X, one for Y, nothing for Z) /// </summary> public static IEnumerable<Point> Iterate(AxisForDouble axis1, AxisForDouble axis2) { if (axis1.Axis == Axis.Z || axis2.Axis == Axis.Z) { throw new ArgumentException("Z should never be passed into this 2D method"); } foreach (double v1 in axis1.Iterate()) { foreach (double v2 in axis2.Iterate()) { double x = 0, y = 0, dummy = 0; axis1.SetCorrespondingValue(ref x, ref y, ref dummy, v1); axis2.SetCorrespondingValue(ref x, ref y, ref dummy, v2); yield return new Point(x, y); } } }