/// <summary>Expects CCW triangle order as input, emits 4 new CCW triangles.</summary> /// <param name="first">1st output Triangle</param> /// <param name="second">2nd output Triangle</param> /// <param name="third">3rd output Triangle</param> /// <param name="fourth">4th output Triangle</param> public void SubdivideSierpinski(out TetrahedronFace first, out TetrahedronFace second, out TetrahedronFace third, out TetrahedronFace fourth) { Vector3d temp; // find the 3 points AB, BC, CA Vector3d CenterAB; Vector3d.Add(ref this.APosition, ref this.BPosition, out temp); Vector3d.Multiply(ref temp, 0.5f, out CenterAB); Vector3d CenterBC; Vector3d.Add(ref this.BPosition, ref this.CPosition, out temp); Vector3d.Multiply(ref temp, 0.5f, out CenterBC); Vector3d CenterCA; Vector3d.Add(ref this.CPosition, ref this.APosition, out temp); Vector3d.Multiply(ref temp, 0.5f, out CenterCA); // find the 3 points AD, BD, CD Vector3d CenterAD; Vector3d.Lerp(ref this.APosition, ref this.DPosition, 0.5, out CenterAD); Vector3d CenterBD; Vector3d.Lerp(ref this.BPosition, ref this.DPosition, 0.5, out CenterBD); Vector3d CenterCD; Vector3d.Lerp(ref this.CPosition, ref this.DPosition, 0.5, out CenterCD); // emit 4 new CCW triangles first = new TetrahedronFace(ref this.APosition, ref this.ATexCoord, ref CenterAB, ref this.BTexCoord, ref CenterCA, ref this.CTexCoord, ref CenterAD, ref this.Normal); second = new TetrahedronFace(ref CenterAB, ref this.ATexCoord, ref this.BPosition, ref this.BTexCoord, ref CenterBC, ref this.CTexCoord, ref CenterBD, ref this.Normal); third = new TetrahedronFace(ref CenterCA, ref this.ATexCoord, ref CenterBC, ref this.BTexCoord, ref this.CPosition, ref this.CTexCoord, ref CenterCD, ref this.Normal); fourth = new TetrahedronFace(ref CenterAD, ref this.ATexCoord, ref CenterBD, ref this.BTexCoord, ref CenterCD, ref this.CTexCoord, ref this.DPosition, ref this.Normal); }
/// <summary>Subdivides each triangle into 4 new ones.</summary> private void SubdivideTetrahedron(ref TetrahedronFace[] source, out TetrahedronFace[] output) { output = new TetrahedronFace[source.Length * 4]; int counter = 0; for (int i = 0; i < source.Length; i++) { source[i].SubdivideSierpinski(out output[counter + 0], out output[counter + 1], out output[counter + 2], out output[counter + 3]); counter += 4; // every source triangle emits 4 new triangles } }
private void SubdivideKoch(double height, ref TetrahedronFace[] input, out TetrahedronFace[] output) { output = new TetrahedronFace[input.Length * 6]; int counter = 0; for (int i = 0; i < input.Length; i++) { input[i].SubdivideKoch(height, out output[counter + 0], out output[counter + 1], out output[counter + 2], out output[counter + 3], out output[counter + 4], out output[counter + 5]); counter += 6; // every source triangle emits 6 new triangles } }
/// <summary>Generates the lowest subdivision mesh, which consists of 4 Triangles.</summary> internal static void CreateDefaultTetrahedron(double scale, out TetrahedronFace[] array) { Vector3d[] Points = new Vector3d[4]; Points[0] = new Vector3d(0.0 * scale, 0.0 * scale, 1.0 * scale); Points[1] = new Vector3d(-0.816 * scale, 0.471 * scale, -0.333 * scale); Points[2] = new Vector3d(0.816 * scale, 0.471 * scale, -0.333 * scale); Points[3] = new Vector3d(0.0 * scale, -0.943 * scale, -0.333 * scale); Vector2d[] TexCoords = new Vector2d[4]; TexCoords[0] = new Vector2d(0.0, 0.0); TexCoords[1] = new Vector2d(1.0, 0.0); TexCoords[2] = new Vector2d(0.0, 1.0); TexCoords[3] = new Vector2d(1.0, 1.0); Vector3d Normal; array = new TetrahedronFace[4]; FindNormal(ref Points[0], ref Points[2], ref Points[1], ref Points[3], out Normal); array[0] = new TetrahedronFace(ref Points[0], ref TexCoords[2], ref Points[2], ref TexCoords[0], ref Points[1], ref TexCoords[1], ref Points[3], ref Normal); FindNormal(ref Points[0], ref Points[3], ref Points[2], ref Points[1], out Normal); array[1] = new TetrahedronFace(ref Points[0], ref TexCoords[0], ref Points[3], ref TexCoords[1], ref Points[2], ref TexCoords[2], ref Points[1], ref Normal); FindNormal(ref Points[0], ref Points[1], ref Points[3], ref Points[2], out Normal); array[2] = new TetrahedronFace(ref Points[0], ref TexCoords[2], ref Points[1], ref TexCoords[1], ref Points[3], ref TexCoords[3], ref Points[2], ref Normal); FindNormal(ref Points[1], ref Points[2], ref Points[3], ref Points[0], out Normal); array[3] = new TetrahedronFace(ref Points[1], ref TexCoords[3], ref Points[2], ref TexCoords[2], ref Points[3], ref TexCoords[1], ref Points[0], ref Normal); }
internal void SubdivideKoch(double height, out TetrahedronFace first, out TetrahedronFace second, out TetrahedronFace third, out TetrahedronFace fourth, out TetrahedronFace fifth, out TetrahedronFace sixth) { Vector3d CenterAB, CenterBC, CenterCA, CenterD; Vector2d TexCoordAB, TexCoordBC, TexCoordCA, TexCoordD; Vector3d.Lerp(ref this.APosition, ref this.BPosition, 0.5, out CenterAB); Vector3d.Lerp(ref this.BPosition, ref this.CPosition, 0.5, out CenterBC); Vector3d.Lerp(ref this.CPosition, ref this.APosition, 0.5, out CenterCA); CenterD = CenterAB; Vector3d.Add(ref CenterD, ref CenterBC, out CenterD); Vector3d.Add(ref CenterD, ref CenterCA, out CenterD); CenterD /= 3.0; Vector3d E = CenterD + (this.Normal * 0.5); Vector3d temp = this.Normal; temp *= height; Vector3d.Add(ref CenterD, ref temp, out CenterD); Vector2d.Lerp(ref this.ATexCoord, ref this.BTexCoord, 0.5, out TexCoordAB); Vector2d.Lerp(ref this.BTexCoord, ref this.CTexCoord, 0.5, out TexCoordBC); Vector2d.Lerp(ref this.CTexCoord, ref this.ATexCoord, 0.5, out TexCoordCA); TexCoordD = TexCoordAB; Vector2d.Add(ref TexCoordD, ref TexCoordBC, out TexCoordD); Vector2d.Add(ref TexCoordD, ref TexCoordCA, out TexCoordD); TexCoordD /= 3.0; #region 1 first.APosition = this.APosition; first.ATexCoord = this.ATexCoord; first.BPosition = CenterAB; first.BTexCoord = TexCoordAB; first.CPosition = CenterCA; first.CTexCoord = TexCoordCA; first.Normal = this.Normal; temp = (this.APosition + CenterAB + CenterCA); temp /= 3.0; temp += this.Normal * -1.0; first.DPosition = temp; #endregion 1 #region 2 second.APosition = CenterAB; second.ATexCoord = TexCoordAB; second.BPosition = this.BPosition; second.BTexCoord = this.BTexCoord; second.CPosition = CenterBC; second.CTexCoord = TexCoordBC; second.Normal = this.Normal; temp = CenterAB + this.BPosition + CenterBC; temp /= 3.0; temp += this.Normal * -1.0; second.DPosition = temp; #endregion 2 #region 3 third.APosition = CenterBC; third.ATexCoord = TexCoordBC; third.BPosition = this.CPosition; third.BTexCoord = this.CTexCoord; third.CPosition = CenterCA; third.CTexCoord = TexCoordCA; third.Normal = this.Normal; temp = CenterBC + this.CPosition + CenterCA; temp /= 3.0; temp += this.Normal * -1.0; third.DPosition = temp; #endregion 3 #region 4 fourth.APosition = CenterAB; fourth.ATexCoord = TexCoordAB; fourth.BPosition = CenterD; fourth.BTexCoord = TexCoordD; fourth.CPosition = CenterCA; fourth.CTexCoord = TexCoordCA; SierpinskiTetrahedron.FindNormal(ref CenterAB, ref CenterD, ref CenterCA, out fourth.Normal); fourth.DPosition = E; #endregion 4 #region 5 fifth.APosition = CenterAB; fifth.ATexCoord = TexCoordAB; fifth.BPosition = CenterBC; fifth.BTexCoord = TexCoordBC; fifth.CPosition = CenterD; fifth.CTexCoord = TexCoordD; SierpinskiTetrahedron.FindNormal(ref CenterAB, ref CenterBC, ref CenterD, out fifth.Normal); fifth.DPosition = E; #endregion 5 #region 6 sixth.APosition = CenterBC; sixth.ATexCoord = TexCoordBC; sixth.BPosition = CenterCA; sixth.BTexCoord = TexCoordCA; sixth.CPosition = CenterD; sixth.CTexCoord = TexCoordD; SierpinskiTetrahedron.FindNormal(ref CenterBC, ref CenterCA, ref CenterD, out sixth.Normal); sixth.DPosition = E; #endregion 6 }