Opentk/Source/Examples/Shapes/SlicedHose.cs
2009-11-04 20:48:31 +00:00

194 lines
6.4 KiB
C#

using System;
using System.Collections.Generic;
using OpenTK;
namespace Examples.Shapes
{
public sealed class SlicedHose : DrawableShape
{
public enum eSide:byte
{
// Around X Axis
BottomRight,
TopRight,
TopLeft,
BottomLeft,
// Around Y Axis
FrontRight,
BackRight,
BackLeft,
FrontLeft,
// Around Z Axis
FrontBottom,
BackBottom,
BackTop,
FrontTop,
}
public SlicedHose( eSide side, uint subdivs, double scale, Vector3d offset1, Vector3d offset2, bool useDL )
: base( useDL )
{
PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.Triangles;
Vector3d start = Vector3d.Zero,
end = Vector3d.Zero;
double TexCoordStart=0f, TexCoordEnd=0f;
switch ( side )
{
#region Around X Axis
case eSide.BottomRight:
start = -Vector3d.UnitY;
end = Vector3d.UnitZ;
TexCoordStart = 0.0;
TexCoordEnd = 0.25;
break;
case eSide.TopRight:
start = Vector3d.UnitZ;
end = Vector3d.UnitY;
TexCoordStart = 0.25;
TexCoordEnd = 0.5;
break;
case eSide.TopLeft:
start = Vector3d.UnitY;
end = -Vector3d.UnitZ;
TexCoordStart = 0.5;
TexCoordEnd = 0.75;
break;
case eSide.BottomLeft:
start = -Vector3d.UnitZ;
end = -Vector3d.UnitY;
TexCoordStart = 0.75;
TexCoordEnd = 1.0;
break;
#endregion Around X Axis
#region Around Y Axis
case eSide.FrontRight:
start = Vector3d.UnitX;
end = Vector3d.UnitZ;
TexCoordStart = 0.0;
TexCoordEnd = 0.25;
break;
case eSide.BackRight:
start = Vector3d.UnitZ;
end = -Vector3d.UnitX;
TexCoordStart = 0.25;
TexCoordEnd = 0.5;
break;
case eSide.BackLeft:
start = -Vector3d.UnitX;
end = -Vector3d.UnitZ;
TexCoordStart = 0.5;
TexCoordEnd = 0.75;
break;
case eSide.FrontLeft:
start = -Vector3d.UnitZ;
end = Vector3d.UnitX;
TexCoordStart = 0.75;
TexCoordEnd = 1.0;
break;
#endregion Around Y Axis
#region Around Z Axis
case eSide.FrontBottom:
start = -Vector3d.UnitY;
end = Vector3d.UnitX;
TexCoordStart = 0.0;
TexCoordEnd = 0.25;
break;
case eSide.BackBottom:
start = -Vector3d.UnitX;
end = -Vector3d.UnitY;
TexCoordStart = 0.25;
TexCoordEnd = 0.5;
break;
case eSide.BackTop:
start = Vector3d.UnitY;
end = -Vector3d.UnitX;
TexCoordStart = 0.5;
TexCoordEnd = 0.75;
break;
case eSide.FrontTop:
start = Vector3d.UnitX;
end = Vector3d.UnitY;
TexCoordStart = 0.75;
TexCoordEnd = 1.0;
break;
#endregion Around Z Axis
}
VertexT2dN3dV3d[] temp = new VertexT2dN3dV3d[2 + subdivs];
double divisor = 1.0/ ((double)temp.Length-1.0);
for ( int i = 0; i < temp.Length; i++ )
{
float Multiplier = (float)( i * divisor );
temp[i].TexCoord.X = TexCoordStart * Multiplier + TexCoordEnd * ( 1.0f- Multiplier);
Slerp( ref start, ref end, Multiplier, out temp[i].Normal );
temp[i].Normal.Normalize();
temp[i].Position = temp[i].Normal;
temp[i].Position *= scale;
}
VertexArray = new VertexT2dN3dV3d[temp.Length * 2];
IndexArray = new uint[( temp.Length - 1 ) * 2 * 3];
uint VertexCounter = 0,
IndexCounter = 0,
QuadCounter = 0;
for ( int i = 0; i < temp.Length; i++ )
{
VertexArray[VertexCounter + 0].TexCoord.X = temp[i].TexCoord.X;
VertexArray[VertexCounter + 0].TexCoord.Y = 0.0;
VertexArray[VertexCounter + 0].Normal = temp[i].Normal;
VertexArray[VertexCounter + 0].Position = temp[i].Position + offset1;
VertexArray[VertexCounter + 1].TexCoord.X = temp[i].TexCoord.X;
VertexArray[VertexCounter + 1].TexCoord.Y = 1.0;
VertexArray[VertexCounter + 1].Normal = temp[i].Normal;
VertexArray[VertexCounter + 1].Position = temp[i].Position + offset2;
VertexCounter += 2;
if ( i < temp.Length - 1 )
{
IndexArray[IndexCounter + 0] = QuadCounter + 0;
IndexArray[IndexCounter + 1] = QuadCounter + 1;
IndexArray[IndexCounter + 2] = QuadCounter + 2;
IndexArray[IndexCounter + 3] = QuadCounter + 2;
IndexArray[IndexCounter + 4] = QuadCounter + 1;
IndexArray[IndexCounter + 5] = QuadCounter + 3;
IndexCounter += 6;
QuadCounter += 2;
}
}
}
private void Slerp( ref Vector3d a, ref Vector3d b, double factor, out Vector3d result)
{
double t1;
Vector3d.Dot( ref a, ref b, out t1 );
double theta = System.Math.Acos( t1 );
double temp = 1.0 / System.Math.Sin( theta );
double t2 = System.Math.Sin( ( 1.0 - factor ) * theta ) * temp;
double t3 = System.Math.Sin( factor * theta ) * temp;
Vector3d v1 = Vector3d.Multiply( a, t2);
Vector3d v2 = Vector3d.Multiply( b, t3 );
result = Vector3d.Add( v1, v2 );
}
}
}