mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-23 19:45:29 +00:00
8dcb8601a2
Hopefully this is the first and last time we have to do this.
197 lines
8.1 KiB
C#
197 lines
8.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
using OpenTK;
|
|
|
|
namespace Examples.Shapes
|
|
{
|
|
public sealed class SlicedSphere: DrawableShape
|
|
{
|
|
public enum eSubdivisions
|
|
{
|
|
Zero = 0,
|
|
One = 1,
|
|
Two = 2,
|
|
Three = 3,
|
|
Four = 4,
|
|
Five=5,
|
|
Six=6,
|
|
Seven=7,
|
|
Eight=8,
|
|
}
|
|
|
|
public enum eDir
|
|
{
|
|
All,
|
|
FrontTopRight,
|
|
FrontBottomRight,
|
|
FrontBottomLeft,
|
|
FrontTopLeft,
|
|
BackTopRight,
|
|
BackBottomRight,
|
|
BackBottomLeft,
|
|
BackTopLeft,
|
|
|
|
}
|
|
|
|
public SlicedSphere( double radius, Vector3d offset, eSubdivisions subdivs, eDir[] sides, bool useDL )
|
|
: base( useDL )
|
|
{
|
|
double Diameter = radius;
|
|
|
|
PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.Triangles;
|
|
|
|
if ( sides[0] == eDir.All )
|
|
{
|
|
sides = new eDir[] { eDir.FrontTopRight,
|
|
eDir.FrontBottomRight,
|
|
eDir.FrontBottomLeft,
|
|
eDir.FrontTopLeft,
|
|
eDir.BackTopRight,
|
|
eDir.BackBottomRight,
|
|
eDir.BackBottomLeft,
|
|
eDir.BackTopLeft,};
|
|
}
|
|
|
|
VertexArray = new VertexT2dN3dV3d[sides.Length * 3];
|
|
IndexArray = new uint[sides.Length * 3];
|
|
|
|
uint counter = 0;
|
|
foreach ( eDir s in sides )
|
|
{
|
|
GetDefaultVertices( s, Diameter, out VertexArray[counter + 0], out VertexArray[counter + 1], out VertexArray[counter + 2] );
|
|
IndexArray[counter + 0] = counter + 0;
|
|
IndexArray[counter + 1] = counter + 1;
|
|
IndexArray[counter + 2] = counter + 2;
|
|
counter += 3;
|
|
}
|
|
|
|
if ( subdivs != eSubdivisions.Zero )
|
|
{
|
|
|
|
for ( int s = 0; s < (int)subdivs; s++ )
|
|
{
|
|
#region Assemble Chunks and convert to Arrays
|
|
List<Chunk> AllChunks = new List<Chunk>();
|
|
for ( uint i = 0; i < IndexArray.Length; i += 3 )
|
|
{
|
|
Chunk chu;
|
|
Subdivide( Diameter,
|
|
ref VertexArray[IndexArray[i + 0]],
|
|
ref VertexArray[IndexArray[i + 1]],
|
|
ref VertexArray[IndexArray[i + 2]],
|
|
out chu );
|
|
AllChunks.Add( chu );
|
|
}
|
|
|
|
Chunk.GetArray( ref AllChunks, out VertexArray, out IndexArray );
|
|
AllChunks.Clear();
|
|
#endregion Assemble Chunks and convert to Arrays
|
|
}
|
|
}
|
|
|
|
for (int i=0; i<VertexArray.Length;i++)
|
|
{
|
|
Vector3d.Add(ref VertexArray[i].Position, ref offset, out VertexArray[i].Position);
|
|
}
|
|
}
|
|
|
|
private void GetDefaultVertices( eDir s, double scale, out VertexT2dN3dV3d first, out VertexT2dN3dV3d second, out VertexT2dN3dV3d third )
|
|
{
|
|
VertexT2dN3dV3d t1 = new VertexT2dN3dV3d(),
|
|
t2 = new VertexT2dN3dV3d(),
|
|
t3 = new VertexT2dN3dV3d();
|
|
switch ( s )
|
|
{
|
|
case eDir.FrontTopRight:
|
|
t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), Vector3d.UnitY, Vector3d.UnitY * scale );
|
|
t2 = new VertexT2dN3dV3d( new Vector2d( 0.0, 0.0 ), Vector3d.UnitZ, Vector3d.UnitZ * scale );
|
|
t3 = new VertexT2dN3dV3d( new Vector2d( 0.5, 0.0 ), Vector3d.UnitX, Vector3d.UnitX * scale );
|
|
break;
|
|
case eDir.FrontBottomRight:
|
|
t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 0.0 ), Vector3d.UnitX, Vector3d.UnitX * scale );
|
|
t2 = new VertexT2dN3dV3d( new Vector2d( 0.0, 0.0 ), Vector3d.UnitZ, Vector3d.UnitZ * scale );
|
|
t3 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), -Vector3d.UnitY, -Vector3d.UnitY * scale );
|
|
break;
|
|
case eDir.FrontBottomLeft:
|
|
t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 0.0 ), Vector3d.UnitX, Vector3d.UnitX * scale );
|
|
t2 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), -Vector3d.UnitY, -Vector3d.UnitY * scale );
|
|
t3 = new VertexT2dN3dV3d( new Vector2d( 1.0, 0.0 ), -Vector3d.UnitZ, -Vector3d.UnitZ * scale );
|
|
break;
|
|
case eDir.FrontTopLeft:
|
|
t1 = new VertexT2dN3dV3d( new Vector2d( 1.0, 0.0 ), -Vector3d.UnitZ, -Vector3d.UnitZ * scale );
|
|
t2 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), Vector3d.UnitY, Vector3d.UnitY * scale );
|
|
t3 = new VertexT2dN3dV3d( new Vector2d( 0.5, 0.0 ), Vector3d.UnitX, Vector3d.UnitX * scale );
|
|
break;
|
|
case eDir.BackTopRight:
|
|
t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), Vector3d.UnitY, Vector3d.UnitY * scale );
|
|
t2 = new VertexT2dN3dV3d( new Vector2d( 0.0, 1.0 ), -Vector3d.UnitX, -Vector3d.UnitX * scale );
|
|
t3 = new VertexT2dN3dV3d( new Vector2d( 0.0, 0.0 ), Vector3d.UnitZ, Vector3d.UnitZ * scale );
|
|
break;
|
|
case eDir.BackBottomRight:
|
|
t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), -Vector3d.UnitY, -Vector3d.UnitY * scale );
|
|
t2 = new VertexT2dN3dV3d( new Vector2d( 0.0, 0.0 ), Vector3d.UnitZ, Vector3d.UnitZ * scale );
|
|
t3 = new VertexT2dN3dV3d( new Vector2d( 0.0, 1.0 ), -Vector3d.UnitX, -Vector3d.UnitX * scale );
|
|
break;
|
|
case eDir.BackBottomLeft:
|
|
t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), -Vector3d.UnitY, -Vector3d.UnitY * scale );
|
|
t2 = new VertexT2dN3dV3d( new Vector2d( 1.0, 1.0 ), -Vector3d.UnitX, -Vector3d.UnitX * scale );
|
|
t3 = new VertexT2dN3dV3d( new Vector2d( 1.0, 0.0 ), -Vector3d.UnitZ, -Vector3d.UnitZ * scale );
|
|
break;
|
|
case eDir.BackTopLeft:
|
|
t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), Vector3d.UnitY, Vector3d.UnitY * scale );
|
|
t2 = new VertexT2dN3dV3d( new Vector2d( 1.0, 0.0 ), -Vector3d.UnitZ, -Vector3d.UnitZ * scale );
|
|
t3 = new VertexT2dN3dV3d( new Vector2d( 1.0, 1.0 ), -Vector3d.UnitX, -Vector3d.UnitX * scale );
|
|
break;
|
|
}
|
|
first = t1;
|
|
second = t2;
|
|
third = t3;
|
|
}
|
|
|
|
|
|
private void Subdivide( double Scale, ref VertexT2dN3dV3d first, ref VertexT2dN3dV3d second, ref VertexT2dN3dV3d third, out Chunk c )
|
|
{
|
|
c = new Chunk(6, 12);
|
|
|
|
c.Vertices[0] = first;
|
|
|
|
Vector3d.Lerp(ref first.Position, ref second.Position, 0.5,out c.Vertices[1].Normal );
|
|
c.Vertices[1].Normal.Normalize();
|
|
c.Vertices[1].Position = c.Vertices[1].Normal * Scale;
|
|
Vector2d.Lerp( ref first.TexCoord, ref second.TexCoord, 0.5, out c.Vertices[1].TexCoord );
|
|
|
|
Vector3d.Lerp( ref third.Position, ref first.Position, 0.5, out c.Vertices[2].Normal );
|
|
c.Vertices[2].Normal.Normalize();
|
|
c.Vertices[2].Position = c.Vertices[2].Normal * Scale;
|
|
Vector2d.Lerp( ref third.TexCoord, ref first.TexCoord, 0.5, out c.Vertices[2].TexCoord );
|
|
|
|
c.Vertices[3] = second;
|
|
|
|
Vector3d.Lerp( ref second.Position, ref third.Position, 0.5, out c.Vertices[4].Normal );
|
|
c.Vertices[4].Normal.Normalize();
|
|
c.Vertices[4].Position = c.Vertices[4].Normal * Scale;
|
|
Vector2d.Lerp( ref second.TexCoord, ref third.TexCoord, 0.5, out c.Vertices[4].TexCoord );
|
|
|
|
c.Vertices[5] = third;
|
|
|
|
#region Indices
|
|
c.Indices[0]=0;
|
|
c.Indices[1]=1;
|
|
c.Indices[2]=2;
|
|
c.Indices[3]=2;
|
|
c.Indices[4]=1;
|
|
c.Indices[5]=4;
|
|
c.Indices[6]=1;
|
|
c.Indices[7]=3;
|
|
c.Indices[8]=4;
|
|
c.Indices[9]=2;
|
|
c.Indices[10]=4;
|
|
c.Indices[11]=5;
|
|
#endregion Indices
|
|
}
|
|
|
|
}
|
|
}
|