1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
|
using System;
using OpenTK;
namespace Examples.Shapes
{
/// <summary>winding always assumed CCW (Counter-ClockWise)</summary>
internal struct TetrahedronFace
{
private Vector3d APosition, BPosition, CPosition;
private Vector3d DPosition, Normal;
private Vector2d ATexCoord, BTexCoord, CTexCoord;
public TetrahedronFace( ref Vector3d apos, ref Vector2d atc,
ref Vector3d bpos, ref Vector2d btc,
ref Vector3d cpos, ref Vector2d ctc,
ref Vector3d dpos,
ref Vector3d normal )
{
APosition = apos; ATexCoord = atc;
BPosition = bpos; BTexCoord = btc;
CPosition = cpos; CTexCoord = ctc;
DPosition = dpos;
Normal = normal;
}
/// <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 );
}
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
}
/// <summary>Returns 3 Vertices which form a CCW triangle.</summary>
public void GetVertices( out VertexT2dN3dV3d first, out VertexT2dN3dV3d second, out VertexT2dN3dV3d third )
{
first.TexCoord = this.ATexCoord;
first.Normal = this.Normal;
first.Position = this.APosition;
second.TexCoord = this.BTexCoord;
second.Normal = this.Normal;
second.Position = this.BPosition;
third.TexCoord = this.CTexCoord;
third.Normal = this.Normal;
third.Position = this.CPosition;
}
/// <summary>Debugging Aid, no real purpose</summary>
public override string ToString()
{
return "A= " + this.APosition.ToString() + " TexCoord: " + this.ATexCoord.ToString() + "\n" +
"B= " + this.BPosition.ToString() + " TexCoord: " + this.ATexCoord.ToString() + "\n" +
"C= " + this.CPosition.ToString() + " TexCoord: " + this.ATexCoord.ToString() + "\n" +
"Normal= " + this.Normal.ToString();
}
}
}
|