mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-25 07:05:38 +00:00
8dcb8601a2
Hopefully this is the first and last time we have to do this.
195 lines
6.2 KiB
C#
195 lines
6.2 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 );
|
|
}
|
|
|
|
|
|
}
|
|
}
|