diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json
new file mode 100644
index 0000000..f8b4888
--- /dev/null
+++ b/.vs/ProjectSettings.json
@@ -0,0 +1,3 @@
+{
+ "CurrentProjectSetting": null
+}
\ No newline at end of file
diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite
new file mode 100644
index 0000000..2ae2e41
Binary files /dev/null and b/.vs/slnx.sqlite differ
diff --git a/FrameBuffer.cs b/FrameBuffer.cs
deleted file mode 100644
index ce19694..0000000
--- a/FrameBuffer.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Print image to screen.
- *
- * Just 'draw' the byte array to the buffer.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.IO;
-
-namespace ConsoleGraphics
-{
- class FrameBuffer : Program
- {
- private static int lastTime;
- private static int numRenderings = 0;
- private const short sampleSize = 100;
- private string lastFrame = "";
- Stream s = Console.OpenStandardOutput();
-
- private void vSync(short targetFrameRate, int delay, int startDrawTime)
- {
- //Synchronize frames and display framerate to the lower right corner of the render window
- int targetDelay = 1000 / targetFrameRate;
- if (delay < targetDelay && VSYNC_ON)//we're too fast
- {
- System.Threading.Thread.Sleep(targetDelay - delay);
- }
-
- if (numRenderings == sampleSize)
- {
- int y = Environment.TickCount - lastTime;
- if (y != 0)
- printch((sampleSize * 1000 / y).ToString().ToCharArray(), RENDER_WIDTH - 50, RENDER_HEIGHT + 1);
- numRenderings = 0;
- }
- }
-
- public void drawFrame(byte[,] image, int a = 0, int b = 0)
- {
- //use cudafy / multithreading to paint quickly, also invoke writetoconsole?
- byte[] bufImg = new byte[RENDER_HEIGHT * RENDER_WIDTH];
-
- for (int x = 0; x < RENDER_WIDTH; x++)
- for (int y = 0; y < RENDER_HEIGHT; y++)
- bufImg[x+y*RENDER_WIDTH] = image[x,y];
- int beginRender = Environment.TickCount;
-
- Console.SetCursorPosition(a, b);
- //.Flush();
- //string iString = bufImg.ToString();
- //byte[] b = Encoding.UTF8.GetBytes(iString);
- //if (string.Compare(lastFrame, iString) != 0)
- //{
- s.Write(bufImg, 0, bufImg.Length);
- // lastFrame = iString;
- //}
- int endRender = Environment.TickCount - beginRender;
-
- vSync(MAX_FPS, endRender, beginRender);
-
- if (numRenderings == 0)
- lastTime = Environment.TickCount;
-
- numRenderings++;
- }
- }
-}
diff --git a/Game.cs b/Game.cs
new file mode 100644
index 0000000..b67affe
--- /dev/null
+++ b/Game.cs
@@ -0,0 +1,190 @@
+using System;
+using System.Threading;
+using System.IO;
+using ConsoleGraphics.Maths;
+using ConsoleGraphics.Render;
+using ConsoleGraphics.Utils;
+
+namespace ConsoleGraphics
+{
+ public static class Game
+ {
+ //special characters:█ ▄ ▀ ■
+ //public bool FRAMERATE_ON = true;
+
+ public static bool USE_VSYNC = false;
+ public static ThreeState renderState = new ThreeState(0);
+ public const short RENDER_WIDTH = 300;
+ public const short RENDER_HEIGHT = 100;
+ public const short MAX_FPS = 1000;
+ public const float PI = (float)3.1415926535;
+
+ //static char[, ,] numerals = new char[9, 8, 10];
+ public static char[] levels;
+
+ public static volatile Mesh ActiveMesh = null;
+ public static Light light1 = new Light(0, 0, 0, 700);
+
+ public static void Main(string[] args)
+ {
+ try
+ {
+ ActiveMesh = Mesh.LoadMeshFromFile(@"Resources\Meshes\link.obj");
+ }
+ catch(Exception e)
+ {
+ Console.WriteLine($"Failed to load mesh: {e.Message}");
+ Console.Read();
+ return;
+ }
+
+ //BrightnessInit.go();
+ //BrightnessInit.sortstuff();
+ GameInit(RENDER_WIDTH, RENDER_HEIGHT, "render");
+ ActiveMesh.Translate(new Vector3(-800, -300, -8));
+ //someShape.rotate((float)0.25);
+
+ FrameBuffer.DrawFrame(Rasterizer.RenderSolid(ActiveMesh));
+ //Console.ReadLine();
+ //someShape.rotate((float)(3.1415));
+
+ // render loop
+ while (true)
+ {
+ //light1.intensity = (int)((double)800 * Math.Sin(4*i));
+ //someShape.rotate(0.005, 0);
+ //someShape.rotate(0.005, 1);
+ //someShape.rotate(0.005, 2);
+ //someShape.translate(new Mesh.point3((float)Math.Sin(i), 0, 0));
+ // buffer.drawFrame(drawLine(new byte[RENDER_HEIGHT * RENDER_WIDTH], a1, a2));
+ if (renderState.x == 0)
+ FrameBuffer.DrawFrame(Rasterizer.RenderSolid(ActiveMesh));
+ else if (renderState.x == 1)
+ FrameBuffer.DrawFrame(Rasterizer.RenderVertices(ActiveMesh));
+ else if (renderState.x == 2)
+ FrameBuffer.DrawFrame(Rasterizer.RenderWire(ActiveMesh));
+
+ //light1.coords.x = 1000 * (float)Math.Sin(i);
+ // light1.coords.y = 1000 * (float)Math.Sin(i);
+ //light1.coords.z = 100 * (float)Math.Sin(i);
+ //someShape.rotate((float)0.005, 0);
+ //someShape.rotate((float)0.005, 1);
+ }
+ }
+
+ private static void GameInit(short width, short height, string title)
+ {
+ Console.Title = title;
+ Console.CursorVisible = false;
+ Console.BackgroundColor = ConsoleColor.Black;
+
+ SetConsoleSize(width, height);
+
+ //clear colors from user preset.
+ Console.Clear();
+ Console.SetCursorPosition(0, height);
+ Console.Write(new String('▄', RENDER_WIDTH));
+ Console.ForegroundColor = ConsoleColor.Cyan;
+
+ StreamReader levelsReader = new StreamReader("Resources\\levels.txt");
+
+ levels = new char[256];
+ int index = 0;
+ while (!levelsReader.EndOfStream && index < 256)
+ {
+ string e1 = levelsReader.ReadLine();
+ levels[index] = Char.Parse(e1);
+ index++;
+ }
+
+ Thread inputThread = new Thread(MainGetInput);
+ inputThread.Start();
+ //Thread soundPlayer = new Thread(playSound);
+ //soundPlayer.Start();
+ }
+
+ private static void SetConsoleSize(short width, short height)
+ {
+ // loop forever. only return when the window size and buffer size is set
+ while (true)
+ {
+ try
+ {
+ Console.SetWindowSize(width, height + 15);
+ Console.SetBufferSize(width, height + 15);
+ // exit the function allowing everything else to initialise
+ return;
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ Console.WriteLine("Decrease your font size and press enter");
+ Console.WriteLine("You can resize the font using 'CTRL + MouseWheel'");
+ Console.ReadLine();
+ }
+ }
+ }
+
+ private static byte[,] LoadTexture(string loc)
+ {
+ byte[,] loadedTexture = new byte[2, 2];
+ return (loadedTexture);
+ }
+
+ public static void printch(char[] charId, int x, int y)
+ {
+ Console.SetCursorPosition(0, RENDER_HEIGHT + 4);
+ Console.Write(new string(' ', 10));
+ Console.SetCursorPosition(0, RENDER_HEIGHT + 4);
+ Console.Write(charId);
+ }
+
+ private static void MainGetInput()
+ {
+ //Console.TreatControlCAsInput = true;
+
+ while (true)
+ {
+ ConsoleKeyInfo keyInfo = Console.ReadKey();
+ if (keyInfo.Key == ConsoleKey.Escape)
+ {
+ Environment.Exit(0);
+ return;
+ }
+
+ switch (keyInfo.Key)
+ {
+ case ConsoleKey.Spacebar:
+ renderState.changeState();
+ break;
+ case ConsoleKey.W:
+ ActiveMesh.Translate(0, 0, 0.1f);
+ break;
+ case ConsoleKey.A:
+ ActiveMesh.Translate(-10.0f, 0, 0);
+ break;
+ case ConsoleKey.S:
+ ActiveMesh.Translate(0, 0, -0.1f);
+ break;
+ case ConsoleKey.D:
+ ActiveMesh.Translate(10.0f, 0, 0);
+ break;
+ case ConsoleKey.R:
+ ActiveMesh.Rotate(0.01, 0);
+ break;
+ case ConsoleKey.T:
+ ActiveMesh.Rotate(0.01, 1);
+ break;
+ case ConsoleKey.Y:
+ ActiveMesh.Rotate(0.01, 2);
+ break;
+ case ConsoleKey.Q:
+ ActiveMesh.Translate(0, -10.0f, 0);
+ break;
+ case ConsoleKey.E:
+ ActiveMesh.Translate(0, 10.0f, 0);
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/Material.cs b/Material.cs
deleted file mode 100644
index 027a3ba..0000000
--- a/Material.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using System.Drawing;
-using System.IO;
-
-namespace ConsoleGraphics
-{
- class Material
- //convert textures
- {
- public byte[,] bitmapColorsCached;
- public int SIZE;
-
- public Material(string fileName)
- {
- Bitmap sourceBmp = (Bitmap)Image.FromFile(fileName, true);//load character set (digits 1->9..)
- bitmapColorsCached = new byte[sourceBmp.Width, sourceBmp.Height];
- SIZE = sourceBmp.Width;
- for (int i = 0; i < sourceBmp.Width; i++)
- for (int j = 0; j < sourceBmp.Height; j++)
- {
- Color c = sourceBmp.GetPixel(i, j);
- bitmapColorsCached[i,j] = (byte)((c.R + c.B + c.G) / 3);
- }
- }
- }
-}
diff --git a/Maths/MathHelper.cs b/Maths/MathHelper.cs
new file mode 100644
index 0000000..767b215
--- /dev/null
+++ b/Maths/MathHelper.cs
@@ -0,0 +1,51 @@
+namespace ConsoleGraphics.Maths
+{
+ ///
+ /// A helper class that contains useful function for doing maths
+ ///
+ public class MathHelper
+ {
+ ///
+ /// Swaps the values of the 2 given floats
+ ///
+ ///
+ ///
+ public static void Swap(ref float x, ref float y)
+ {
+ float temp = x;
+ x = y;
+ y = temp;
+ }
+
+ ///
+ /// Swaps the values of the 2 given integers
+ ///
+ ///
+ ///
+ public static void Swap(ref int x, ref int y)
+ {
+ int temp = x;
+ x = y;
+ y = temp;
+ }
+
+ ///
+ /// Clamps the given value between the given min and max value.
+ ///
+ /// e.g. Clamp(420, 50, 500) return 420, Clamp(100, 5, 50) return 50, Clamp(
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static float Clamp(float value, float min, float max)
+ {
+ if (value > max)
+ return max;
+ if (value < min)
+ return min;
+ return value;
+ }
+ }
+}
diff --git a/Maths/Matrix.cs b/Maths/Matrix.cs
new file mode 100644
index 0000000..0d024f2
--- /dev/null
+++ b/Maths/Matrix.cs
@@ -0,0 +1,34 @@
+namespace ConsoleGraphics.Maths
+{
+ ///
+ /// Matrix. N x N matricies
+ ///
+ public class Matrix
+ {
+ ///
+ /// Row,Column
+ ///
+ public float[,] M;
+
+ public Matrix(float[,] vals, int rows, int cols)
+ {
+ M = new float[rows, cols];
+ for (int i = 0; i < rows; i++)
+ {
+ for (int j = 0; j < cols; j++)
+ {
+ M[i, j] = vals[i, j];
+ }
+ }
+ }
+
+ public Vector3 Multiply(Vector3 vector)
+ {
+ Vector3 pNew;
+ pNew.X = vector.X * M[0, 0] + vector.Y * M[0, 1] + vector.Z * M[0, 2];
+ pNew.Y = vector.X * M[1, 0] + vector.Y * M[1, 1] + vector.Z * M[1, 2];
+ pNew.Z = vector.X * M[2, 0] + vector.Y * M[2, 1] + vector.Z * M[2, 2];
+ return pNew;
+ }
+ }
+}
diff --git a/Maths/Triangle.cs b/Maths/Triangle.cs
new file mode 100644
index 0000000..f3bf472
--- /dev/null
+++ b/Maths/Triangle.cs
@@ -0,0 +1,34 @@
+namespace ConsoleGraphics.Maths
+{
+ ///
+ /// A face that contains a indexes which can be used to point to vertices, texture coordinates, and a material
+ ///
+ public struct Triangle
+ {
+ ///
+ /// An array of indexes which point to a vertex somewhere else
+ ///
+ public int[] VertexIds;
+ ///
+ /// An array of indexes which point to a texture coordinate somewhere else
+ ///
+ public int[] UVIds;
+ ///
+ /// An index that points to a material somewhere else
+ ///
+ public int MaterialId;
+
+ public Triangle(int v1, int v2, int v3, int vt1, int vt2, int vt3, int mid)
+ {
+ VertexIds = new int[3];
+ VertexIds[0] = v1;
+ VertexIds[1] = v2;
+ VertexIds[2] = v3;
+ UVIds = new int[3];
+ UVIds[0] = vt1;
+ UVIds[1] = vt2;
+ UVIds[2] = vt3;
+ MaterialId = mid;
+ }
+ }
+}
diff --git a/Maths/Vector2.cs b/Maths/Vector2.cs
new file mode 100644
index 0000000..aaa76b1
--- /dev/null
+++ b/Maths/Vector2.cs
@@ -0,0 +1,13 @@
+namespace ConsoleGraphics.Maths
+{
+ public struct Vector2
+ {
+ public float X, Y;
+
+ public Vector2(float x, float y)
+ {
+ X = x;
+ Y = y;
+ }
+ }
+}
diff --git a/Maths/Vector3.cs b/Maths/Vector3.cs
new file mode 100644
index 0000000..fc46b1a
--- /dev/null
+++ b/Maths/Vector3.cs
@@ -0,0 +1,108 @@
+using System;
+
+namespace ConsoleGraphics.Maths
+{
+ ///
+ /// A struct containing an X, Y and Z value, and basic functions for manipulating those values, e.g. the dot product, normalisation, etc
+ ///
+ public struct Vector3
+ {
+ public float X, Y, Z;
+
+ public Vector3(float x, float y, float z = 0)
+ {
+ X = x;
+ Y = y;
+ Z = z;
+ }
+
+ ///
+ /// Adds the given XYZ values to this vector instance's XYZ values
+ ///
+ ///
+ ///
+ ///
+ public void Add(float x, float y, float z)
+ {
+ this.X += x;
+ this.Y += y;
+ this.Z += z;
+ }
+
+ ///
+ /// Adds the XYZ values of the given vector to this vector instance's XYZ values
+ ///
+ ///
+ ///
+ ///
+ public void Add(Vector3 v)
+ {
+ Add(v.X, v.Y, v.Z);
+ }
+
+ ///
+ /// Returns the dot product between this vector instance and the given vector
+ ///
+ ///
+ ///
+ public float Dot(Vector3 v)
+ {
+ return X * v.X + Y * v.Y + Z * v.Z;
+ }
+
+ ///
+ /// Returns the squared magnitude of this vector instance
+ ///
+ ///
+ public float MagnitudeSquared()
+ {
+ return X * X + Y * Y + Z * Z;
+ }
+
+ ///
+ /// Returns the magnitude of this vector instance
+ ///
+ ///
+ public float Magnitude()
+ {
+ return (float)Math.Sqrt(MagnitudeSquared());
+ }
+
+ public static Vector3 Normalize(Vector3 a)
+ {
+ float norm = (float)Math.Sqrt(a.X * a.X + a.Y * a.Y + a.Z * a.Z);
+ return (new Vector3(a.X / norm, a.Y / norm, a.Z / norm));
+ }
+
+ public static Vector3 Cross(Vector3 a, Vector3 b)
+ {
+ Vector3 resultant;
+ resultant.X = a.Y * b.Z - a.Z * b.Y;
+ resultant.Y = a.Z * b.X - a.X * b.Z;
+ resultant.Z = a.X * b.Y - a.Y * b.X;
+ return (resultant);
+ }
+
+ ///
+ /// Returns a new vector where the XYZ values of a and b have been added
+ ///
+ ///
+ ///
+ ///
+ public static Vector3 Add(Vector3 a, Vector3 b)
+ {
+ return (new Vector3((a.X + b.X), (a.Y + b.Y), (a.Z + b.Z)));
+ }
+
+ ///
+ /// Returns a new vector which contains the dot product between the a and b vector
+ ///
+ ///
+ ///
+ ///
+ public static float Dot(Vector3 a, Vector3 b)
+ {
+ return (a.X * b.X + a.Y * b.Y + a.Z * b.Z);
+ }
+ }
+}
diff --git a/Matrix.cs b/Matrix.cs
deleted file mode 100644
index 22719a9..0000000
--- a/Matrix.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * N x N matricies
- * Define & perform basic operations on matricies.
- *
- */
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ConsoleGraphics
-{
- class Matrix : Program
- {
- public float[,] m_i;//row,col
-
- public Matrix(float[,] vals, int rows, int cols)
- {
- m_i = new float[rows, cols];
- for (int i = 0; i < rows; i++)
- {
- for (int j = 0; j < cols; j++)
- {
- m_i[i, j] = vals[i, j];
- }
- }
- }
-
- public static float magnitude(Mesh.point3 a)
- {
- return((float)Math.Sqrt(dot(a,a)));
- }
- public static Mesh.point3 normalize(Mesh.point3 a)
- {
- float norm = (float)Math.Sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
- return (new Mesh.point3(a.x/norm, a.y/norm, a.z/norm));
- }
- public static Mesh.point3 cross(Mesh.point3 a, Mesh.point3 b)
- {
- Mesh.point3 resultant;
- resultant.x = a.y * b.z - a.z * b.y;
- resultant.y = a.z * b.x - a.x * b.z;
- resultant.z = a.x * b.y - a.y * b.x;
- return (resultant);
- }
-
- public static Mesh.point3 add(Mesh.point3 a, Mesh.point3 b)
- {
- return (new Mesh.point3((a.x + b.x), (a.y + b.y), (a.z + b.z)));
- }
-
- public static float dot(Mesh.point3 a, Mesh.point3 b)
- {
- return (a.x * b.x + a.y * b.y + a.z * b.z);
- }
-
- public Mesh.point3 multiply(Mesh.point3 vector)
- {
- Mesh.point3 pNew;
- pNew.x = vector.x * m_i[0, 0] + vector.y * m_i[0, 1] + vector.z * m_i[0, 2];
- pNew.y = vector.x * m_i[1, 0] + vector.y * m_i[1, 1] + vector.z * m_i[1, 2];
- pNew.z = vector.x * m_i[2, 0] + vector.y * m_i[2, 1] + vector.z * m_i[2, 2];
- return (pNew);
- }
- }
-}
diff --git a/Mesh.cs b/Mesh.cs
deleted file mode 100644
index c038743..0000000
--- a/Mesh.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Mesh - all the things that define a mesh. triangles, edges, verticies... later UVs...
- *
- *
- */
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ConsoleGraphics
-{
- class Mesh : Program
- {
- public Mesh(point3[] meshVerts, triangle[] meshFaces, point2[] meshUvs, Material[] mtls = null)
- {
- verts = meshVerts;
- vertCount = verts.Length;
- faces = meshFaces;
- faceCount = faces.Length;
- uvVerts = meshUvs;
- matIDs = mtls;
- }
-
- public struct triangle
- {
- public int[] vertIDs;
- public int[] uvIds;
- public int matID;
- public triangle(int v1, int v2, int v3, int vt1, int vt2, int vt3, int mid)
- {
- vertIDs = new int[3];
- vertIDs[0] = v1;
- vertIDs[1] = v2;
- vertIDs[2] = v3;
- uvIds = new int[3];
- uvIds[0] = vt1;
- uvIds[1] = vt2;
- uvIds[2] = vt3;
- matID = mid;
- }
- };
-
- public struct point3
- {
- public float x, y, z;
- public point3(float newX, float newY, float newZ = 0)
- {
- x = newX;
- y = newY;
- z = newZ;
- }
- };
-
- public struct point2
- {
- public float x, y;
- public point2(float newX, float newY)
- {
- x = newX;
- y = newY;
- }
- };
-
- public point3[] verts;
- public triangle[] faces;
- public point2[] uvVerts;
- public int vertCount;
- public int faceCount;
- public Material[] matIDs;
- public void translate(point3 translation)
- {
- for (int i = 0; i < verts.Length; i++)
- {
- verts[i] = Matrix.add(verts[i], translation);
- }
- }
-
- public void rotate(double angle, byte dir)
- {
- //Rotate about centerpoint of the shape: translate the center of our shape to the origin, rotate, translate back.
- float cosAngle = (float)Math.Cos(angle);
- float sinAngle = (float)Math.Sin(angle);
- Matrix rotMtrx = null;
- point3 startCoords = verts[0];
- translate(new Mesh.point3(-startCoords.x, -startCoords.y, -startCoords.z));
- #region rotations
- /* Rotate about X Axis {{1,0, 0},
- {0, cosAngle,sinAngle*100},
- {0, -sinAngle/100, cosAngle}}, 3, 3);
-
-
- * Rotate about Y Axis {{cosAngle,0,-sinAngle*100},
- {0, 1, 0},
- {sinAngle, 0, cosAngle}}, 3, 3);
- Rotate about Z axis
- * {{cosAngle,-sinAngle,0},
- {sinAngle, cosAngle,0},
- {0, 0, 1}},3,3);
- */
- #endregion
- int x = Environment.TickCount;
-
- if (dir == 0)
- rotMtrx = new Matrix(new float[,] {{1,0,0},
- {0, cosAngle,sinAngle*100},
- {0, -sinAngle/100, cosAngle}}, 3, 3);
- else if (dir == 1)
- rotMtrx = new Matrix(new float[,] {{cosAngle,0,-sinAngle*100},
- {0, 1, 0},
- {sinAngle/100, 0, cosAngle}}, 3, 3);
- else
- rotMtrx = new Matrix(new float[,] {{cosAngle,-sinAngle,0},
- {sinAngle, cosAngle,0},
- {0, 0, 1}}, 3, 3);
- x = Environment.TickCount - x;
-
- for (int i = 0; i < vertCount; i++)
- {
- verts[i] = rotMtrx.multiply(verts[i]);
- }
- translate(new Mesh.point3(startCoords.x, startCoords.y, startCoords.z));
- }
- }
-}
diff --git a/Program.cs b/Program.cs
deleted file mode 100644
index 65e0314..0000000
--- a/Program.cs
+++ /dev/null
@@ -1,238 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using System.IO;
-using System.Drawing;
-
-namespace ConsoleGraphics
-{
- class Program
- {
- //special characters:█ ▄ ▀ ■
-
- public bool VSYNC_ON = false;
- public static threeState ts = new threeState(0);
- // public bool FRAMERATE_ON = true;
- public const short RENDER_WIDTH = 300;
- public const short RENDER_HEIGHT = 100;
- public const short MAX_FPS = 1000;
- public const float pi = (float)3.1415926535;
- static char[, ,] numerals = new char[9, 8, 10];
- public static char[] levels;
-
- public struct threeState
- {
- public byte x;
- public threeState(byte initialState)
- {
- x = 0;
- }
- public void changeState()
- {
- x = (byte)((x + 1) % 3);
- }
- }
-
- public struct light
- {
- public Mesh.point3 coords;
- public float intensity;
- public light(float x, float y, float z, float setIntensity)
- {
- coords = new Mesh.point3(x, y, z);
- intensity = setIntensity;
- }
- };
-
- static void init(short width, short height, string title)
- {
- Console.Title = title;
- Console.CursorVisible = false;
- Console.BackgroundColor = ConsoleColor.Black;
- reTry:
- try
- {
- Console.SetWindowSize(width, height + 15);
- Console.SetBufferSize(width, height + 15);
- }
- catch (ArgumentOutOfRangeException)
- {
- Console.WriteLine("Decrease your font size and press enter");
- Console.ReadLine();
- goto reTry;
- }
- Console.Clear();//clear colors from user preset.
- Console.SetCursorPosition(0, height);
- Console.Write(new String('▄', RENDER_WIDTH));
- Console.ForegroundColor = ConsoleColor.Cyan;
-
- StreamReader r = new StreamReader("levels.txt");
-
- levels = new char[256];
- int index = 0;
- while (!r.EndOfStream && index < 256)
- {
- string e1 = r.ReadLine();
- levels[index] = Char.Parse(e1);
- index++;
- }
-
- Thread cin = new Thread(getInput);
- cin.Start();
- //Thread soundPlayer = new Thread(playSound);
- //soundPlayer.Start();
- }
-
- static byte[,] loadTex(string loc)
- {
- byte[,] loadedTexture = new byte[2, 2];
- return (loadedTexture);
- }
-
- static Mesh loadObj(string loc)
- {
- StreamReader r = new StreamReader(loc + ".obj");
- List loadedVerts = new List();
- List loadedUvs = new List();
- List loadedFaces = new List();
- List loadedUvFaces = new List();
- List mtls = new List();
- int vertCount = 0;
- int faceCount = 0;
-
- while (!r.EndOfStream)
- {
- string e1 = r.ReadLine();
- if (e1 != "")
- {
- if (e1[0] == 'v' && e1[1] == 't')//texture verticies
- {
- string temp = e1.Substring(3, e1.Length - 3);
- string[] coords = temp.Split(' ');
- Mesh.point2 p = new Mesh.point2(float.Parse(coords[0]), float.Parse(coords[1]));
- loadedUvs.Add(p);
- }
- else if (e1[0] == 'v')//vertex
- {
- vertCount++;
- string temp = e1.Substring(3, e1.Length - 3);
- string[] coords = temp.Split(' ');
- Mesh.point3 p = new Mesh.point3(float.Parse(coords[0]) * 100, float.Parse(coords[1]) * 100, float.Parse(coords[2]));
- //if z is positive it's off screen, z=0 we clip
- loadedVerts.Add(p);
- }
- else if (e1[0] == 'u')
- {//use this mtl for rest of faces faces material
- Material m = new Material(e1.Substring(7, e1.Length - 7));
- mtls.Add(m);
- }
- else if (e1[0] == 'f')//edge
- {
- faceCount++;
- string temp = e1.Substring(2, e1.Length - 2);
- string[] coords = temp.Split(' ', '/');
- Mesh.triangle f = new Mesh.triangle(int.Parse(coords[0]) - 1, int.Parse(coords[2]) - 1, int.Parse(coords[4]) - 1, /*UV ID's*/ int.Parse(coords[1]) - 1, int.Parse(coords[3]) - 1, int.Parse(coords[5]) - 1, mtls.Count);
- // Mesh.triangle uvf = new Mesh.triangle(int.Parse(coords[1]), int.Parse(coords[3]), int.Parse(coords[5]));
- loadedFaces.Add(f);
- // loadedUvFaces.Add(uvf);
- }
- }
- }
- return (new Mesh(loadedVerts.ToArray(), loadedFaces.ToArray(), loadedUvs.ToArray(), mtls.ToArray()));
- }
-
- public static Mesh someShape = loadObj("link");
- public static light light1 = new light(0, 0, 0, 700);
-
- public static void Main(string[] args)
- {
- //BrightnessInit.go();
- //BrightnessInit.sortstuff();
- init(RENDER_WIDTH, RENDER_HEIGHT, "render");
- FrameBuffer buffer = new FrameBuffer();
- Rasterizer rast = new Rasterizer();
- someShape.translate(new Mesh.point3(-800, -300, -8));
- //someShape.rotate((float)0.25);
-
- buffer.drawFrame(rast.renderSolid());
- Console.ReadLine();
- //someShape.rotate((float)(3.1415));
- for (double i = 0; i < 1000; i += 0.01)
- {
- //light1.intensity = (int)((double)800 * Math.Sin(4*i));
- //someShape.rotate(0.005, 0);
- //someShape.rotate(0.005, 1);
- //someShape.rotate(0.005, 2);
- //someShape.translate(new Mesh.point3((float)Math.Sin(i), 0, 0));
- // buffer.drawFrame(drawLine(new byte[RENDER_HEIGHT * RENDER_WIDTH], a1, a2));
- if (ts.x == 0)
- buffer.drawFrame(rast.renderSolid());
- else if (ts.x == 2)
- buffer.drawFrame(rast.renderWire(someShape));
- else if (ts.x == 1)
- buffer.drawFrame(rast.renderVerts(someShape));
-
- //light1.coords.x = 1000 * (float)Math.Sin(i);
- // light1.coords.y = 1000 * (float)Math.Sin(i);
- //light1.coords.z = 100 * (float)Math.Sin(i);
- //someShape.rotate((float)0.005, 0);
- //someShape.rotate((float)0.005, 1);
- }
- Console.ReadLine();
- }
-
- static void getInput()
- {
- ConsoleKeyInfo cki;
- // Console.TreatControlCAsInput = true;
- do
- {
- cki = Console.ReadKey();
- switch (cki.Key)
- {
- case ConsoleKey.Spacebar:
- ts.changeState();
- break;
- case ConsoleKey.W:
- someShape.translate(new Mesh.point3(0, 0, (float)0.1));
- break;
- case ConsoleKey.A:
- someShape.translate(new Mesh.point3(-10, 0, 0));
- break;
- case ConsoleKey.S:
- someShape.translate(new Mesh.point3(0, 0, (float)-0.1));
- break;
- case ConsoleKey.D:
- someShape.translate(new Mesh.point3(10, 0, 0));
- break;
- case ConsoleKey.R:
- someShape.rotate(0.01, 0);
- break;
- case ConsoleKey.T:
- someShape.rotate(0.01, 1);
- break;
- case ConsoleKey.Y:
- someShape.rotate(0.01, 2);
- break;
- case ConsoleKey.Q:
- someShape.translate(new Mesh.point3(0, -10, 0));
- break;
- case ConsoleKey.E:
- someShape.translate(new Mesh.point3(0, 10, 0));
- break;
- }
- } while (cki.Key != ConsoleKey.Escape);
- }
-
- public static void printch(char[] charId, int x, int y)
- {
- Console.SetCursorPosition(0, RENDER_HEIGHT + 4);
- Console.Write(new string(' ', 10));
- Console.SetCursorPosition(0, RENDER_HEIGHT + 4);
- Console.Write(charId);
- }
- }
-}
diff --git a/Rasterize.cs b/Rasterize.cs
deleted file mode 100644
index 9a58540..0000000
--- a/Rasterize.cs
+++ /dev/null
@@ -1,366 +0,0 @@
-/* Rasterization - all the grunt work!
- * Determine pixle 'colors'..
- */
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Drawing;
-
-namespace ConsoleGraphics
-{
- class Rasterizer : Program
- {
- public static int[,] zBuffer = new int[RENDER_WIDTH, RENDER_HEIGHT];
-
- void swap(ref float x, ref float y)
- {
- float temp = x;
- x = y;
- y = temp;
- }
-
- void swap(ref int x, ref int y)
- {
- int temp = x;
- x = y;
- y = temp;
- }
-
- float clamp(float val, float min, float max)
- {
- return (Math.Max(Math.Min(val, max), min));
- }
-
- public byte[,] renderVerts(Mesh someShape)
- {
- byte[,] image = new byte[RENDER_WIDTH, RENDER_HEIGHT];//
-
- for (int x = 0; x < RENDER_WIDTH; x++)
- for (int y = 0; y < RENDER_HEIGHT; y++)
- image[x, y] = 32;
-
- foreach (Mesh.triangle f in someShape.faces)
- {
- for (int i = 0; i < 3; i++)//each vertex
- {
- double depth = someShape.verts[f.vertIDs[i]].z;
- int P_x1 = (int)(someShape.verts[f.vertIDs[i]].x / depth);
- int P_y1 = (int)(someShape.verts[f.vertIDs[i]].y / depth);
-
- if (P_y1 < RENDER_HEIGHT - 1 && P_y1 >= 0 && P_x1 < RENDER_WIDTH - 1 && P_x1 >= 0)//the vert is in bounds with the screen
- image[P_x1, P_y1] = 177;
- }
- }
- return (image);
- }
-
- public byte[,] renderWire(Mesh someShape)
- {
- byte[,] image = new byte[RENDER_WIDTH, RENDER_HEIGHT];//
-
- for (int x = 0; x < RENDER_WIDTH; x++)
- for (int y = 0; y < RENDER_HEIGHT; y++)
- image[x, y] = 32;
-
- foreach (Mesh.triangle f in someShape.faces)
- {
- for (int i = 0; i < 3; i++)//each vertex
- {
- double depth = someShape.verts[f.vertIDs[i]].z;
- int P_x1 = (int)((RENDER_WIDTH / 2) + someShape.verts[f.vertIDs[i]].x / depth);
- int P_y1 = (int)(((RENDER_HEIGHT - 15) / 2) + someShape.verts[f.vertIDs[i]].y / depth);
-
- if (P_y1 < RENDER_HEIGHT - 1 && P_y1 >= 0 && P_x1 < RENDER_WIDTH - 1 && P_x1 >= 0)//the vert is in bounds with the screen
- for (int j = 0; j < 2; j++)//each of the 2 neighboring verts
- {
- double depth2 = someShape.verts[f.vertIDs[j]].z;
- int P_x = (int)((RENDER_WIDTH / 2) + someShape.verts[f.vertIDs[j]].x / depth2);
- int P_y = (int)(((RENDER_HEIGHT - 15) / 2) + someShape.verts[f.vertIDs[j]].y / depth2);
-
- if (P_y < RENDER_HEIGHT - 1 && P_y >= 0 && P_x < RENDER_WIDTH - 1 && P_x >= 0)
- image = drawLine(image, P_x, P_y, P_x1, P_y1, true);
- }
- }
- }
- return (image);
- }
- Mesh.triangle targFace;
- public byte[,] renderSolid()
- {
- byte[,] image = new byte[RENDER_WIDTH, RENDER_HEIGHT];//
-
- for (int x = 0; x < RENDER_WIDTH; x++)
- for (int y = 0; y < RENDER_HEIGHT; y++)
- {
- image[x, y] = 32; //space character is drawn faster than the null character (0)
- zBuffer[x, y] = -100; //far clipping plane
- }
-
- foreach (Mesh.triangle f in someShape.faces)
- {
- targFace = f;
- Mesh.point3 a = Matrix.add(someShape.verts[f.vertIDs[0]], new Mesh.point3(-someShape.verts[f.vertIDs[2]].x, -someShape.verts[f.vertIDs[2]].y, -someShape.verts[f.vertIDs[2]].z));
- Mesh.point3 b = Matrix.add(someShape.verts[f.vertIDs[0]], new Mesh.point3(-someShape.verts[f.vertIDs[1]].x, -someShape.verts[f.vertIDs[1]].y, -someShape.verts[f.vertIDs[1]].z));
- Mesh.point3 surfaceNorm1 = Matrix.cross(a, b);
-
- surfaceNorm1 = Matrix.normalize(surfaceNorm1);
-
- Mesh.point3 lightNorm1 = Matrix.add(light1.coords, new Mesh.point3(-someShape.verts[f.vertIDs[0]].x, -someShape.verts[f.vertIDs[0]].y, -someShape.verts[f.vertIDs[0]].z));//arbitrary vert
- lightNorm1 = Matrix.normalize(lightNorm1);
- ////////////////////////////////////
- Mesh.point3 a1 = Matrix.add(someShape.verts[f.vertIDs[1]], new Mesh.point3(-someShape.verts[f.vertIDs[2]].x, -someShape.verts[f.vertIDs[2]].y, -someShape.verts[f.vertIDs[2]].z));
- Mesh.point3 b1 = Matrix.add(someShape.verts[f.vertIDs[1]], new Mesh.point3(-someShape.verts[f.vertIDs[0]].x, -someShape.verts[f.vertIDs[0]].y, -someShape.verts[f.vertIDs[0]].z));
- Mesh.point3 surfaceNorm2 = Matrix.cross(a1, b1);
-
- surfaceNorm2 = Matrix.normalize(surfaceNorm2);
-
- Mesh.point3 lightNorm2 = Matrix.add(light1.coords, new Mesh.point3(-someShape.verts[f.vertIDs[1]].x, -someShape.verts[f.vertIDs[1]].y, -someShape.verts[f.vertIDs[1]].z));//arbitrary vert
- lightNorm2 = Matrix.normalize(lightNorm2);
- //////////////////////////////////////////////
- Mesh.point3 a2 = Matrix.add(someShape.verts[f.vertIDs[2]], new Mesh.point3(-someShape.verts[f.vertIDs[0]].x, -someShape.verts[f.vertIDs[0]].y, -someShape.verts[f.vertIDs[0]].z));
- Mesh.point3 b2 = Matrix.add(someShape.verts[f.vertIDs[2]], new Mesh.point3(-someShape.verts[f.vertIDs[1]].x, -someShape.verts[f.vertIDs[1]].y, -someShape.verts[f.vertIDs[1]].z));
- Mesh.point3 surfaceNorm3 = Matrix.cross(a2, b2);
-
- surfaceNorm3 = Matrix.normalize(surfaceNorm3);
-
- Mesh.point3 lightNorm3 = Matrix.add(light1.coords, new Mesh.point3(-someShape.verts[f.vertIDs[2]].x, -someShape.verts[f.vertIDs[2]].y, -someShape.verts[f.vertIDs[2]].z));//arbitrary vert
- lightNorm3 = Matrix.normalize(lightNorm3);
- ////////////////////////////////////////////
-
- //perspective projection
- float[] depth = {someShape.verts[f.vertIDs[0]].z,
- someShape.verts[f.vertIDs[1]].z,
- someShape.verts[f.vertIDs[2]].z};
-
- if (depth[0] < 0 && depth[1] < 0 && depth[2] < 0)
- { //>= one vertex is in screen
- int x0 = (int)((RENDER_WIDTH / 2) + someShape.verts[f.vertIDs[0]].x / depth[0]);
- int y0 = (int)(((RENDER_HEIGHT - 15) / 2) + someShape.verts[f.vertIDs[0]].y / depth[0]);
-
- int x1 = (int)((RENDER_WIDTH / 2) + someShape.verts[f.vertIDs[1]].x / depth[1]);
- int y1 = (int)(((RENDER_HEIGHT - 15) / 2) + someShape.verts[f.vertIDs[1]].y / depth[1]);
-
- int x2 = (int)((RENDER_WIDTH / 2) + someShape.verts[f.vertIDs[2]].x / depth[2]);
- int y2 = (int)(((RENDER_HEIGHT - 15) / 2) + someShape.verts[f.vertIDs[2]].y / depth[2]);
-
-
- Mesh.point2[] uvs = new Mesh.point2[] { someShape.uvVerts[f.uvIds[0]],
- someShape.uvVerts[f.uvIds[1]],
- someShape.uvVerts[f.uvIds[2]]
- };
- Mesh.point3[] projPoints = new Mesh.point3[] {new Mesh.point3(x0, y0, depth[0]),
- new Mesh.point3(x1, y1, depth[1]),
- new Mesh.point3(x2, y2, depth[2])};
-
- byte[] colors = {(byte)(light1.intensity * Math.Max(0, Matrix.dot(surfaceNorm1, lightNorm1))),
- (byte)(light1.intensity * Math.Max(0, Matrix.dot(surfaceNorm2, lightNorm2))),
- (byte)(light1.intensity * Math.Max(0, Matrix.dot(surfaceNorm3, lightNorm3)))};
-
- image = drawTriangle(image, projPoints, uvs, colors);
- }
- }
- return (image);
- }
-
- private byte[,] drawTriangle(byte[,] image, Mesh.point3[] points, Mesh.point2[] uvs, byte[] brightness = null)
- {
- /*
- * A
- * B-------
- * C
- *
- */
- //sort by lowest y value (highest on screen)
- Mesh.point3[] unsortedPoints = new Mesh.point3[3];
- points.CopyTo(unsortedPoints, 0);
-
- if (points[1].y < points[0].y)
- {//swap point[1] and point[0]
- swap(ref points[0].y, ref points[1].y);
- swap(ref points[0].x, ref points[1].x);
- }
- if (points[2].y < points[0].y)
- {//swap point[0] and point[2]
- swap(ref points[0].y, ref points[2].y);
- swap(ref points[0].x, ref points[2].x);
- }
- if (points[2].y < points[1].y)
- {//swap point[1] & point[2]
- swap(ref points[1].y, ref points[2].y);
- swap(ref points[1].x, ref points[2].x);
- }
-
- if (points[0].y == points[1].y)
- {//flat top
- image = fillFlatTop(image, points, unsortedPoints, brightness, uvs);
- }
- else if (points[1].y == points[2].y)
- {//flat bottom
- image = fillFlatBottom(image, points, unsortedPoints, brightness, uvs);
- }
- else
- {//nontrivial
- Mesh.point3 midpoint = new Mesh.point3((int)(Math.Ceiling(points[0].x + ((float)(points[1].y - points[0].y) / (float)(points[2].y - points[0].y)) * (points[2].x - points[0].x))), points[1].y);
- fillFlatBottom(image, new Mesh.point3[] { points[0], points[1], midpoint }, unsortedPoints, brightness, uvs);
- fillFlatTop(image, new Mesh.point3[] { points[1], midpoint, points[2] }, unsortedPoints, brightness, uvs);
- }
- return (image);
- }
-
- private byte[,] fillFlatTop(byte[,] image, Mesh.point3[] sortedPoints, Mesh.point3[] unsortedPoints, byte[] brightness, Mesh.point2[] uvs = null)
- {
- float startX = sortedPoints[2].x;
- float endX = sortedPoints[2].x;
-
- float invslope1 = (float)(sortedPoints[2].x - sortedPoints[0].x) / (float)(sortedPoints[2].y - sortedPoints[0].y);
- float invslope2 = (float)(sortedPoints[2].x - sortedPoints[1].x) / (float)(sortedPoints[2].y - sortedPoints[1].y);
-
- for (int scanlineY = (int)sortedPoints[2].y; scanlineY > sortedPoints[0].y; scanlineY--)
- {
- drawLine(image, (int)startX, scanlineY, (int)endX, scanlineY, false, unsortedPoints, brightness, uvs);
- startX -= invslope1;
- endX -= invslope2;
- }
- return (image);
- }
-
- private byte[,] fillFlatBottom(byte[,] image, Mesh.point3[] sortedPoints, Mesh.point3[] unsortedPoints, byte[] brightness, Mesh.point2[] uvs = null)
- {
- float invslope1 = (float)(sortedPoints[2].x - sortedPoints[0].x) / (float)(sortedPoints[2].y - sortedPoints[0].y);
- float invslope2 = (float)(sortedPoints[0].x - sortedPoints[1].x) / (float)(sortedPoints[0].y - sortedPoints[1].y);
-
- float curx1 = sortedPoints[0].x;
- float curx2 = sortedPoints[0].x;
-
- for (int scanlineY = (int)sortedPoints[0].y; scanlineY <= sortedPoints[1].y; scanlineY++)
- {
- drawLine(image, (int)curx1, scanlineY, (int)curx2, scanlineY, false, unsortedPoints, brightness, uvs);
- curx1 += invslope1;
- curx2 += invslope2;
- }
- return (image);
- }
-
- public byte[,] drawLine(byte[,] image, /*start*/int x0, int y0, int x1, int y1,/*end*/ bool drawWireFrame, Mesh.point3[] unsortedPoints = null, byte[] color = null, Mesh.point2[] uvs = null)
- {
- float rise = y1 - y0;
- float run = x1 - x0;
- byte txl = 219;
- //if (color != null)
- //{
- // color[0] = 0;
- // color[1] = 50;
- // color[2] = 100;
- //}
- if (run == 0)
- {
- if (drawWireFrame)
- txl = 124;// |
-
- if (y0 > y1)
- swap(ref y0, ref y1);
-
- while (y0 < y1)//DRAW
- {
- image[x0, y0] = txl;
- y0++;
- }
- return (image);
- }
-
- float m = rise / run;
-
- if (-1 <= rise / run && rise / run <= 1)
- {
-
- if (drawWireFrame)
- {
- if (rise / run > 0.5)
- txl = 92;// /
- else if (rise / run < -0.5)
- txl = 47;// \
- else
- txl = 95;// -
- }
-
- if (x0 > x1)
- {
- swap(ref x0, ref x1);
- swap(ref y0, ref y1);
- }
-
- float y = y0;
- float x = x0;
- float denom = 0;
- if (!drawWireFrame)
- denom = ((unsortedPoints[1].y - unsortedPoints[2].y) * (unsortedPoints[0].x - unsortedPoints[2].x) + (unsortedPoints[2].x - unsortedPoints[1].x) * (unsortedPoints[0].y - unsortedPoints[2].y));
-
- while (x <= x1 && y < RENDER_HEIGHT && x < RENDER_WIDTH && y >= 0)
- {
- if (x > 0)//clipping logic < ^
- {
- int xtoi = (int)x;
- int ytoi = (int)y;
- if (drawWireFrame)
- {
- image[xtoi, ytoi] = txl;
- y += m;
- }
- else//HERE'S WHERE WE DRAW TRIANGLES!
- {
- float b1 = (((unsortedPoints[1].y - unsortedPoints[2].y) * (x - unsortedPoints[2].x)) + ((unsortedPoints[2].x - unsortedPoints[1].x) * (y - unsortedPoints[2].y))) / denom;
- float b2 = (((unsortedPoints[2].y - unsortedPoints[0].y) * (x - unsortedPoints[2].x)) + ((unsortedPoints[0].x - unsortedPoints[2].x) * (y - unsortedPoints[2].y))) / denom;
- float b3 = 1 - b1 - b2;
-
- int interpolatedZ = (int)(b1 * unsortedPoints[0].z + b2 * unsortedPoints[1].z + b3 * unsortedPoints[2].z);
-
- if (interpolatedZ > zBuffer[xtoi, ytoi])
- { // use barycentric interpolation to do everything..
- float interpU = (float)(b1 * uvs[0].x + b2 * uvs[1].x + b3 * uvs[2].x);
- float interpV = (float)(b1 * uvs[0].y + b2 * uvs[1].y + b3 * uvs[2].y);
- float interpBright = color[1];// + b2 * (float)color[1] + b3 * (float)color[2]);
- Material someMat = someShape.matIDs[targFace.matID-1];
- int xpos = Math.Min(Math.Max((int)(interpU * someMat.SIZE), 0), someMat.SIZE-1);
- int ypos = Math.Min(Math.Max((int)(interpV * someMat.SIZE), 0), someMat.SIZE-1);
-
- byte fa = someMat.bitmapColorsCached[(int)clamp(xpos, 0, someMat.SIZE-1), (int)clamp(ypos, 0, someMat.SIZE-1)];
- image[xtoi, ytoi] = (byte)(Convert.ToInt32(levels[(int)clamp(fa + interpBright, 0, 255)]));
- zBuffer[xtoi, ytoi] = interpolatedZ;
- }
- }
- }
- x++;
- }
- }
- else
- {
- if (run / rise > 0.5)
- txl = 92;// /
- else if (run / rise < -0.5)
- txl = 47;// \
- else
- txl = 124;// -
-
- if (y0 > y1)
- {
- swap(ref x0, ref x1);
- swap(ref y0, ref y1);
- }
-
- float x = x0;
- float invSlope = 1 / m;
-
- while (y0 < y1)
- {
- image[(int)x, y0] = txl;
- x += invSlope;
- y0++;
- }
- }
- return (image);
- }
- }
-}
diff --git a/Render/FrameBuffer.cs b/Render/FrameBuffer.cs
new file mode 100644
index 0000000..f999177
--- /dev/null
+++ b/Render/FrameBuffer.cs
@@ -0,0 +1,78 @@
+using System;
+using System.IO;
+using System.Threading;
+
+namespace ConsoleGraphics.Render
+{
+ ///
+ /// Draws a buffer (an array of bytes) to the console buffer/screen
+ ///
+ public static class FrameBuffer
+ {
+ private static int LastRenderTick;
+ private static int numRenderings = 0;
+ private const short sampleSize = 100;
+ //private string lastFrame = "";
+
+ ///
+ /// STDOUT
+ ///
+ public static Stream ConsoleOutput = Console.OpenStandardOutput();
+
+ // defining it static. saves creating a 30000 byte long array every time the game renders
+ // probably makes the garbage collector happier too lol
+ private static byte[] ViewportBuffer = new byte[Game.RENDER_HEIGHT * Game.RENDER_WIDTH];
+
+ public static void DrawFrame(byte[,] image, int a = 0, int b = 0)
+ {
+ //use cudafy / multithreading to paint quickly, also invoke writetoconsole?
+
+ for (int x = 0; x < Game.RENDER_WIDTH; x++)
+ {
+ for (int y = 0; y < Game.RENDER_HEIGHT; y++)
+ {
+ ViewportBuffer[x + y * Game.RENDER_WIDTH] = image[x, y];
+ }
+ }
+
+ Console.SetCursorPosition(a, b);
+
+ int beginRender = Environment.TickCount;
+ //.Flush();
+ //string iString = bufImg.ToString();
+ //byte[] b = Encoding.UTF8.GetBytes(iString);
+ //if (string.Compare(lastFrame, iString) != 0)
+ //{
+ ConsoleOutput.Write(ViewportBuffer, 0, ViewportBuffer.Length);
+ // lastFrame = iString;
+ //}
+ int endRender = Environment.TickCount - beginRender;
+
+ VerticalSync(Game.MAX_FPS, endRender, beginRender);
+
+ if (numRenderings == 0)
+ LastRenderTick = Environment.TickCount;
+
+ numRenderings++;
+ }
+
+ public static void VerticalSync(short targetFrameRate, int delay, int startDrawTime)
+ {
+ //Synchronize frames and display framerate to the lower right corner of the render window
+ int targetDelay = 1000 / targetFrameRate;
+ //we're too fast
+ if (delay < targetDelay && Game.USE_VSYNC)
+ {
+ Thread.Sleep(targetDelay - delay);
+ }
+
+ if (numRenderings == sampleSize)
+ {
+ int ticksElapsed = Environment.TickCount - LastRenderTick;
+ if (ticksElapsed != 0)
+ Game.printch((sampleSize * 1000 / ticksElapsed).ToString().ToCharArray(), Game.RENDER_WIDTH - 50, Game.RENDER_HEIGHT + 1);
+ numRenderings = 0;
+ }
+ }
+ }
+}
diff --git a/Render/Light.cs b/Render/Light.cs
new file mode 100644
index 0000000..6861d02
--- /dev/null
+++ b/Render/Light.cs
@@ -0,0 +1,16 @@
+using ConsoleGraphics.Maths;
+
+namespace ConsoleGraphics.Render
+{
+ public struct Light
+ {
+ public Vector3 Coordinates;
+ public float Intensity;
+
+ public Light(float x, float y, float z, float intensity)
+ {
+ Coordinates = new Vector3(x, y, z);
+ Intensity = intensity;
+ }
+ }
+}
diff --git a/Render/Material.cs b/Render/Material.cs
new file mode 100644
index 0000000..b6b9d17
--- /dev/null
+++ b/Render/Material.cs
@@ -0,0 +1,27 @@
+using System.Drawing;
+
+namespace ConsoleGraphics.Render
+{
+ //convert textures
+ public class Material
+ {
+ public byte[,] BitmapColorsCached;
+ public int Size;
+
+ public Material(string fileName)
+ {
+ //load character set (digits 1->9..)
+ Bitmap sourceBmp = (Bitmap)Image.FromFile(fileName, true);
+ BitmapColorsCached = new byte[sourceBmp.Width, sourceBmp.Height];
+ Size = sourceBmp.Width;
+ for (int w = 0; w < sourceBmp.Width; w++)
+ {
+ for (int h = 0; h < sourceBmp.Height; h++)
+ {
+ Color c = sourceBmp.GetPixel(w, h);
+ BitmapColorsCached[w, h] = (byte)((c.R + c.B + c.G) / 3);
+ }
+ }
+ }
+ }
+}
diff --git a/Render/Mesh.cs b/Render/Mesh.cs
new file mode 100644
index 0000000..01fb1fe
--- /dev/null
+++ b/Render/Mesh.cs
@@ -0,0 +1,159 @@
+/* Mesh - all the things that define a mesh. triangles, edges, verticies... later UVs...
+ *
+ *
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using ConsoleGraphics.Maths;
+
+namespace ConsoleGraphics.Render
+{
+ public class Mesh
+ {
+ public Vector3[] Vertices;
+ public Triangle[] Faces;
+ public Vector2[] UVs;
+ public Material[] Materials;
+ public int VerticesCount;
+ public int FacesCount;
+
+ public Mesh(Vector3[] meshVerts, Triangle[] meshFaces, Vector2[] meshUvs, Material[] mats = null)
+ {
+ Vertices = meshVerts;
+ VerticesCount = Vertices.Length;
+ Faces = meshFaces;
+ FacesCount = Faces.Length;
+ UVs = meshUvs;
+ Materials = mats;
+ }
+
+ public static Mesh LoadMeshFromFile(string fileName)
+ {
+ StreamReader reader = new StreamReader(fileName);
+ List loadedVerts = new List();
+ List loadedUvs = new List();
+ List loadedFaces = new List();
+ //List loadedUvFaces = new List();
+ List mtls = new List();
+ int vertCount = 0;
+ int faceCount = 0;
+
+ while (!reader.EndOfStream)
+ {
+ string e1 = reader.ReadLine();
+ if (e1 != "")
+ {
+ if (e1[0] == 'v' && e1[1] == 't')//texture verticies
+ {
+ string temp = e1.Substring(3, e1.Length - 3);
+ string[] coords = temp.Split(' ');
+ Vector2 p = new Vector2(float.Parse(coords[0]), float.Parse(coords[1]));
+ loadedUvs.Add(p);
+ }
+ else if (e1[0] == 'v')//vertex
+ {
+ vertCount++;
+ string temp = e1.Substring(3, e1.Length - 3);
+ string[] coords = temp.Split(' ');
+ Vector3 p = new Vector3(float.Parse(coords[0]) * 100, float.Parse(coords[1]) * 100, float.Parse(coords[2]));
+ //if z is positive it's off screen, z=0 we clip
+ loadedVerts.Add(p);
+ }
+ else if (e1[0] == 'u')
+ {//use this mtl for rest of faces faces material
+ Material m = new Material(e1.Substring(7, e1.Length - 7));
+ mtls.Add(m);
+ }
+ else if (e1[0] == 'f')//edge
+ {
+ faceCount++;
+ string temp = e1.Substring(2, e1.Length - 2);
+ string[] coords = temp.Split(' ', '/');
+ Triangle f = new Triangle(int.Parse(coords[0]) - 1, int.Parse(coords[2]) - 1, int.Parse(coords[4]) - 1, /*UV ID's*/ int.Parse(coords[1]) - 1, int.Parse(coords[3]) - 1, int.Parse(coords[5]) - 1, mtls.Count);
+ // Triangle uvf = new Triangle(int.Parse(coords[1]), int.Parse(coords[3]), int.Parse(coords[5]));
+ loadedFaces.Add(f);
+ // loadedUvFaces.Add(uvf);
+ }
+ }
+ }
+ return (new Mesh(loadedVerts.ToArray(), loadedFaces.ToArray(), loadedUvs.ToArray(), mtls.ToArray()));
+ }
+
+ public void Translate(Vector3 translation)
+ {
+ for (int i = 0; i < Vertices.Length; i++)
+ {
+ Vertices[i].Add(translation);
+ }
+ }
+
+ public void Translate(float x, float y, float z)
+ {
+ for (int i = 0; i < Vertices.Length; i++)
+ {
+ Vertices[i].Add(x, y, z);
+ }
+ }
+
+ public void Rotate(double angle, byte dir)
+ {
+ //Rotate about centerpoint of the shape: translate the center of our shape to the origin, rotate, translate back.
+ float cosAngle = (float)Math.Cos(angle);
+ float sinAngle = (float)Math.Sin(angle);
+ Vector3 startCoords = Vertices[0];
+ Translate(new Vector3(-startCoords.X, -startCoords.Y, -startCoords.Z));
+ #region rotations
+ /* Rotate about X Axis {{1,0, 0},
+ {0, cosAngle,sinAngle*100},
+ {0, -sinAngle/100, cosAngle}}, 3, 3);
+
+
+ * Rotate about Y Axis {{cosAngle,0,-sinAngle*100},
+ {0, 1, 0},
+ {sinAngle, 0, cosAngle}}, 3, 3);
+ Rotate about Z axis
+ * {{cosAngle,-sinAngle,0},
+ {sinAngle, cosAngle,0},
+ {0, 0, 1}},3,3);
+ */
+ #endregion
+ int x = Environment.TickCount;
+
+ Matrix rotationMatrix;
+ if (dir == 0)
+ rotationMatrix = new Matrix(
+ new float[,]
+ {
+ {1, 0, 0},
+ {0, cosAngle, sinAngle * 100},
+ {0, -sinAngle / 100, cosAngle}
+ }, 3, 3);
+ else if (dir == 1)
+ rotationMatrix = new Matrix(
+ new float[,]
+ {
+ {cosAngle, 0, -sinAngle * 100},
+ {0, 1, 0},
+ {sinAngle / 100, 0, cosAngle}
+ }, 3, 3);
+ else
+ rotationMatrix = new Matrix(
+ new float[,]
+ {
+ {cosAngle, -sinAngle, 0},
+ {sinAngle, cosAngle, 0},
+ {0, 0, 1}
+ }, 3, 3);
+
+ x = Environment.TickCount - x;
+
+ for (int i = 0; i < VerticesCount; i++)
+ {
+ Vertices[i] = rotationMatrix.Multiply(Vertices[i]);
+ }
+
+ Translate(new Vector3(startCoords.X, startCoords.Y, startCoords.Z));
+ }
+ }
+}
diff --git a/Render/Rasterize.cs b/Render/Rasterize.cs
new file mode 100644
index 0000000..8e543b2
--- /dev/null
+++ b/Render/Rasterize.cs
@@ -0,0 +1,379 @@
+/* Rasterization - all the grunt work!
+ * Determine pixle 'colors'..
+ */
+
+using System;
+using ConsoleGraphics.Maths;
+
+namespace ConsoleGraphics.Render
+{
+ public class Rasterizer
+ {
+ public static int[,] zBuffer = new int[Game.RENDER_WIDTH, Game.RENDER_HEIGHT];
+
+ private static Triangle TargetFace;
+
+ public static byte[,] RenderVertices(Mesh someShape)
+ {
+ byte[,] image = new byte[Game.RENDER_WIDTH, Game.RENDER_HEIGHT];
+
+ for (int x = 0; x < Game.RENDER_WIDTH; x++)
+ for (int y = 0; y < Game.RENDER_HEIGHT; y++)
+ image[x, y] = 32;
+
+ foreach (Triangle f in someShape.Faces)
+ {
+ // each vertex
+ for (int i = 0; i < 3; i++)
+ {
+ double depth = someShape.Vertices[f.VertexIds[i]].Z;
+ int P_x1 = (int)(someShape.Vertices[f.VertexIds[i]].X / depth);
+ int P_y1 = (int)(someShape.Vertices[f.VertexIds[i]].Y / depth);
+
+ //the vert is in bounds with the screen
+ if (P_y1 < Game.RENDER_HEIGHT - 1 && P_y1 >= 0 && P_x1 < Game.RENDER_WIDTH - 1 && P_x1 >= 0)
+ image[P_x1, P_y1] = 177;
+ }
+ }
+ return (image);
+ }
+
+ public static byte[,] RenderWire(Mesh someShape)
+ {
+ byte[,] image = new byte[Game.RENDER_WIDTH, Game.RENDER_HEIGHT];//
+
+ for (int x = 0; x < Game.RENDER_WIDTH; x++)
+ for (int y = 0; y < Game.RENDER_HEIGHT; y++)
+ image[x, y] = 32;
+
+ foreach (Triangle f in someShape.Faces)
+ {
+ for (int i = 0; i < 3; i++)//each vertex
+ {
+ double depth = someShape.Vertices[f.VertexIds[i]].Z;
+ int P_x1 = (int)((Game.RENDER_WIDTH / 2) + someShape.Vertices[f.VertexIds[i]].X / depth);
+ int P_y1 = (int)(((Game.RENDER_HEIGHT - 15) / 2) + someShape.Vertices[f.VertexIds[i]].Y / depth);
+
+ //the vert is in bounds with the screen
+ if (P_y1 < Game.RENDER_HEIGHT - 1 && P_y1 >= 0 && P_x1 < Game.RENDER_WIDTH - 1 && P_x1 >= 0)
+ {
+ //each of the 2 neighboring verts
+ for (int j = 0; j < 2; j++)
+ {
+ double depth2 = someShape.Vertices[f.VertexIds[j]].Z;
+ int P_x = (int)((Game.RENDER_WIDTH / 2) + someShape.Vertices[f.VertexIds[j]].X / depth2);
+ int P_y = (int)(((Game.RENDER_HEIGHT - 15) / 2) + someShape.Vertices[f.VertexIds[j]].Y / depth2);
+
+ if (P_y < Game.RENDER_HEIGHT - 1 && P_y >= 0 && P_x < Game.RENDER_WIDTH - 1 && P_x >= 0)
+ image = DrawLine(image, P_x, P_y, P_x1, P_y1, true);
+ }
+ }
+ }
+ }
+ return (image);
+ }
+
+ public static byte[,] RenderSolid(Mesh someShape)
+ {
+ byte[,] image = new byte[Game.RENDER_WIDTH, Game.RENDER_HEIGHT];
+
+ for (int x = 0; x < Game.RENDER_WIDTH; x++)
+ {
+ for (int y = 0; y < Game.RENDER_HEIGHT; y++)
+ {
+ image[x, y] = 32; //space character is drawn faster than the null character (0)
+ zBuffer[x, y] = -100; //far clipping plane
+ }
+ }
+
+ foreach (Triangle f in someShape.Faces)
+ {
+ TargetFace = f;
+ Vector3 a = Vector3.Add(someShape.Vertices[f.VertexIds[0]], new Vector3(-someShape.Vertices[f.VertexIds[2]].X, -someShape.Vertices[f.VertexIds[2]].Y, -someShape.Vertices[f.VertexIds[2]].Z));
+ Vector3 b = Vector3.Add(someShape.Vertices[f.VertexIds[0]], new Vector3(-someShape.Vertices[f.VertexIds[1]].X, -someShape.Vertices[f.VertexIds[1]].Y, -someShape.Vertices[f.VertexIds[1]].Z));
+ Vector3 surfaceNorm1 = Vector3.Cross(a, b);
+
+ surfaceNorm1 = Vector3.Normalize(surfaceNorm1);
+
+ Vector3 lightNorm1 = Vector3.Add(Game.light1.Coordinates, new Vector3(-someShape.Vertices[f.VertexIds[0]].X, -someShape.Vertices[f.VertexIds[0]].Y, -someShape.Vertices[f.VertexIds[0]].Z));//arbitrary vert
+ lightNorm1 = Vector3.Normalize(lightNorm1);
+ ////////////////////////////////////
+ Vector3 a1 = Vector3.Add(someShape.Vertices[f.VertexIds[1]], new Vector3(-someShape.Vertices[f.VertexIds[2]].X, -someShape.Vertices[f.VertexIds[2]].Y, -someShape.Vertices[f.VertexIds[2]].Z));
+ Vector3 b1 = Vector3.Add(someShape.Vertices[f.VertexIds[1]], new Vector3(-someShape.Vertices[f.VertexIds[0]].X, -someShape.Vertices[f.VertexIds[0]].Y, -someShape.Vertices[f.VertexIds[0]].Z));
+ Vector3 surfaceNorm2 = Vector3.Cross(a1, b1);
+
+ surfaceNorm2 = Vector3.Normalize(surfaceNorm2);
+
+ Vector3 lightNorm2 = Vector3.Add(Game.light1.Coordinates, new Vector3(-someShape.Vertices[f.VertexIds[1]].X, -someShape.Vertices[f.VertexIds[1]].Y, -someShape.Vertices[f.VertexIds[1]].Z));//arbitrary vert
+ lightNorm2 = Vector3.Normalize(lightNorm2);
+ //////////////////////////////////////////////
+ Vector3 a2 = Vector3.Add(someShape.Vertices[f.VertexIds[2]], new Vector3(-someShape.Vertices[f.VertexIds[0]].X, -someShape.Vertices[f.VertexIds[0]].Y, -someShape.Vertices[f.VertexIds[0]].Z));
+ Vector3 b2 = Vector3.Add(someShape.Vertices[f.VertexIds[2]], new Vector3(-someShape.Vertices[f.VertexIds[1]].X, -someShape.Vertices[f.VertexIds[1]].Y, -someShape.Vertices[f.VertexIds[1]].Z));
+ Vector3 surfaceNorm3 = Vector3.Cross(a2, b2);
+
+ surfaceNorm3 = Vector3.Normalize(surfaceNorm3);
+
+ Vector3 lightNorm3 = Vector3.Add(Game.light1.Coordinates, new Vector3(-someShape.Vertices[f.VertexIds[2]].X, -someShape.Vertices[f.VertexIds[2]].Y, -someShape.Vertices[f.VertexIds[2]].Z));//arbitrary vert
+ lightNorm3 = Vector3.Normalize(lightNorm3);
+ ////////////////////////////////////////////
+
+ //perspective projection
+ float[] depth = {someShape.Vertices[f.VertexIds[0]].Z,
+ someShape.Vertices[f.VertexIds[1]].Z,
+ someShape.Vertices[f.VertexIds[2]].Z};
+
+ if (depth[0] < 0 && depth[1] < 0 && depth[2] < 0)
+ { //>= one vertex is in screen
+ int x0 = (int)((Game.RENDER_WIDTH / 2) + someShape.Vertices[f.VertexIds[0]].X / depth[0]);
+ int y0 = (int)(((Game.RENDER_HEIGHT - 15) / 2) + someShape.Vertices[f.VertexIds[0]].Y / depth[0]);
+
+ int x1 = (int)((Game.RENDER_WIDTH / 2) + someShape.Vertices[f.VertexIds[1]].X / depth[1]);
+ int y1 = (int)(((Game.RENDER_HEIGHT - 15) / 2) + someShape.Vertices[f.VertexIds[1]].Y / depth[1]);
+
+ int x2 = (int)((Game.RENDER_WIDTH / 2) + someShape.Vertices[f.VertexIds[2]].X / depth[2]);
+ int y2 = (int)(((Game.RENDER_HEIGHT - 15) / 2) + someShape.Vertices[f.VertexIds[2]].Y / depth[2]);
+
+
+ Vector2[] uvs = new Vector2[]
+ {
+ someShape.UVs[f.UVIds[0]],
+ someShape.UVs[f.UVIds[1]],
+ someShape.UVs[f.UVIds[2]]
+ };
+
+ Vector3[] projPoints = new Vector3[]
+ {
+ new Vector3(x0, y0, depth[0]),
+ new Vector3(x1, y1, depth[1]),
+ new Vector3(x2, y2, depth[2])
+ };
+
+ byte[] colors = new byte[]
+ {
+ (byte)(Game.light1.Intensity * Math.Max(0, Vector3.Dot(surfaceNorm1, lightNorm1))),
+ (byte)(Game.light1.Intensity * Math.Max(0, Vector3.Dot(surfaceNorm2, lightNorm2))),
+ (byte)(Game.light1.Intensity * Math.Max(0, Vector3.Dot(surfaceNorm3, lightNorm3)))
+ };
+
+ image = DrawTriangle(image, projPoints, uvs, colors);
+ }
+ }
+ return image;
+ }
+
+ private static byte[,] DrawTriangle(byte[,] image, Vector3[] points, Vector2[] uvs, byte[] brightness = null)
+ {
+ /*
+ * A
+ * B-------
+ * C
+ *
+ */
+ //sort by lowest y value (highest on screen)
+ Vector3[] unsortedPoints = new Vector3[3];
+ points.CopyTo(unsortedPoints, 0);
+
+ if (points[1].Y < points[0].Y)
+ {//swap point[1] and point[0]
+ MathHelper.Swap(ref points[0].Y, ref points[1].Y);
+ MathHelper.Swap(ref points[0].X, ref points[1].X);
+ }
+ if (points[2].Y < points[0].Y)
+ {//swap point[0] and point[2]
+ MathHelper.Swap(ref points[0].Y, ref points[2].Y);
+ MathHelper.Swap(ref points[0].X, ref points[2].X);
+ }
+ if (points[2].Y < points[1].Y)
+ {//swap point[1] & point[2]
+ MathHelper.Swap(ref points[1].Y, ref points[2].Y);
+ MathHelper.Swap(ref points[1].X, ref points[2].X);
+ }
+
+ if (points[0].Y == points[1].Y)
+ {//flat top
+ image = FillFlatTop(image, points, unsortedPoints, brightness, uvs);
+ }
+ else if (points[1].Y == points[2].Y)
+ {//flat bottom
+ image = FillFlatBottom(image, points, unsortedPoints, brightness, uvs);
+ }
+ else
+ {//nontrivial
+ Vector3 midpoint = new Vector3((int)(Math.Ceiling(points[0].X + ((float)(points[1].Y - points[0].Y) / (float)(points[2].Y - points[0].Y)) * (points[2].X - points[0].X))), points[1].Y);
+ FillFlatBottom(image, new Vector3[] { points[0], points[1], midpoint }, unsortedPoints, brightness, uvs);
+ FillFlatTop(image, new Vector3[] { points[1], midpoint, points[2] }, unsortedPoints, brightness, uvs);
+ }
+ return (image);
+ }
+
+ private static byte[,] FillFlatTop(byte[,] image, Vector3[] sortedPoints, Vector3[] unsortedPoints, byte[] brightness, Vector2[] uvs = null)
+ {
+ float startX = sortedPoints[2].X;
+ float endX = sortedPoints[2].X;
+
+ float invslope1 = (float)(sortedPoints[2].X - sortedPoints[0].X) / (float)(sortedPoints[2].Y - sortedPoints[0].Y);
+ float invslope2 = (float)(sortedPoints[2].X - sortedPoints[1].X) / (float)(sortedPoints[2].Y - sortedPoints[1].Y);
+
+ for (int scanlineY = (int)sortedPoints[2].Y; scanlineY > sortedPoints[0].Y; scanlineY--)
+ {
+ DrawLine(image, (int)startX, scanlineY, (int)endX, scanlineY, false, unsortedPoints, brightness, uvs);
+ startX -= invslope1;
+ endX -= invslope2;
+ }
+ return (image);
+ }
+
+ private static byte[,] FillFlatBottom(
+ byte[,] image,
+ Vector3[] sortedPoints,
+ Vector3[] unsortedPoints,
+ byte[] brightness,
+ Vector2[] uvs = null)
+ {
+ float invslope1 = (float)(sortedPoints[2].X - sortedPoints[0].X) / (float)(sortedPoints[2].Y - sortedPoints[0].Y);
+ float invslope2 = (float)(sortedPoints[0].X - sortedPoints[1].X) / (float)(sortedPoints[0].Y - sortedPoints[1].Y);
+
+ float curx1 = sortedPoints[0].X;
+ float curx2 = sortedPoints[0].X;
+
+ for (int scanlineY = (int)sortedPoints[0].Y; scanlineY <= sortedPoints[1].Y; scanlineY++)
+ {
+ DrawLine(image, (int)curx1, scanlineY, (int)curx2, scanlineY, false, unsortedPoints, brightness, uvs);
+ curx1 += invslope1;
+ curx2 += invslope2;
+ }
+ return (image);
+ }
+
+ public static byte[,] DrawLine(
+ byte[,] image,
+ // start
+ int x0, int y0,
+ int x1, int y1,
+ // end
+ bool drawWireFrame,
+ Vector3[] unsortedPoints = null,
+ byte[] color = null,
+ Vector2[] uvs = null)
+ {
+ float rise = y1 - y0;
+ float run = x1 - x0;
+ byte txl = 219;
+ //if (color != null)
+ //{
+ // color[0] = 0;
+ // color[1] = 50;
+ // color[2] = 100;
+ //}
+ if (run == 0)
+ {
+ if (drawWireFrame)
+ txl = 124;// |
+
+ if (y0 > y1)
+ MathHelper.Swap(ref y0, ref y1);
+
+ while (y0 < y1)//DRAW
+ {
+ image[x0, y0] = txl;
+ y0++;
+ }
+ return (image);
+ }
+
+ float m = rise / run;
+
+ if (-1 <= rise / run && rise / run <= 1)
+ {
+
+ if (drawWireFrame)
+ {
+ if (rise / run > 0.5)
+ txl = 92;// /
+ else if (rise / run < -0.5)
+ txl = 47;// \
+ else
+ txl = 95;// -
+ }
+
+ if (x0 > x1)
+ {
+ MathHelper.Swap(ref x0, ref x1);
+ MathHelper.Swap(ref y0, ref y1);
+ }
+
+ float y = y0;
+ float x = x0;
+ float denom = 0;
+ if (!drawWireFrame)
+ denom = ((unsortedPoints[1].Y - unsortedPoints[2].Y) * (unsortedPoints[0].X - unsortedPoints[2].X) + (unsortedPoints[2].X - unsortedPoints[1].X) * (unsortedPoints[0].Y - unsortedPoints[2].Y));
+
+ while (x <= x1 && y < Game.RENDER_HEIGHT && x < Game.RENDER_WIDTH && y >= 0)
+ {
+ if (x > 0)//clipping logic < ^
+ {
+ int xtoi = (int)x;
+ int ytoi = (int)y;
+ if (drawWireFrame)
+ {
+ image[xtoi, ytoi] = txl;
+ y += m;
+ }
+ else
+ {
+ //HERE'S WHERE WE DRAW TRIANGLES!
+ float b1 = (((unsortedPoints[1].Y - unsortedPoints[2].Y) * (x - unsortedPoints[2].X)) + ((unsortedPoints[2].X - unsortedPoints[1].X) * (y - unsortedPoints[2].Y))) / denom;
+ float b2 = (((unsortedPoints[2].Y - unsortedPoints[0].Y) * (x - unsortedPoints[2].X)) + ((unsortedPoints[0].X - unsortedPoints[2].X) * (y - unsortedPoints[2].Y))) / denom;
+ float b3 = 1 - b1 - b2;
+
+ int interpolatedZ = (int)(b1 * unsortedPoints[0].Z + b2 * unsortedPoints[1].Z + b3 * unsortedPoints[2].Z);
+
+ if (interpolatedZ > zBuffer[xtoi, ytoi])
+ {
+ // use barycentric interpolation to do everything..
+ float interpU = (float)(b1 * uvs[0].X + b2 * uvs[1].X + b3 * uvs[2].X);
+ float interpV = (float)(b1 * uvs[0].Y + b2 * uvs[1].Y + b3 * uvs[2].Y);
+ float interpBright = color[1];// + b2 * (float)color[1] + b3 * (float)color[2]);
+ Material material = Game.ActiveMesh.Materials[TargetFace.MaterialId - 1];
+
+ int xpos = Math.Min(Math.Max((int)(interpU * material.Size), 0), material.Size - 1);
+ int ypos = Math.Min(Math.Max((int)(interpV * material.Size), 0), material.Size - 1);
+
+ byte fa = material.BitmapColorsCached[(int)MathHelper.Clamp(xpos, 0, material.Size - 1), (int)MathHelper.Clamp(ypos, 0, material.Size - 1)];
+ image[xtoi, ytoi] = (byte)(Convert.ToInt32(Game.levels[(int)MathHelper.Clamp(fa + interpBright, 0, 255)]));
+ zBuffer[xtoi, ytoi] = interpolatedZ;
+ }
+ }
+ }
+ x++;
+ }
+ }
+ else
+ {
+ if (run / rise > 0.5)
+ txl = 92;// /
+ else if (run / rise < -0.5)
+ txl = 47;// \
+ else
+ txl = 124;// -
+
+ if (y0 > y1)
+ {
+ MathHelper.Swap(ref x0, ref x1);
+ MathHelper.Swap(ref y0, ref y1);
+ }
+
+ float x = x0;
+ float invSlope = 1 / m;
+
+ while (y0 < y1)
+ {
+ image[(int)x, y0] = txl;
+ x += invSlope;
+ y0++;
+ }
+ }
+ return (image);
+ }
+ }
+}
diff --git a/Resources/Meshes/link.obj b/Resources/Meshes/link.obj
new file mode 100644
index 0000000..4b1ace9
--- /dev/null
+++ b/Resources/Meshes/link.obj
@@ -0,0 +1,1340 @@
+# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
+# File Created: 10.01.2015 11:09:19
+
+#
+# object Regroup24
+#
+
+v 0.6500 3.7043 0.1008
+v 0.5093 3.7324 0.2711
+v 0.4631 3.6402 0.3538
+v 0.2454 3.3350 0.1493
+v 0.2538 3.2557 0.5010
+v 0.0148 3.2065 0.3867
+v -0.3575 3.4402 0.1700
+v -0.3551 3.3859 0.4216
+v -0.3724 3.5410 0.4660
+v -0.2984 3.3805 0.6717
+v -0.2391 3.2557 0.5010
+v -0.1771 3.2376 0.6692
+v -0.2266 3.3350 0.1493
+v 0.0001 3.1298 0.6558
+v -0.2525 3.5116 0.7146
+v -0.2625 3.6870 0.7385
+v 0.0001 3.5293 0.7754
+v -0.3898 3.7002 0.5074
+v -0.0835 3.3643 0.7914
+v 0.0001 3.4326 0.9066
+v -0.4437 3.6402 0.3538
+v 0.1952 3.2370 0.6694
+v 0.1006 3.3640 0.7910
+v 0.0001 3.7097 0.7920
+v -0.0313 3.8689 0.7830
+v -0.1495 3.9362 0.7218
+v 0.3140 3.3805 0.6717
+v 0.2685 3.5107 0.7154
+v 0.1156 3.9497 0.7369
+v 0.2803 3.6862 0.7394
+v 0.4182 3.7002 0.5074
+v 0.3888 3.5409 0.4666
+v 0.3718 3.3859 0.4216
+v -0.6353 3.7054 0.1015
+v -0.4942 3.7324 0.2711
+v -0.0994 3.3517 0.0201
+v 0.3725 3.4400 0.1705
+v 0.1283 3.3524 0.0219
+v -0.0985 3.2386 -0.0081
+v 0.1320 3.2386 -0.0081
+v 0.1972 3.1373 0.1448
+v 0.0001 3.0061 0.3165
+v -0.1777 3.1373 0.1448
+v 0.1438 2.1895 0.2657
+v 0.0001 2.2184 -0.2293
+v -0.1670 2.1887 0.2638
+v 0.4045 1.9710 0.0343
+v 0.3971 2.2023 0.0498
+v -0.1690 1.8902 0.2460
+v -0.4167 2.1994 0.0479
+v -0.4228 1.9710 0.0343
+v 0.1470 1.8902 0.2460
+v 0.0001 1.9902 -0.2582
+v -0.0305 4.1649 0.7574
+v 0.0065 4.2353 1.0055
+v 0.0395 4.2251 0.6670
+v 0.2261 3.9369 1.0735
+v 0.3460 4.1908 0.7374
+v 0.5075 3.8941 0.7437
+v 0.5150 3.5445 0.7498
+v 0.2975 3.6246 0.9042
+v 0.4138 4.0891 0.5413
+v -0.4365 3.5391 0.7632
+v -0.5406 3.8380 0.6363
+v -0.3481 3.6452 0.8526
+v -0.2905 3.9799 1.0519
+v -0.0996 4.2112 1.0295
+v -0.1185 4.2251 0.6670
+v -0.4369 4.1037 0.6108
+v 0.0091 3.3358 -0.1591
+v 0.3366 3.4630 0.0013
+v -0.3206 3.4640 -0.0009
+v 0.1944 3.0332 0.2829
+v -0.2425 3.2223 -0.0503
+v -0.2006 3.0332 0.2829
+v 0.0001 2.8189 0.4559
+v 0.2211 3.2223 -0.0503
+v 0.0001 3.2593 0.7577
+v 0.3546 2.9628 0.4124
+v 0.2646 3.3363 -0.0869
+v -0.3615 2.9628 0.4127
+v -0.2473 3.3363 -0.1090
+v 0.0001 4.4341 0.3208
+v -0.2971 4.3602 0.1926
+v 0.0001 4.4821 -0.1856
+v 0.3144 4.3602 0.1926
+v 0.4781 4.2168 -0.1794
+v -0.4619 4.2168 -0.1794
+v -0.4527 3.7130 -0.1694
+v 0.4696 3.7116 -0.1661
+v -0.5317 3.0904 0.1047
+v -0.5577 3.0459 -0.1571
+v -0.5683 2.8166 -0.1824
+v -0.2924 2.4178 -0.3895
+v -0.6009 2.3787 -0.1960
+v 0.5605 2.8166 -0.1824
+v 0.5923 2.3787 -0.1960
+v 0.2824 2.4178 -0.3895
+v 0.0001 2.5555 0.5125
+v -0.3173 2.1172 0.4856
+v 0.3073 2.1172 0.4856
+v 0.6261 2.7180 0.0008
+v 0.5652 2.7107 0.3069
+v 0.5825 2.3508 0.1888
+v -0.2834 3.0914 -0.1868
+v -0.5899 2.3508 0.1888
+v -0.4289 1.9806 0.2741
+v 0.4181 1.9806 0.2741
+v -0.5652 2.7107 0.3070
+v -0.5382 2.9454 0.2761
+v 0.5384 2.9454 0.2762
+v -0.6335 2.7180 0.0008
+v 0.5320 3.0904 0.1047
+v 0.0001 1.9957 -0.0645
+v 0.4173 2.1454 -0.3814
+v -0.4298 2.1454 -0.3814
+v 0.2749 3.0914 -0.1868
+v 0.5575 3.0459 -0.1571
+v -0.5964 2.6538 -0.1795
+v -0.5850 2.4241 -0.0510
+v 0.5964 2.6538 -0.1803
+v 0.5851 2.4243 -0.0538
+v -0.3823 3.5667 -0.4784
+v 0.3903 3.5667 -0.4784
+v 0.2851 3.7159 -0.6525
+v 0.2905 3.5394 -0.0945
+v -0.2806 3.7159 -0.6525
+v 0.0001 3.7098 -0.8376
+v -0.2836 3.5394 -0.0945
+v 0.2970 3.2345 -0.5518
+v 0.0114 3.2172 -0.3064
+v -0.2717 3.2345 -0.5518
+v 0.0001 2.8602 -0.5945
+v 0.0088 3.2931 -0.8176
+v -0.4272 1.9463 -0.1506
+v 0.4116 1.9463 -0.1510
+v -0.3998 1.8717 0.1756
+v -0.3223 1.9184 -0.2891
+v 0.6075 1.1533 -0.1356
+v 0.6252 1.6673 -0.0918
+v 0.7651 1.2474 0.0888
+v 0.4753 1.8045 0.1205
+v 0.4442 1.3427 0.5996
+v 0.6779 1.3491 0.4073
+v 0.2949 1.1058 -0.2049
+v 0.4742 1.5854 -0.2767
+v 0.2592 1.5098 -0.3445
+v 0.2364 1.3125 0.6031
+v 0.1564 1.8345 0.2917
+v 0.0349 1.6952 0.3177
+v 0.0001 1.3786 0.2859
+v 0.0001 1.3434 -0.5335
+v 0.3860 1.8717 0.1756
+v 0.5543 1.8395 0.0233
+v 0.0352 1.7029 -0.4445
+v 0.3076 1.9184 -0.2891
+v 0.0414 1.8419 -0.3975
+v -0.7843 1.2474 0.0888
+v -0.4711 1.5854 -0.2767
+v -0.6101 1.1533 -0.1356
+v -0.4981 1.3427 0.5996
+v -0.5002 1.8045 0.1205
+v -0.7192 1.3491 0.4073
+v -0.2504 1.5098 -0.3445
+v -0.2936 1.1061 -0.2060
+v -0.6351 1.6673 -0.0918
+v -0.2905 1.3125 0.6031
+v -0.1699 1.8345 0.2919
+v -0.0462 1.6944 0.3146
+v -0.5683 1.8395 0.0233
+v -0.0511 1.7029 -0.4445
+v -0.0574 1.8419 -0.3975
+v 0.3669 0.5949 0.4079
+v 0.1074 0.7729 0.0465
+v 0.2581 0.3109 -0.0222
+v 0.2503 0.3707 -0.2076
+v 0.3183 0.8381 -0.2049
+v 0.5227 0.4206 -0.2834
+v 0.6660 0.6512 0.3267
+v 0.3568 0.7591 0.3005
+v 0.5643 0.7974 0.2441
+v 0.6560 0.8763 -0.0878
+v 0.6474 0.3841 -0.1308
+v 0.5029 0.2752 0.0655
+v 0.2171 0.8500 0.0713
+v 0.3398 0.9269 -0.0631
+v 0.5643 0.9154 -0.0161
+v 0.4760 0.0149 -0.3733
+v 0.1870 0.0143 0.0759
+v 0.3252 0.1550 0.3433
+v 0.5876 0.2785 0.2208
+v 0.2116 0.0173 -0.2542
+v 0.7396 0.0115 -0.1727
+v 0.8469 0.1524 0.1097
+v 0.5773 0.0071 0.5454
+v 0.2939 0.0107 0.3538
+v 0.8757 0.0076 0.0919
+v 0.6789 0.1808 0.4272
+v 0.8312 0.0059 0.4311
+v 0.3511 0.9560 0.3969
+v 0.5533 0.9947 0.3415
+v 0.3175 1.1236 -0.0066
+v 0.5645 1.1095 0.1034
+v 0.2027 1.0429 0.2015
+v 0.2279 1.0698 0.2428
+v 0.3638 1.0581 0.1120
+v 0.5113 1.2343 0.3911
+v 0.3234 1.1973 0.4439
+v 0.5330 1.1301 0.1580
+v 0.4816 1.4650 -0.0181
+v 0.2363 1.4470 -0.0890
+v 0.1566 1.4343 0.0823
+v 0.5000 1.4371 0.2679
+v 0.2308 1.3887 0.3437
+v 0.8832 2.4410 0.0089
+v 0.8694 2.3330 -0.0968
+v 0.8359 2.4247 -0.1333
+v 0.7617 2.3497 0.2301
+v 0.7375 2.4769 0.1133
+v 0.9566 2.3269 0.1115
+v 0.6206 2.4234 0.0410
+v 0.6278 2.2247 0.1094
+v 0.7246 2.2901 -0.1053
+v 0.7001 2.3592 -0.1351
+v 0.9174 2.1939 -0.0606
+v 0.8454 1.8851 0.1941
+v 0.7173 2.1413 -0.0469
+v 0.9522 1.9197 0.1994
+v 0.7735 1.9567 0.2996
+v 0.9647 2.0000 0.2952
+v 0.8626 2.0135 0.3633
+v 0.7062 2.5424 -0.1761
+v 0.8296 2.5442 0.1063
+v 0.6372 2.6072 0.1816
+v 0.8679 2.5743 -0.0818
+v 1.1037 1.5774 0.3775
+v 0.8769 1.5347 0.5967
+v 0.6960 1.6892 0.4880
+v 1.0247 1.7881 0.6604
+v 0.9322 1.9818 0.5498
+v 1.1546 1.7148 0.3738
+v 1.1061 1.8395 0.2604
+v 0.8877 2.0259 0.3737
+v 0.7540 1.9545 0.3154
+v 0.8576 1.8862 0.1687
+v 0.9167 1.6631 0.3033
+v 0.6549 1.8655 0.4703
+v 0.9761 1.7458 0.1736
+v 0.9915 1.9568 0.2277
+v 0.7793 2.7864 0.1381
+v 0.7598 2.8999 0.1175
+v 0.5384 2.9454 0.2760
+v 0.8153 2.8149 -0.0433
+v 1.0201 2.5364 0.0521
+v -0.8359 2.4247 -0.1333
+v -0.8694 2.3330 -0.0968
+v -0.8832 2.4410 0.0089
+v -0.7375 2.4769 0.1133
+v -0.7617 2.3497 0.2301
+v -0.9566 2.3269 0.1115
+v -0.6278 2.2247 0.1094
+v -0.6206 2.4234 0.0410
+v -0.7001 2.3592 -0.1351
+v -0.7246 2.2901 -0.1053
+v -0.9174 2.1939 -0.0606
+v -0.9522 1.9197 0.1994
+v -0.7173 2.1413 -0.0469
+v -0.8454 1.8851 0.1941
+v -0.7735 1.9567 0.2996
+v -0.9647 2.0000 0.2952
+v -0.8626 2.0135 0.3633
+v -0.7062 2.5424 -0.1761
+v -0.6372 2.6072 0.1816
+v -0.8296 2.5442 0.1063
+v -0.8679 2.5743 -0.0818
+v -0.6960 1.6892 0.4880
+v -0.8769 1.5347 0.5967
+v -1.1037 1.5774 0.3775
+v -1.0247 1.7881 0.6604
+v -0.9322 1.9818 0.5498
+v -1.1061 1.8395 0.2604
+v -1.1546 1.7148 0.3738
+v -0.8877 2.0259 0.3737
+v -0.8576 1.8862 0.1687
+v -0.7540 1.9545 0.3154
+v -0.6549 1.8655 0.4703
+v -0.9167 1.6631 0.3033
+v -0.9761 1.7458 0.1736
+v -0.9915 1.9568 0.2277
+v -0.7598 2.8999 0.1175
+v -0.7793 2.7864 0.1381
+v -0.8153 2.8149 -0.0433
+v -1.0201 2.5364 0.0521
+v -0.2581 0.3109 -0.0222
+v -0.1074 0.7729 0.0465
+v -0.3669 0.5949 0.4079
+v -0.2503 0.3707 -0.2076
+v -0.3183 0.8381 -0.2049
+v -0.5227 0.4206 -0.2834
+v -0.3568 0.7591 0.3005
+v -0.6660 0.6512 0.3267
+v -0.5643 0.7974 0.2441
+v -0.6560 0.8763 -0.0878
+v -0.6474 0.3841 -0.1308
+v -0.5029 0.2752 0.0655
+v -0.3398 0.9269 -0.0631
+v -0.2171 0.8500 0.0713
+v -0.5643 0.9154 -0.0161
+v -0.4760 0.0149 -0.3733
+v -0.1870 0.0143 0.0759
+v -0.5876 0.2785 0.2208
+v -0.3252 0.1550 0.3433
+v -0.2116 0.0173 -0.2542
+v -0.7396 0.0115 -0.1727
+v -0.8469 0.1524 0.1097
+v -0.2939 0.0107 0.3538
+v -0.5773 0.0071 0.5454
+v -0.8757 0.0076 0.0919
+v -0.6789 0.1808 0.4272
+v -0.8312 0.0059 0.4311
+v -0.5533 0.9947 0.3415
+v -0.3511 0.9560 0.3969
+v -0.5645 1.1095 0.1034
+v -0.3175 1.1236 -0.0066
+v -0.2027 1.0429 0.2015
+v -0.3638 1.0581 0.1120
+v -0.2279 1.0698 0.2428
+v -0.5113 1.2343 0.3911
+v -0.3234 1.1973 0.4439
+v -0.5330 1.1301 0.1580
+v -0.4816 1.4650 -0.0181
+v -0.2363 1.4470 -0.0890
+v -0.1566 1.4343 0.0823
+v -0.5000 1.4371 0.2679
+v -0.2308 1.3887 0.3437
+# 335 vertices
+
+vt 0.2135 0.0260 0.0000
+vt 0.2591 0.0428 0.0000
+vt 0.2222 0.0676 0.0000
+vt 0.1124 0.1603 0.0000
+vt 0.0642 0.1761 0.0000
+vt 0.0951 0.2220 0.0000
+vt 0.3095 0.2325 0.0000
+vt 0.2772 0.2438 0.0000
+vt 0.3622 0.2162 0.0000
+vt 0.2576 0.2373 0.0000
+vt 0.1799 0.2519 0.0000
+vt 0.1533 0.2468 0.0000
+vt 0.2235 0.2329 0.0000
+vt 0.0528 0.2394 0.0000
+vt 0.3151 0.2047 0.0000
+vt 0.4101 0.1722 0.0000
+vt 0.2625 0.1615 0.0000
+vt 0.4512 0.1876 0.0000
+vt 0.1970 0.2081 0.0000
+vt 0.2097 0.1811 0.0000
+vt 0.4310 0.2082 0.0000
+vt 0.0654 0.1897 0.0000
+vt 0.1534 0.1797 0.0000
+vt 0.3574 0.1263 0.0000
+vt 0.4512 0.1014 0.0000
+vt 0.5152 0.1062 0.0000
+vt 0.1137 0.1432 0.0000
+vt 0.1924 0.1250 0.0000
+vt 0.4595 0.0628 0.0000
+vt 0.2820 0.0889 0.0000
+vt 0.2590 0.0646 0.0000
+vt 0.1837 0.0996 0.0000
+vt 0.1063 0.1323 0.0000
+vt 0.5156 0.2228 0.0000
+vt 0.4944 0.1969 0.0000
+vt 0.2041 0.2096 0.0000
+vt 0.1379 0.1203 0.0000
+vt 0.1505 0.1745 0.0000
+vt 0.1389 0.2343 0.0000
+vt 0.0845 0.1988 0.0000
+vt 0.0316 0.2012 0.0000
+vt 0.0265 0.2483 0.0000
+vt 0.1201 0.2589 0.0000
+vt 0.8245 0.3764 0.0000
+vt 0.8552 0.3620 0.0000
+vt 0.8515 0.3759 0.0000
+vt 0.8046 0.3199 0.0000
+vt 0.7671 0.3625 0.0000
+vt 0.8032 0.3704 0.0000
+vt 0.7088 0.3112 0.0000
+vt 0.7312 0.3699 0.0000
+vt 0.7296 0.3196 0.0000
+vt 0.8257 0.3108 0.0000
+vt 0.7671 0.3118 0.0000
+vt 0.7104 0.3767 0.0000
+vt 0.7941 0.8715 0.0000
+vt 0.8152 0.8743 0.0000
+vt 0.7814 0.8715 0.0000
+vt 0.8160 0.8556 0.0000
+vt 0.8060 0.8547 0.0000
+vt 0.8423 0.8531 0.0000
+vt 0.7907 0.8603 0.0000
+vt 0.8108 0.8388 0.0000
+vt 0.8341 0.8195 0.0000
+vt 0.8449 0.8323 0.0000
+vt 0.7768 0.8511 0.0000
+vt 0.7868 0.8236 0.0000
+vt 0.7717 0.8262 0.0000
+vt 0.7991 0.8293 0.0000
+vt 0.8044 0.8213 0.0000
+vt 0.7821 0.8149 0.0000
+vt 0.7931 0.8223 0.0000
+vt 0.7682 0.8166 0.0000
+vt 0.8315 0.8149 0.0000
+vt 0.7989 0.8237 0.0000
+vt 0.8328 0.8250 0.0000
+vt 0.7977 0.8469 0.0000
+vt 0.8299 0.8463 0.0000
+vt 0.8102 0.8661 0.0000
+vt 0.8077 0.8496 0.0000
+vt 0.7849 0.8640 0.0000
+vt 0.7730 0.8618 0.0000
+vt 0.7773 0.8412 0.0000
+vt 0.8004 0.8431 0.0000
+vt 0.7773 0.8669 0.0000
+vt 0.8175 0.8526 0.0000
+vt 0.8327 0.8278 0.0000
+vt 0.8955 0.8308 0.0000
+vt 0.7126 0.9067 0.0000
+vt 0.7122 0.9055 0.0000
+vt 0.6562 0.8658 0.0000
+vt 0.7125 0.9010 0.0000
+vt 0.6316 0.8917 0.0000
+vt 0.7138 0.8403 0.0000
+vt 0.6525 0.8642 0.0000
+vt 0.7151 0.8399 0.0000
+vt 0.3771 0.6591 0.0000
+vt 0.4945 0.6355 0.0000
+vt 0.4423 0.7310 0.0000
+vt 0.5454 0.6962 0.0000
+vt 0.5968 0.6356 0.0000
+vt 0.5452 0.7879 0.0000
+vt 0.6480 0.7314 0.0000
+vt 0.7153 0.6600 0.0000
+vt 0.6163 0.0332 0.0000
+vt 0.6640 0.0716 0.0000
+vt 0.5685 0.0716 0.0000
+vt 0.5873 0.2558 0.0000
+vt 0.5703 0.1607 0.0000
+vt 0.5767 0.1372 0.0000
+vt 0.5790 0.1445 0.0000
+vt 0.5685 0.1681 0.0000
+vt 0.5986 0.1305 0.0000
+vt 0.5726 0.1759 0.0000
+vt 0.5985 0.1597 0.0000
+vt 0.5777 0.2146 0.0000
+vt 0.5713 0.1746 0.0000
+vt 0.5984 0.2161 0.0000
+vt 0.5848 0.2442 0.0000
+vt 0.5982 0.2580 0.0000
+vt 0.8853 0.6459 0.0000
+vt 0.8556 0.6355 0.0000
+vt 0.8881 0.6562 0.0000
+vt 0.8883 0.6804 0.0000
+vt 0.8605 0.7261 0.0000
+vt 0.8915 0.7259 0.0000
+vt 0.7747 0.6804 0.0000
+vt 0.7715 0.7259 0.0000
+vt 0.8027 0.7261 0.0000
+vt 0.8316 0.6925 0.0000
+vt 0.8631 0.7384 0.0000
+vt 0.8002 0.7384 0.0000
+vt 0.7682 0.6867 0.0000
+vt 0.7726 0.7205 0.0000
+vt 0.8597 0.6522 0.0000
+vt 0.8906 0.7205 0.0000
+vt 0.8743 0.7572 0.0000
+vt 0.7891 0.7572 0.0000
+vt 0.8860 0.6572 0.0000
+vt 0.7770 0.6572 0.0000
+vt 0.8948 0.6867 0.0000
+vt 0.8316 0.6665 0.0000
+vt 0.8116 0.6480 0.0000
+vt 0.7777 0.6459 0.0000
+vt 0.8514 0.6480 0.0000
+vt 0.8310 0.7629 0.0000
+vt 0.7891 0.7542 0.0000
+vt 0.8743 0.7542 0.0000
+vt 0.8035 0.6522 0.0000
+vt 0.7750 0.6562 0.0000
+vt 0.8089 0.6355 0.0000
+vt 0.9088 0.3283 0.0000
+vt 0.9347 0.3327 0.0000
+vt 0.9121 0.3504 0.0000
+vt 0.9135 0.3216 0.0000
+vt 0.9509 0.3223 0.0000
+vt 0.9443 0.3530 0.0000
+vt 0.9735 0.3592 0.0000
+vt 0.9692 0.3308 0.0000
+vt 0.9684 0.3675 0.0000
+vt 0.9263 0.3658 0.0000
+vt 0.5507 0.8617 0.0000
+vt 0.5279 0.8750 0.0000
+vt 0.5279 0.8465 0.0000
+vt 0.5470 0.8498 0.0000
+vt 0.5470 0.8828 0.0000
+vt 0.5319 0.8403 0.0000
+vt 0.5279 0.8961 0.0000
+vt 0.5496 0.8399 0.0000
+vt 0.5645 0.8636 0.0000
+vt 0.5620 0.8770 0.0000
+vt 0.5742 0.8681 0.0000
+vt 0.5654 0.8482 0.0000
+vt 0.4749 0.8399 0.0000
+vt 0.3867 0.9042 0.0000
+vt 0.4750 0.9042 0.0000
+vt 0.3879 0.8399 0.0000
+vt 0.6367 0.1288 0.0000
+vt 0.5886 0.1338 0.0000
+vt 0.5890 0.1288 0.0000
+vt 0.6846 0.1341 0.0000
+vt 0.6838 0.1286 0.0000
+vt 0.5916 0.1410 0.0000
+vt 0.6180 0.1379 0.0000
+vt 0.6005 0.1390 0.0000
+vt 0.6978 0.2376 0.0000
+vt 0.7052 0.1822 0.0000
+vt 0.7052 0.2450 0.0000
+vt 0.6893 0.1737 0.0000
+vt 0.6623 0.2482 0.0000
+vt 0.6931 0.2461 0.0000
+vt 0.6657 0.2279 0.0000
+vt 0.6966 0.1777 0.0000
+vt 0.6741 0.1748 0.0000
+vt 0.6393 0.2442 0.0000
+vt 0.6584 0.1476 0.0000
+vt 0.6446 0.1649 0.0000
+vt 0.6397 0.2053 0.0000
+vt 0.6394 0.2172 0.0000
+vt 0.6844 0.1441 0.0000
+vt 0.7033 0.1498 0.0000
+vt 0.6445 0.1708 0.0000
+vt 0.6755 0.1425 0.0000
+vt 0.6454 0.1528 0.0000
+vt 0.6875 0.1377 0.0000
+vt 0.5724 0.2532 0.0000
+vt 0.5865 0.1723 0.0000
+vt 0.5844 0.2452 0.0000
+vt 0.6193 0.2589 0.0000
+vt 0.5938 0.1674 0.0000
+vt 0.5889 0.2558 0.0000
+vt 0.6089 0.1691 0.0000
+vt 0.6164 0.2339 0.0000
+vt 0.5744 0.1790 0.0000
+vt 0.6422 0.2545 0.0000
+vt 0.6249 0.1363 0.0000
+vt 0.6428 0.2071 0.0000
+vt 0.6386 0.1578 0.0000
+vt 0.6426 0.2217 0.0000
+vt 0.5802 0.1377 0.0000
+vt 0.6382 0.1650 0.0000
+vt 0.6377 0.1431 0.0000
+vt 0.6080 0.1297 0.0000
+vt 0.5963 0.1236 0.0000
+vt 0.6815 0.1413 0.0000
+vt 0.6543 0.1378 0.0000
+vt 0.6421 0.1506 0.0000
+vt 0.6314 0.1701 0.0000
+vt 0.6307 0.1506 0.0000
+vt 0.7008 0.1472 0.0000
+vt 0.6414 0.1640 0.0000
+vt 0.6319 0.1642 0.0000
+vt 0.6366 0.2080 0.0000
+vt 0.6554 0.1451 0.0000
+vt 0.5723 0.1468 0.0000
+vt 0.6414 0.1701 0.0000
+vt 0.6362 0.2206 0.0000
+vt 0.6177 0.1450 0.0000
+vt 0.6726 0.1392 0.0000
+vt 0.1171 0.8175 0.0000
+vt 0.0996 0.8137 0.0000
+vt 0.1074 0.9276 0.0000
+vt 0.0971 0.9343 0.0000
+vt 0.0895 0.8288 0.0000
+vt 0.1582 0.8282 0.0000
+vt 0.1511 0.9341 0.0000
+vt 0.1676 0.9337 0.0000
+vt 0.1274 0.8172 0.0000
+vt 0.1151 0.8003 0.0000
+vt 0.1286 0.8000 0.0000
+vt 0.1449 0.8111 0.0000
+vt 0.1397 0.9273 0.0000
+vt 0.1232 0.9292 0.0000
+vt 0.0981 0.8030 0.0000
+vt 0.0894 0.8016 0.0000
+vt 0.1581 0.8009 0.0000
+vt 0.1460 0.8016 0.0000
+vt 0.8961 0.2518 0.0000
+vt 0.8864 0.1335 0.0000
+vt 0.8902 0.1363 0.0000
+vt 0.8510 0.2514 0.0000
+vt 0.8561 0.1236 0.0000
+vt 0.8322 0.1284 0.0000
+vt 0.8033 0.2053 0.0000
+vt 0.8046 0.1568 0.0000
+vt 0.8615 0.1271 0.0000
+vt 0.7586 0.2512 0.0000
+vt 0.8033 0.2515 0.0000
+vt 0.7682 0.1938 0.0000
+vt 0.7144 0.9075 0.0000
+vt 0.7152 0.9064 0.0000
+vt 0.7131 0.9080 0.0000
+vt 0.7135 0.9053 0.0000
+vt 0.9034 0.5146 0.0000
+vt 0.9377 0.5020 0.0000
+vt 0.9412 0.5360 0.0000
+vt 0.9496 0.5254 0.0000
+vt 0.9455 0.5426 0.0000
+vt 0.9465 0.5156 0.0000
+vt 0.9546 0.5330 0.0000
+vt 0.9510 0.5622 0.0000
+vt 0.9070 0.5309 0.0000
+vt 0.9021 0.5563 0.0000
+vt 0.9344 0.5805 0.0000
+vt 0.9309 0.5801 0.0000
+vt 0.9057 0.5775 0.0000
+vt 0.9081 0.5372 0.0000
+vt 0.9493 0.5614 0.0000
+vt 0.8939 0.5549 0.0000
+vt 0.9094 0.5780 0.0000
+vt 0.9499 0.5624 0.0000
+vt 0.9433 0.3160 0.0000
+vt 0.9536 0.3109 0.0000
+vt 0.9714 0.3317 0.0000
+vt 0.9377 0.3407 0.0000
+vt 0.9207 0.3279 0.0000
+vt 0.9700 0.3185 0.0000
+vt 0.9081 0.3108 0.0000
+# 298 texture coords
+
+g Regroup24
+usemtl Resources\Textures\YoungLink.bmp
+f 1/1 2/2 3/3
+f 4/4 5/5 6/6
+f 7/7 8/8 9/9
+f 10/10 11/11 12/12
+f 11/11 10/10 8/8
+f 8/8 7/7 11/11
+f 11/11 13/13 6/6
+f 11/11 14/14 12/12
+f 15/15 16/16 9/9
+f 16/16 15/15 17/17
+f 9/9 16/16 18/18
+f 15/15 19/19 17/17
+f 20/20 17/17 19/19
+f 9/9 18/18 21/21
+f 14/14 5/5 22/22
+f 20/20 23/23 17/17
+f 24/24 16/16 17/17
+f 25/25 26/26 24/24
+f 27/27 28/28 23/23
+f 16/16 24/24 26/26
+f 29/29 30/30 31/31
+f 29/29 24/24 30/30
+f 16/16 26/26 18/18
+f 28/28 30/30 17/17
+f 32/32 30/30 28/28
+f 30/30 32/32 31/31
+f 30/30 24/24 17/17
+f 27/27 5/5 33/33
+f 23/23 28/28 17/17
+f 27/27 22/22 5/5
+f 27/27 32/32 28/28
+f 34/34 21/21 35/35
+f 34/34 35/35 7/7
+f 10/10 19/19 15/15
+f 27/27 33/33 32/32
+f 36/36 13/13 7/7
+f 10/10 15/15 9/9
+f 14/14 11/11 6/6
+f 6/6 5/5 14/14
+f 5/5 4/4 37/37
+f 4/4 38/38 37/37
+f 8/8 10/10 9/9
+f 13/13 11/11 7/7
+f 33/33 5/5 37/37
+f 1/1 37/37 2/2
+f 33/33 37/37 32/32
+f 29/29 25/25 24/24
+f 39/39 13/13 36/36
+f 40/40 4/4 41/41
+f 40/40 36/36 38/38
+f 42/42 4/4 6/6
+f 42/42 13/13 43/43
+f 39/39 36/36 40/40
+f 4/4 42/42 41/41
+f 13/13 42/42 6/6
+f 13/13 39/39 43/43
+f 4/4 40/40 38/38
+f 44/44 45/45 46/46
+f 47/47 45/48 48/49
+f 49/50 50/51 51/52
+f 52/53 48/49 44/44
+f 45/48 47/47 53/54
+f 45/48 44/44 48/49
+f 48/49 52/53 47/47
+f 45/48 51/52 50/51
+f 46/55 45/48 50/51
+f 50/51 49/50 46/55
+f 51/52 45/48 53/54
+f 54/56 55/57 56/58
+f 55/57 54/56 25/59
+f 55/57 29/60 57/61
+f 55/57 57/61 58/62
+f 59/63 58/62 57/61
+f 55/57 58/62 56/58
+f 60/64 59/63 61/65
+f 59/63 62/66 58/62
+f 3/67 2/68 31/69
+f 31/69 32/70 3/67
+f 60/64 2/68 59/63
+f 60/64 61/65 29/60
+f 56/58 58/62 62/66
+f 60/64 31/69 2/68
+f 59/63 2/68 62/66
+f 60/64 29/60 31/69
+f 59/63 57/61 61/65
+f 61/65 57/61 29/60
+f 55/57 25/59 29/60
+f 21/71 18/72 35/73
+f 63/74 64/75 35/73
+f 65/76 26/77 66/78
+f 65/76 18/72 26/77
+f 67/79 25/80 54/81
+f 63/74 65/76 64/75
+f 66/78 26/77 67/79
+f 67/79 26/77 25/80
+f 63/74 18/72 65/76
+f 54/81 68/82 67/79
+f 64/75 65/76 66/78
+f 64/75 66/78 69/83
+f 67/79 69/83 66/78
+f 67/79 68/82 69/83
+f 63/74 35/73 18/72
+f 64/75 69/83 35/73
+f 38/84 70/85 71/86
+f 37/87 38/84 71/86
+f 72/86 7/87 35/88
+f 71/86 2/88 37/87
+f 72/86 36/84 7/87
+f 36/84 70/85 38/84
+f 70/85 36/84 72/86
+f 41/89 42/89 73/89
+f 43/89 74/89 75/89
+f 40/89 74/89 39/89
+f 42/89 76/90 73/89
+f 41/89 77/89 40/89
+f 77/89 74/89 40/89
+f 43/89 75/89 42/89
+f 74/89 43/89 39/89
+f 75/89 76/90 42/89
+f 77/89 41/89 73/89
+f 21/91 7/92 9/93
+f 34/94 7/92 21/91
+f 3/95 32/93 37/92
+f 1/96 3/95 37/92
+f 27/97 23/98 22/99
+f 78/100 23/98 19/101
+f 14/102 22/99 78/100
+f 78/100 22/99 23/98
+f 12/103 19/101 10/104
+f 12/103 14/102 78/100
+f 12/103 78/100 19/101
+f 20/105 19/106 23/107
+f 79/108 80/108 77/108
+f 74/108 81/108 75/108
+f 82/108 74/108 77/108
+f 82/108 77/108 80/108
+f 73/108 76/108 79/108
+f 77/108 73/108 79/108
+f 82/108 81/108 74/108
+f 75/108 81/108 76/108
+f 68/109 83/110 84/111
+f 83/110 68/109 56/109
+f 54/112 56/109 68/109
+f 84/111 83/110 85/113
+f 86/111 56/109 62/114
+f 87/115 62/114 2/116
+f 86/111 87/115 85/113
+f 86/111 85/113 83/110
+f 86/111 62/114 87/115
+f 86/111 83/110 56/109
+f 69/117 84/111 88/115
+f 85/113 88/115 84/111
+f 35/116 88/115 89/118
+f 88/115 35/116 69/117
+f 90/118 71/119 70/120
+f 89/118 70/120 72/119
+f 90/118 2/116 71/119
+f 2/116 90/118 87/115
+f 35/116 89/118 72/119
+f 68/109 84/111 69/117
+f 91/121 74/122 92/123
+f 93/124 94/125 95/126
+f 96/127 97/128 98/129
+f 99/130 100/131 101/132
+f 102/133 103/127 104/134
+f 94/125 92/123 105/135
+f 100/131 106/136 107/137
+f 104/134 101/132 108/138
+f 109/124 99/130 110/139
+f 111/140 99/130 103/127
+f 112/141 95/126 106/136
+f 109/124 112/141 106/136
+f 76/142 111/140 73/143
+f 113/144 73/143 111/140
+f 76/142 110/139 99/130
+f 110/139 76/142 75/145
+f 114/146 115/147 108/138
+f 108/138 97/128 104/134
+f 105/135 98/129 94/125
+f 114/146 116/148 115/147
+f 107/137 116/148 114/146
+f 117/149 98/129 105/135
+f 118/150 98/129 117/149
+f 95/126 107/137 106/136
+f 95/126 94/125 116/148
+f 114/146 108/138 107/137
+f 92/123 74/122 105/135
+f 115/147 98/129 97/128
+f 74/122 117/149 105/135
+f 77/151 118/150 117/149
+f 101/132 107/137 108/138
+f 77/151 117/149 74/122
+f 115/147 94/125 98/129
+f 100/131 107/137 101/132
+f 97/128 102/133 104/134
+f 116/148 94/125 115/147
+f 73/143 113/144 77/151
+f 101/132 103/127 99/130
+f 74/122 91/121 75/145
+f 97/128 96/127 102/133
+f 112/141 93/124 95/126
+f 75/145 91/121 110/139
+f 99/130 111/140 76/142
+f 94/125 93/124 92/123
+f 103/127 101/132 104/134
+f 100/131 109/124 106/136
+f 107/137 95/126 116/148
+f 109/124 100/131 99/130
+f 118/150 77/151 113/144
+f 97/128 108/138 115/147
+f 98/129 118/150 96/127
+f 93/152 119/153 92/154
+f 119/153 93/152 112/155
+f 109/152 120/156 112/155
+f 120/156 119/153 112/155
+f 121/157 96/158 118/159
+f 96/158 121/157 102/160
+f 121/157 122/161 102/160
+f 122/161 103/158 102/160
+f 123/162 89/163 88/164
+f 87/164 124/162 125/165
+f 124/162 90/163 126/166
+f 88/164 127/165 123/162
+f 85/167 127/165 88/164
+f 125/165 85/167 87/164
+f 70/168 126/166 90/163
+f 85/167 125/165 128/169
+f 89/163 123/162 129/166
+f 127/165 85/167 128/169
+f 129/166 70/168 89/163
+f 90/163 124/162 87/164
+f 70/168 129/166 126/166
+f 130/170 126/166 131/171
+f 129/166 132/170 131/171
+f 133/172 131/171 132/170
+f 134/173 132/170 127/165
+f 130/170 125/165 124/162
+f 134/173 127/165 128/169
+f 130/170 134/173 125/165
+f 130/170 131/171 133/172
+f 132/170 134/173 133/172
+f 126/166 129/166 131/171
+f 125/165 134/173 128/169
+f 127/165 132/170 123/162
+f 126/166 130/170 124/162
+f 134/173 130/170 133/172
+f 132/170 129/166 123/162
+f 44/174 49/175 52/176
+f 49/175 44/174 46/177
+f 53/178 135/179 51/180
+f 136/181 53/178 47/182
+f 51/180 137/183 49/184
+f 135/179 53/178 138/185
+f 139/186 140/187 141/188
+f 142/189 143/190 144/191
+f 145/192 146/193 139/186
+f 146/193 140/187 139/186
+f 141/188 142/189 144/191
+f 147/194 146/193 145/192
+f 140/187 142/189 141/188
+f 148/195 149/196 150/197
+f 150/197 151/198 148/195
+f 152/199 147/194 145/192
+f 142/189 140/187 153/200
+f 153/200 140/187 154/201
+f 147/194 155/202 156/203
+f 156/203 155/202 157/204
+f 136/205 146/193 156/203
+f 156/203 146/193 147/194
+f 153/200 143/190 142/189
+f 140/187 136/205 154/201
+f 149/196 148/195 143/190
+f 149/196 143/190 153/200
+f 147/194 152/199 155/202
+f 136/205 140/187 146/193
+f 158/206 159/207 160/208
+f 161/209 162/210 163/211
+f 160/208 164/212 165/213
+f 166/214 159/207 158/206
+f 163/211 166/214 158/206
+f 159/207 164/212 160/208
+f 162/210 166/214 163/211
+f 167/215 168/216 161/209
+f 151/217 169/218 167/215
+f 164/212 152/219 165/213
+f 166/214 162/210 170/220
+f 170/220 162/210 137/113
+f 171/221 164/212 172/222
+f 172/222 164/212 138/223
+f 159/207 135/224 164/212
+f 164/212 135/224 138/223
+f 162/210 168/216 137/113
+f 135/224 166/214 170/220
+f 168/216 167/215 169/218
+f 161/209 168/216 162/210
+f 152/219 164/212 171/221
+f 166/214 135/224 159/207
+f 153/225 47/182 52/226
+f 157/227 171/228 172/229
+f 47/182 153/225 154/230
+f 53/178 172/229 138/185
+f 150/231 169/232 151/233
+f 47/182 154/230 136/181
+f 52/226 149/234 153/225
+f 137/183 51/180 170/235
+f 53/178 157/227 172/229
+f 171/228 155/236 152/237
+f 49/184 137/183 168/238
+f 53/178 156/239 157/227
+f 51/180 135/179 170/235
+f 49/184 149/234 52/226
+f 171/228 157/227 155/236
+f 168/238 150/231 149/234
+f 168/238 149/234 49/184
+f 169/232 150/231 168/238
+f 53/178 136/181 156/239
+f 51/180 135/179 53/178
+f 47/182 53/178 136/181
+f 49/184 137/183 51/180
+f 138/185 53/178 135/179
+f 141/188 140/187 139/186
+f 144/191 143/190 142/189
+f 139/186 146/193 145/192
+f 139/186 140/187 146/193
+f 144/191 142/189 141/188
+f 145/192 146/193 147/194
+f 141/188 142/189 140/187
+f 150/197 149/196 148/195
+f 148/195 151/198 150/197
+f 145/192 147/194 152/199
+f 153/200 140/187 142/189
+f 154/201 140/187 153/200
+f 156/203 155/202 147/194
+f 157/204 155/202 156/203
+f 156/203 146/193 136/205
+f 147/194 146/193 156/203
+f 142/189 143/190 153/200
+f 154/201 136/205 140/187
+f 143/190 148/195 149/196
+f 153/200 143/190 149/196
+f 155/202 152/199 147/194
+f 146/193 140/187 136/205
+f 160/208 159/207 158/206
+f 163/211 162/210 161/209
+f 165/213 164/212 160/208
+f 158/206 159/207 166/214
+f 158/206 166/214 163/211
+f 160/208 164/212 159/207
+f 163/211 166/214 162/210
+f 161/209 168/216 167/215
+f 167/215 169/218 151/217
+f 165/213 152/219 164/212
+f 170/220 162/210 166/214
+f 137/113 162/210 170/220
+f 172/222 164/212 171/221
+f 138/223 164/212 172/222
+f 164/212 135/224 159/207
+f 138/223 135/224 164/212
+f 137/113 168/216 162/210
+f 170/220 166/214 135/224
+f 169/218 167/215 168/216
+f 162/210 168/216 161/209
+f 171/221 164/212 152/219
+f 159/207 135/224 166/214
+f 52/226 47/182 153/225
+f 172/229 171/228 157/227
+f 154/230 153/225 47/182
+f 138/185 172/229 53/178
+f 151/233 169/232 150/231
+f 136/181 154/230 47/182
+f 153/225 149/234 52/226
+f 170/235 51/180 137/183
+f 172/229 157/227 53/178
+f 152/237 155/236 171/228
+f 168/238 137/183 49/184
+f 157/227 156/239 53/178
+f 170/235 135/179 51/180
+f 52/226 149/234 49/184
+f 155/236 157/227 171/228
+f 149/234 150/231 168/238
+f 49/184 149/234 168/238
+f 168/238 150/231 169/232
+f 156/239 136/181 53/178
+f 173/240 174/241 175/242
+f 176/243 175/242 174/241
+f 174/241 177/244 176/243
+f 177/245 178/246 176/247
+f 173/240 179/248 180/249
+f 180/249 179/248 181/250
+f 179/248 182/251 181/250
+f 182/251 183/252 178/246
+f 179/248 184/253 183/252
+f 184/253 173/240 175/242
+f 185/254 186/255 177/244
+f 179/248 173/240 184/253
+f 183/252 182/251 179/248
+f 186/256 187/257 177/245
+f 174/241 173/240 180/249
+f 177/245 182/251 178/246
+f 180/249 185/254 174/241
+f 187/257 181/250 182/251
+f 185/254 177/244 174/241
+f 177/245 187/257 182/251
+f 188/258 176/259 178/260
+f 189/261 175/262 176/259
+f 184/263 190/264 191/265
+f 192/258 176/259 188/258
+f 176/259 192/258 189/261
+f 175/262 190/264 184/263
+f 188/258 178/260 193/261
+f 183/266 193/261 178/260
+f 194/264 183/266 191/265
+f 191/265 183/266 184/263
+f 175/262 189/261 190/264
+f 193/261 183/266 194/264
+f 193/261 189/261 188/258
+f 188/258 189/261 192/258
+f 195/267 190/264 196/268
+f 193/261 194/264 197/268
+f 198/269 194/264 191/265
+f 198/269 190/264 195/267
+f 193/261 196/268 189/261
+f 197/268 196/268 193/261
+f 199/267 194/264 198/269
+f 198/269 195/267 199/267
+f 190/264 198/269 191/265
+f 194/264 199/267 197/268
+f 196/268 197/268 195/267
+f 195/267 197/268 199/267
+f 190/264 189/261 196/268
+f 200/270 180/270 201/270
+f 201/270 180/270 181/270
+f 187/271 202/271 203/271
+f 202/271 185/271 204/271
+f 203/271 201/270 181/270
+f 185/271 202/271 186/271
+f 185/271 180/270 204/271
+f 181/270 187/271 203/271
+f 200/270 204/271 180/270
+f 202/271 187/271 186/271
+f 204/271 205/270 206/271
+f 201/270 203/271 207/270
+f 207/270 208/270 201/270
+f 201/270 208/270 200/270
+f 205/270 204/271 208/270
+f 206/271 203/271 202/271
+f 203/271 209/270 207/270
+f 208/270 204/271 200/270
+f 209/270 203/271 206/271
+f 204/271 206/271 202/271
+f 210/89 207/270 209/270
+f 210/89 209/270 211/89
+f 211/89 205/270 212/89
+f 213/270 207/270 210/89
+f 211/89 209/270 206/271
+f 205/270 211/89 206/271
+f 212/89 205/270 214/270
+f 214/270 205/270 208/270
+f 214/270 208/270 213/270
+f 213/270 208/270 207/270
+f 215/89 216/90 217/90
+f 218/272 215/89 219/89
+f 215/89 218/272 220/89
+f 218/272 221/89 222/89
+f 217/90 223/89 224/89
+f 221/89 223/89 222/89
+f 221/89 218/272 219/89
+f 216/90 223/89 217/90
+f 225/273 215/89 220/89
+f 223/89 221/89 224/89
+f 216/90 215/89 225/273
+f 226/271 227/89 228/271
+f 228/271 227/89 225/273
+f 222/89 227/89 229/270
+f 229/270 227/89 226/271
+f 225/273 220/89 228/271
+f 228/271 220/89 230/270
+f 218/272 222/89 231/270
+f 231/270 222/89 229/270
+f 227/89 216/90 225/273
+f 222/89 223/89 227/89
+f 231/270 220/89 218/272
+f 223/89 216/90 227/89
+f 229/270 230/270 231/270
+f 230/270 220/89 231/270
+f 228/271 230/270 226/271
+f 226/271 230/270 229/270
+f 224/273 122/89 232/90
+f 219/89 233/89 234/89
+f 215/89 235/90 233/89
+f 217/273 235/90 215/89
+f 122/89 224/273 221/89
+f 233/89 219/89 215/89
+f 234/89 221/89 219/89
+f 217/273 232/90 235/90
+f 122/89 121/90 232/90
+f 121/90 235/90 232/90
+f 232/90 217/273 224/273
+f 221/89 234/89 122/89
+f 236/274 237/275 238/276
+f 236/274 239/277 237/275
+f 238/278 237/279 239/280
+f 240/281 238/278 239/280
+f 240/281 241/282 242/283
+f 242/283 243/284 240/281
+f 244/285 243/284 245/286
+f 239/277 241/282 240/281
+f 241/282 236/274 242/283
+f 239/277 236/274 241/282
+f 246/287 247/288 245/286
+f 248/289 245/286 242/283
+f 238/276 247/288 246/287
+f 248/289 246/287 245/286
+f 238/276 246/287 236/274
+f 236/274 246/287 248/289
+f 243/284 242/283 249/290
+f 242/283 236/274 248/289
+f 249/290 242/283 245/286
+f 243/284 249/290 245/286
+f 240/281 243/284 247/288
+f 238/278 240/281 247/291
+f 244/285 245/286 247/288
+f 243/284 244/285 247/288
+f 250/292 251/293 252/294
+f 103/158 122/161 234/295
+f 250/292 103/158 233/296
+f 233/296 103/158 234/295
+f 113/297 252/294 251/293
+f 251/293 118/159 113/297
+f 118/159 253/292 121/157
+f 118/159 251/293 253/292
+f 103/158 250/292 252/294
+f 254/298 250/292 233/296
+f 254/298 253/292 250/292
+f 233/296 235/296 254/298
+f 253/292 254/298 235/296
+f 251/293 250/292 253/292
+f 235/296 121/157 253/292
+f 255/90 256/90 257/89
+f 258/89 257/89 259/272
+f 260/89 259/272 257/89
+f 261/89 262/89 259/272
+f 263/89 264/89 255/90
+f 261/89 264/89 262/89
+f 258/89 259/272 262/89
+f 255/90 264/89 256/90
+f 260/89 257/89 265/273
+f 263/89 262/89 264/89
+f 265/273 257/89 256/90
+f 266/271 267/89 268/271
+f 265/273 267/89 266/271
+f 269/270 267/89 261/89
+f 268/271 267/89 269/270
+f 266/271 260/89 265/273
+f 270/270 260/89 266/271
+f 271/270 261/89 259/272
+f 269/270 261/89 271/270
+f 265/273 256/90 267/89
+f 267/89 264/89 261/89
+f 259/272 260/89 271/270
+f 267/89 256/90 264/89
+f 271/270 270/270 269/270
+f 271/270 260/89 270/270
+f 268/271 270/270 266/271
+f 269/270 270/270 268/271
+f 272/90 120/89 263/273
+f 273/89 274/89 258/89
+f 274/89 275/90 257/89
+f 257/89 275/90 255/273
+f 262/89 263/273 120/89
+f 257/89 258/89 274/89
+f 258/89 262/89 273/89
+f 275/90 272/90 255/273
+f 272/90 119/90 120/89
+f 272/90 275/90 119/90
+f 263/273 255/273 272/90
+f 120/89 273/89 262/89
+f 276/276 277/275 278/274
+f 277/275 279/277 278/274
+f 279/280 277/279 276/278
+f 279/280 276/278 280/281
+f 281/283 282/282 280/281
+f 280/281 283/284 281/283
+f 284/286 283/284 285/285
+f 280/281 282/282 279/277
+f 281/283 278/274 282/282
+f 282/282 278/274 279/277
+f 284/286 286/288 287/287
+f 281/283 284/286 288/289
+f 287/287 286/288 276/276
+f 284/286 287/287 288/289
+f 278/274 287/287 276/276
+f 288/289 287/287 278/274
+f 289/290 281/283 283/284
+f 288/289 278/274 281/283
+f 284/286 281/283 289/290
+f 284/286 289/290 283/284
+f 286/288 283/284 280/281
+f 286/291 280/281 276/278
+f 286/288 284/286 285/285
+f 286/288 285/285 283/284
+f 110/294 290/293 291/292
+f 273/295 120/161 109/158
+f 274/296 109/158 291/292
+f 273/295 109/158 274/296
+f 290/293 110/294 91/297
+f 91/297 92/159 290/293
+f 119/157 292/292 92/159
+f 292/292 290/293 92/159
+f 110/294 291/292 109/158
+f 274/296 291/292 293/298
+f 291/292 292/292 293/298
+f 293/298 275/296 274/296
+f 275/296 293/298 292/292
+f 292/292 291/292 290/293
+f 292/292 119/157 275/296
+f 294/242 295/241 296/240
+f 295/241 294/242 297/243
+f 297/243 298/244 295/241
+f 297/247 299/246 298/245
+f 300/249 301/248 296/240
+f 302/250 301/248 300/249
+f 302/250 303/251 301/248
+f 299/246 304/252 303/251
+f 304/252 305/253 301/248
+f 294/242 296/240 305/253
+f 298/244 306/255 307/254
+f 305/253 296/240 301/248
+f 301/248 303/251 304/252
+f 298/245 308/257 306/256
+f 300/249 296/240 295/241
+f 299/246 303/251 298/245
+f 295/241 307/254 300/249
+f 303/251 302/250 308/257
+f 295/241 298/244 307/254
+f 303/251 308/257 298/245
+f 299/260 297/259 309/258
+f 297/259 294/262 310/261
+f 311/265 312/264 305/263
+f 309/258 297/259 313/258
+f 310/261 313/258 297/259
+f 305/263 312/264 294/262
+f 314/261 299/260 309/258
+f 299/260 314/261 304/266
+f 311/265 304/266 315/264
+f 305/263 304/266 311/265
+f 312/264 310/261 294/262
+f 315/264 304/266 314/261
+f 309/258 310/261 314/261
+f 313/258 310/261 309/258
+f 316/268 312/264 317/267
+f 318/268 315/264 314/261
+f 311/265 315/264 319/269
+f 317/267 312/264 319/269
+f 310/261 316/268 314/261
+f 314/261 316/268 318/268
+f 319/269 315/264 320/267
+f 320/267 317/267 319/269
+f 311/265 319/269 312/264
+f 318/268 320/267 315/264
+f 317/267 318/268 316/268
+f 320/267 318/268 317/267
+f 316/268 310/261 312/264
+f 321/270 300/270 322/270
+f 302/270 300/270 321/270
+f 323/271 324/271 308/271
+f 325/271 307/271 324/271
+f 302/270 321/270 323/271
+f 306/271 324/271 307/271
+f 325/271 300/270 307/271
+f 323/271 308/271 302/270
+f 300/270 325/271 322/270
+f 306/271 308/271 324/271
+f 326/271 327/270 325/271
+f 328/270 323/271 321/270
+f 321/270 329/270 328/270
+f 322/270 329/270 321/270
+f 329/270 325/271 327/270
+f 324/271 323/271 326/271
+f 328/270 330/270 323/271
+f 322/270 325/271 329/270
+f 326/271 323/271 330/270
+f 324/271 326/271 325/271
+f 330/270 328/270 331/89
+f 332/89 330/270 331/89
+f 333/89 327/270 332/89
+f 331/89 328/270 334/270
+f 326/271 330/270 332/89
+f 326/271 332/89 327/270
+f 335/270 327/270 333/89
+f 329/270 327/270 335/270
+f 334/270 329/270 335/270
+f 328/270 329/270 334/270
+# 693 faces
diff --git a/YoungLink.bmp b/Resources/Textures/YoungLink.bmp
similarity index 100%
rename from YoungLink.bmp
rename to Resources/Textures/YoungLink.bmp
diff --git a/levels.txt b/Resources/levels.txt
similarity index 100%
rename from levels.txt
rename to Resources/levels.txt
diff --git a/Utils/ThreeState.cs b/Utils/ThreeState.cs
new file mode 100644
index 0000000..ddd511d
--- /dev/null
+++ b/Utils/ThreeState.cs
@@ -0,0 +1,17 @@
+namespace ConsoleGraphics.Utils
+{
+ public struct ThreeState
+ {
+ public byte x;
+
+ public ThreeState(byte initialState)
+ {
+ x = 0;
+ }
+
+ public void changeState()
+ {
+ x = (byte)((x + 1) % 3);
+ }
+ }
+}
diff --git a/csbuild.csproj b/csbuild.csproj
index d2c9584..42aaf39 100644
--- a/csbuild.csproj
+++ b/csbuild.csproj
@@ -42,16 +42,22 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
Always
@@ -62,12 +68,12 @@
-
+
Always
-
+
Always
diff --git a/link.obj b/link.obj
deleted file mode 100644
index ae433c9..0000000
--- a/link.obj
+++ /dev/null
@@ -1,1340 +0,0 @@
-# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
-# File Created: 10.01.2015 11:09:19
-
-#
-# object Regroup24
-#
-
-v 0.6500 3.7043 0.1008
-v 0.5093 3.7324 0.2711
-v 0.4631 3.6402 0.3538
-v 0.2454 3.3350 0.1493
-v 0.2538 3.2557 0.5010
-v 0.0148 3.2065 0.3867
-v -0.3575 3.4402 0.1700
-v -0.3551 3.3859 0.4216
-v -0.3724 3.5410 0.4660
-v -0.2984 3.3805 0.6717
-v -0.2391 3.2557 0.5010
-v -0.1771 3.2376 0.6692
-v -0.2266 3.3350 0.1493
-v 0.0001 3.1298 0.6558
-v -0.2525 3.5116 0.7146
-v -0.2625 3.6870 0.7385
-v 0.0001 3.5293 0.7754
-v -0.3898 3.7002 0.5074
-v -0.0835 3.3643 0.7914
-v 0.0001 3.4326 0.9066
-v -0.4437 3.6402 0.3538
-v 0.1952 3.2370 0.6694
-v 0.1006 3.3640 0.7910
-v 0.0001 3.7097 0.7920
-v -0.0313 3.8689 0.7830
-v -0.1495 3.9362 0.7218
-v 0.3140 3.3805 0.6717
-v 0.2685 3.5107 0.7154
-v 0.1156 3.9497 0.7369
-v 0.2803 3.6862 0.7394
-v 0.4182 3.7002 0.5074
-v 0.3888 3.5409 0.4666
-v 0.3718 3.3859 0.4216
-v -0.6353 3.7054 0.1015
-v -0.4942 3.7324 0.2711
-v -0.0994 3.3517 0.0201
-v 0.3725 3.4400 0.1705
-v 0.1283 3.3524 0.0219
-v -0.0985 3.2386 -0.0081
-v 0.1320 3.2386 -0.0081
-v 0.1972 3.1373 0.1448
-v 0.0001 3.0061 0.3165
-v -0.1777 3.1373 0.1448
-v 0.1438 2.1895 0.2657
-v 0.0001 2.2184 -0.2293
-v -0.1670 2.1887 0.2638
-v 0.4045 1.9710 0.0343
-v 0.3971 2.2023 0.0498
-v -0.1690 1.8902 0.2460
-v -0.4167 2.1994 0.0479
-v -0.4228 1.9710 0.0343
-v 0.1470 1.8902 0.2460
-v 0.0001 1.9902 -0.2582
-v -0.0305 4.1649 0.7574
-v 0.0065 4.2353 1.0055
-v 0.0395 4.2251 0.6670
-v 0.2261 3.9369 1.0735
-v 0.3460 4.1908 0.7374
-v 0.5075 3.8941 0.7437
-v 0.5150 3.5445 0.7498
-v 0.2975 3.6246 0.9042
-v 0.4138 4.0891 0.5413
-v -0.4365 3.5391 0.7632
-v -0.5406 3.8380 0.6363
-v -0.3481 3.6452 0.8526
-v -0.2905 3.9799 1.0519
-v -0.0996 4.2112 1.0295
-v -0.1185 4.2251 0.6670
-v -0.4369 4.1037 0.6108
-v 0.0091 3.3358 -0.1591
-v 0.3366 3.4630 0.0013
-v -0.3206 3.4640 -0.0009
-v 0.1944 3.0332 0.2829
-v -0.2425 3.2223 -0.0503
-v -0.2006 3.0332 0.2829
-v 0.0001 2.8189 0.4559
-v 0.2211 3.2223 -0.0503
-v 0.0001 3.2593 0.7577
-v 0.3546 2.9628 0.4124
-v 0.2646 3.3363 -0.0869
-v -0.3615 2.9628 0.4127
-v -0.2473 3.3363 -0.1090
-v 0.0001 4.4341 0.3208
-v -0.2971 4.3602 0.1926
-v 0.0001 4.4821 -0.1856
-v 0.3144 4.3602 0.1926
-v 0.4781 4.2168 -0.1794
-v -0.4619 4.2168 -0.1794
-v -0.4527 3.7130 -0.1694
-v 0.4696 3.7116 -0.1661
-v -0.5317 3.0904 0.1047
-v -0.5577 3.0459 -0.1571
-v -0.5683 2.8166 -0.1824
-v -0.2924 2.4178 -0.3895
-v -0.6009 2.3787 -0.1960
-v 0.5605 2.8166 -0.1824
-v 0.5923 2.3787 -0.1960
-v 0.2824 2.4178 -0.3895
-v 0.0001 2.5555 0.5125
-v -0.3173 2.1172 0.4856
-v 0.3073 2.1172 0.4856
-v 0.6261 2.7180 0.0008
-v 0.5652 2.7107 0.3069
-v 0.5825 2.3508 0.1888
-v -0.2834 3.0914 -0.1868
-v -0.5899 2.3508 0.1888
-v -0.4289 1.9806 0.2741
-v 0.4181 1.9806 0.2741
-v -0.5652 2.7107 0.3070
-v -0.5382 2.9454 0.2761
-v 0.5384 2.9454 0.2762
-v -0.6335 2.7180 0.0008
-v 0.5320 3.0904 0.1047
-v 0.0001 1.9957 -0.0645
-v 0.4173 2.1454 -0.3814
-v -0.4298 2.1454 -0.3814
-v 0.2749 3.0914 -0.1868
-v 0.5575 3.0459 -0.1571
-v -0.5964 2.6538 -0.1795
-v -0.5850 2.4241 -0.0510
-v 0.5964 2.6538 -0.1803
-v 0.5851 2.4243 -0.0538
-v -0.3823 3.5667 -0.4784
-v 0.3903 3.5667 -0.4784
-v 0.2851 3.7159 -0.6525
-v 0.2905 3.5394 -0.0945
-v -0.2806 3.7159 -0.6525
-v 0.0001 3.7098 -0.8376
-v -0.2836 3.5394 -0.0945
-v 0.2970 3.2345 -0.5518
-v 0.0114 3.2172 -0.3064
-v -0.2717 3.2345 -0.5518
-v 0.0001 2.8602 -0.5945
-v 0.0088 3.2931 -0.8176
-v -0.4272 1.9463 -0.1506
-v 0.4116 1.9463 -0.1510
-v -0.3998 1.8717 0.1756
-v -0.3223 1.9184 -0.2891
-v 0.6075 1.1533 -0.1356
-v 0.6252 1.6673 -0.0918
-v 0.7651 1.2474 0.0888
-v 0.4753 1.8045 0.1205
-v 0.4442 1.3427 0.5996
-v 0.6779 1.3491 0.4073
-v 0.2949 1.1058 -0.2049
-v 0.4742 1.5854 -0.2767
-v 0.2592 1.5098 -0.3445
-v 0.2364 1.3125 0.6031
-v 0.1564 1.8345 0.2917
-v 0.0349 1.6952 0.3177
-v 0.0001 1.3786 0.2859
-v 0.0001 1.3434 -0.5335
-v 0.3860 1.8717 0.1756
-v 0.5543 1.8395 0.0233
-v 0.0352 1.7029 -0.4445
-v 0.3076 1.9184 -0.2891
-v 0.0414 1.8419 -0.3975
-v -0.7843 1.2474 0.0888
-v -0.4711 1.5854 -0.2767
-v -0.6101 1.1533 -0.1356
-v -0.4981 1.3427 0.5996
-v -0.5002 1.8045 0.1205
-v -0.7192 1.3491 0.4073
-v -0.2504 1.5098 -0.3445
-v -0.2936 1.1061 -0.2060
-v -0.6351 1.6673 -0.0918
-v -0.2905 1.3125 0.6031
-v -0.1699 1.8345 0.2919
-v -0.0462 1.6944 0.3146
-v -0.5683 1.8395 0.0233
-v -0.0511 1.7029 -0.4445
-v -0.0574 1.8419 -0.3975
-v 0.3669 0.5949 0.4079
-v 0.1074 0.7729 0.0465
-v 0.2581 0.3109 -0.0222
-v 0.2503 0.3707 -0.2076
-v 0.3183 0.8381 -0.2049
-v 0.5227 0.4206 -0.2834
-v 0.6660 0.6512 0.3267
-v 0.3568 0.7591 0.3005
-v 0.5643 0.7974 0.2441
-v 0.6560 0.8763 -0.0878
-v 0.6474 0.3841 -0.1308
-v 0.5029 0.2752 0.0655
-v 0.2171 0.8500 0.0713
-v 0.3398 0.9269 -0.0631
-v 0.5643 0.9154 -0.0161
-v 0.4760 0.0149 -0.3733
-v 0.1870 0.0143 0.0759
-v 0.3252 0.1550 0.3433
-v 0.5876 0.2785 0.2208
-v 0.2116 0.0173 -0.2542
-v 0.7396 0.0115 -0.1727
-v 0.8469 0.1524 0.1097
-v 0.5773 0.0071 0.5454
-v 0.2939 0.0107 0.3538
-v 0.8757 0.0076 0.0919
-v 0.6789 0.1808 0.4272
-v 0.8312 0.0059 0.4311
-v 0.3511 0.9560 0.3969
-v 0.5533 0.9947 0.3415
-v 0.3175 1.1236 -0.0066
-v 0.5645 1.1095 0.1034
-v 0.2027 1.0429 0.2015
-v 0.2279 1.0698 0.2428
-v 0.3638 1.0581 0.1120
-v 0.5113 1.2343 0.3911
-v 0.3234 1.1973 0.4439
-v 0.5330 1.1301 0.1580
-v 0.4816 1.4650 -0.0181
-v 0.2363 1.4470 -0.0890
-v 0.1566 1.4343 0.0823
-v 0.5000 1.4371 0.2679
-v 0.2308 1.3887 0.3437
-v 0.8832 2.4410 0.0089
-v 0.8694 2.3330 -0.0968
-v 0.8359 2.4247 -0.1333
-v 0.7617 2.3497 0.2301
-v 0.7375 2.4769 0.1133
-v 0.9566 2.3269 0.1115
-v 0.6206 2.4234 0.0410
-v 0.6278 2.2247 0.1094
-v 0.7246 2.2901 -0.1053
-v 0.7001 2.3592 -0.1351
-v 0.9174 2.1939 -0.0606
-v 0.8454 1.8851 0.1941
-v 0.7173 2.1413 -0.0469
-v 0.9522 1.9197 0.1994
-v 0.7735 1.9567 0.2996
-v 0.9647 2.0000 0.2952
-v 0.8626 2.0135 0.3633
-v 0.7062 2.5424 -0.1761
-v 0.8296 2.5442 0.1063
-v 0.6372 2.6072 0.1816
-v 0.8679 2.5743 -0.0818
-v 1.1037 1.5774 0.3775
-v 0.8769 1.5347 0.5967
-v 0.6960 1.6892 0.4880
-v 1.0247 1.7881 0.6604
-v 0.9322 1.9818 0.5498
-v 1.1546 1.7148 0.3738
-v 1.1061 1.8395 0.2604
-v 0.8877 2.0259 0.3737
-v 0.7540 1.9545 0.3154
-v 0.8576 1.8862 0.1687
-v 0.9167 1.6631 0.3033
-v 0.6549 1.8655 0.4703
-v 0.9761 1.7458 0.1736
-v 0.9915 1.9568 0.2277
-v 0.7793 2.7864 0.1381
-v 0.7598 2.8999 0.1175
-v 0.5384 2.9454 0.2760
-v 0.8153 2.8149 -0.0433
-v 1.0201 2.5364 0.0521
-v -0.8359 2.4247 -0.1333
-v -0.8694 2.3330 -0.0968
-v -0.8832 2.4410 0.0089
-v -0.7375 2.4769 0.1133
-v -0.7617 2.3497 0.2301
-v -0.9566 2.3269 0.1115
-v -0.6278 2.2247 0.1094
-v -0.6206 2.4234 0.0410
-v -0.7001 2.3592 -0.1351
-v -0.7246 2.2901 -0.1053
-v -0.9174 2.1939 -0.0606
-v -0.9522 1.9197 0.1994
-v -0.7173 2.1413 -0.0469
-v -0.8454 1.8851 0.1941
-v -0.7735 1.9567 0.2996
-v -0.9647 2.0000 0.2952
-v -0.8626 2.0135 0.3633
-v -0.7062 2.5424 -0.1761
-v -0.6372 2.6072 0.1816
-v -0.8296 2.5442 0.1063
-v -0.8679 2.5743 -0.0818
-v -0.6960 1.6892 0.4880
-v -0.8769 1.5347 0.5967
-v -1.1037 1.5774 0.3775
-v -1.0247 1.7881 0.6604
-v -0.9322 1.9818 0.5498
-v -1.1061 1.8395 0.2604
-v -1.1546 1.7148 0.3738
-v -0.8877 2.0259 0.3737
-v -0.8576 1.8862 0.1687
-v -0.7540 1.9545 0.3154
-v -0.6549 1.8655 0.4703
-v -0.9167 1.6631 0.3033
-v -0.9761 1.7458 0.1736
-v -0.9915 1.9568 0.2277
-v -0.7598 2.8999 0.1175
-v -0.7793 2.7864 0.1381
-v -0.8153 2.8149 -0.0433
-v -1.0201 2.5364 0.0521
-v -0.2581 0.3109 -0.0222
-v -0.1074 0.7729 0.0465
-v -0.3669 0.5949 0.4079
-v -0.2503 0.3707 -0.2076
-v -0.3183 0.8381 -0.2049
-v -0.5227 0.4206 -0.2834
-v -0.3568 0.7591 0.3005
-v -0.6660 0.6512 0.3267
-v -0.5643 0.7974 0.2441
-v -0.6560 0.8763 -0.0878
-v -0.6474 0.3841 -0.1308
-v -0.5029 0.2752 0.0655
-v -0.3398 0.9269 -0.0631
-v -0.2171 0.8500 0.0713
-v -0.5643 0.9154 -0.0161
-v -0.4760 0.0149 -0.3733
-v -0.1870 0.0143 0.0759
-v -0.5876 0.2785 0.2208
-v -0.3252 0.1550 0.3433
-v -0.2116 0.0173 -0.2542
-v -0.7396 0.0115 -0.1727
-v -0.8469 0.1524 0.1097
-v -0.2939 0.0107 0.3538
-v -0.5773 0.0071 0.5454
-v -0.8757 0.0076 0.0919
-v -0.6789 0.1808 0.4272
-v -0.8312 0.0059 0.4311
-v -0.5533 0.9947 0.3415
-v -0.3511 0.9560 0.3969
-v -0.5645 1.1095 0.1034
-v -0.3175 1.1236 -0.0066
-v -0.2027 1.0429 0.2015
-v -0.3638 1.0581 0.1120
-v -0.2279 1.0698 0.2428
-v -0.5113 1.2343 0.3911
-v -0.3234 1.1973 0.4439
-v -0.5330 1.1301 0.1580
-v -0.4816 1.4650 -0.0181
-v -0.2363 1.4470 -0.0890
-v -0.1566 1.4343 0.0823
-v -0.5000 1.4371 0.2679
-v -0.2308 1.3887 0.3437
-# 335 vertices
-
-vt 0.2135 0.0260 0.0000
-vt 0.2591 0.0428 0.0000
-vt 0.2222 0.0676 0.0000
-vt 0.1124 0.1603 0.0000
-vt 0.0642 0.1761 0.0000
-vt 0.0951 0.2220 0.0000
-vt 0.3095 0.2325 0.0000
-vt 0.2772 0.2438 0.0000
-vt 0.3622 0.2162 0.0000
-vt 0.2576 0.2373 0.0000
-vt 0.1799 0.2519 0.0000
-vt 0.1533 0.2468 0.0000
-vt 0.2235 0.2329 0.0000
-vt 0.0528 0.2394 0.0000
-vt 0.3151 0.2047 0.0000
-vt 0.4101 0.1722 0.0000
-vt 0.2625 0.1615 0.0000
-vt 0.4512 0.1876 0.0000
-vt 0.1970 0.2081 0.0000
-vt 0.2097 0.1811 0.0000
-vt 0.4310 0.2082 0.0000
-vt 0.0654 0.1897 0.0000
-vt 0.1534 0.1797 0.0000
-vt 0.3574 0.1263 0.0000
-vt 0.4512 0.1014 0.0000
-vt 0.5152 0.1062 0.0000
-vt 0.1137 0.1432 0.0000
-vt 0.1924 0.1250 0.0000
-vt 0.4595 0.0628 0.0000
-vt 0.2820 0.0889 0.0000
-vt 0.2590 0.0646 0.0000
-vt 0.1837 0.0996 0.0000
-vt 0.1063 0.1323 0.0000
-vt 0.5156 0.2228 0.0000
-vt 0.4944 0.1969 0.0000
-vt 0.2041 0.2096 0.0000
-vt 0.1379 0.1203 0.0000
-vt 0.1505 0.1745 0.0000
-vt 0.1389 0.2343 0.0000
-vt 0.0845 0.1988 0.0000
-vt 0.0316 0.2012 0.0000
-vt 0.0265 0.2483 0.0000
-vt 0.1201 0.2589 0.0000
-vt 0.8245 0.3764 0.0000
-vt 0.8552 0.3620 0.0000
-vt 0.8515 0.3759 0.0000
-vt 0.8046 0.3199 0.0000
-vt 0.7671 0.3625 0.0000
-vt 0.8032 0.3704 0.0000
-vt 0.7088 0.3112 0.0000
-vt 0.7312 0.3699 0.0000
-vt 0.7296 0.3196 0.0000
-vt 0.8257 0.3108 0.0000
-vt 0.7671 0.3118 0.0000
-vt 0.7104 0.3767 0.0000
-vt 0.7941 0.8715 0.0000
-vt 0.8152 0.8743 0.0000
-vt 0.7814 0.8715 0.0000
-vt 0.8160 0.8556 0.0000
-vt 0.8060 0.8547 0.0000
-vt 0.8423 0.8531 0.0000
-vt 0.7907 0.8603 0.0000
-vt 0.8108 0.8388 0.0000
-vt 0.8341 0.8195 0.0000
-vt 0.8449 0.8323 0.0000
-vt 0.7768 0.8511 0.0000
-vt 0.7868 0.8236 0.0000
-vt 0.7717 0.8262 0.0000
-vt 0.7991 0.8293 0.0000
-vt 0.8044 0.8213 0.0000
-vt 0.7821 0.8149 0.0000
-vt 0.7931 0.8223 0.0000
-vt 0.7682 0.8166 0.0000
-vt 0.8315 0.8149 0.0000
-vt 0.7989 0.8237 0.0000
-vt 0.8328 0.8250 0.0000
-vt 0.7977 0.8469 0.0000
-vt 0.8299 0.8463 0.0000
-vt 0.8102 0.8661 0.0000
-vt 0.8077 0.8496 0.0000
-vt 0.7849 0.8640 0.0000
-vt 0.7730 0.8618 0.0000
-vt 0.7773 0.8412 0.0000
-vt 0.8004 0.8431 0.0000
-vt 0.7773 0.8669 0.0000
-vt 0.8175 0.8526 0.0000
-vt 0.8327 0.8278 0.0000
-vt 0.8955 0.8308 0.0000
-vt 0.7126 0.9067 0.0000
-vt 0.7122 0.9055 0.0000
-vt 0.6562 0.8658 0.0000
-vt 0.7125 0.9010 0.0000
-vt 0.6316 0.8917 0.0000
-vt 0.7138 0.8403 0.0000
-vt 0.6525 0.8642 0.0000
-vt 0.7151 0.8399 0.0000
-vt 0.3771 0.6591 0.0000
-vt 0.4945 0.6355 0.0000
-vt 0.4423 0.7310 0.0000
-vt 0.5454 0.6962 0.0000
-vt 0.5968 0.6356 0.0000
-vt 0.5452 0.7879 0.0000
-vt 0.6480 0.7314 0.0000
-vt 0.7153 0.6600 0.0000
-vt 0.6163 0.0332 0.0000
-vt 0.6640 0.0716 0.0000
-vt 0.5685 0.0716 0.0000
-vt 0.5873 0.2558 0.0000
-vt 0.5703 0.1607 0.0000
-vt 0.5767 0.1372 0.0000
-vt 0.5790 0.1445 0.0000
-vt 0.5685 0.1681 0.0000
-vt 0.5986 0.1305 0.0000
-vt 0.5726 0.1759 0.0000
-vt 0.5985 0.1597 0.0000
-vt 0.5777 0.2146 0.0000
-vt 0.5713 0.1746 0.0000
-vt 0.5984 0.2161 0.0000
-vt 0.5848 0.2442 0.0000
-vt 0.5982 0.2580 0.0000
-vt 0.8853 0.6459 0.0000
-vt 0.8556 0.6355 0.0000
-vt 0.8881 0.6562 0.0000
-vt 0.8883 0.6804 0.0000
-vt 0.8605 0.7261 0.0000
-vt 0.8915 0.7259 0.0000
-vt 0.7747 0.6804 0.0000
-vt 0.7715 0.7259 0.0000
-vt 0.8027 0.7261 0.0000
-vt 0.8316 0.6925 0.0000
-vt 0.8631 0.7384 0.0000
-vt 0.8002 0.7384 0.0000
-vt 0.7682 0.6867 0.0000
-vt 0.7726 0.7205 0.0000
-vt 0.8597 0.6522 0.0000
-vt 0.8906 0.7205 0.0000
-vt 0.8743 0.7572 0.0000
-vt 0.7891 0.7572 0.0000
-vt 0.8860 0.6572 0.0000
-vt 0.7770 0.6572 0.0000
-vt 0.8948 0.6867 0.0000
-vt 0.8316 0.6665 0.0000
-vt 0.8116 0.6480 0.0000
-vt 0.7777 0.6459 0.0000
-vt 0.8514 0.6480 0.0000
-vt 0.8310 0.7629 0.0000
-vt 0.7891 0.7542 0.0000
-vt 0.8743 0.7542 0.0000
-vt 0.8035 0.6522 0.0000
-vt 0.7750 0.6562 0.0000
-vt 0.8089 0.6355 0.0000
-vt 0.9088 0.3283 0.0000
-vt 0.9347 0.3327 0.0000
-vt 0.9121 0.3504 0.0000
-vt 0.9135 0.3216 0.0000
-vt 0.9509 0.3223 0.0000
-vt 0.9443 0.3530 0.0000
-vt 0.9735 0.3592 0.0000
-vt 0.9692 0.3308 0.0000
-vt 0.9684 0.3675 0.0000
-vt 0.9263 0.3658 0.0000
-vt 0.5507 0.8617 0.0000
-vt 0.5279 0.8750 0.0000
-vt 0.5279 0.8465 0.0000
-vt 0.5470 0.8498 0.0000
-vt 0.5470 0.8828 0.0000
-vt 0.5319 0.8403 0.0000
-vt 0.5279 0.8961 0.0000
-vt 0.5496 0.8399 0.0000
-vt 0.5645 0.8636 0.0000
-vt 0.5620 0.8770 0.0000
-vt 0.5742 0.8681 0.0000
-vt 0.5654 0.8482 0.0000
-vt 0.4749 0.8399 0.0000
-vt 0.3867 0.9042 0.0000
-vt 0.4750 0.9042 0.0000
-vt 0.3879 0.8399 0.0000
-vt 0.6367 0.1288 0.0000
-vt 0.5886 0.1338 0.0000
-vt 0.5890 0.1288 0.0000
-vt 0.6846 0.1341 0.0000
-vt 0.6838 0.1286 0.0000
-vt 0.5916 0.1410 0.0000
-vt 0.6180 0.1379 0.0000
-vt 0.6005 0.1390 0.0000
-vt 0.6978 0.2376 0.0000
-vt 0.7052 0.1822 0.0000
-vt 0.7052 0.2450 0.0000
-vt 0.6893 0.1737 0.0000
-vt 0.6623 0.2482 0.0000
-vt 0.6931 0.2461 0.0000
-vt 0.6657 0.2279 0.0000
-vt 0.6966 0.1777 0.0000
-vt 0.6741 0.1748 0.0000
-vt 0.6393 0.2442 0.0000
-vt 0.6584 0.1476 0.0000
-vt 0.6446 0.1649 0.0000
-vt 0.6397 0.2053 0.0000
-vt 0.6394 0.2172 0.0000
-vt 0.6844 0.1441 0.0000
-vt 0.7033 0.1498 0.0000
-vt 0.6445 0.1708 0.0000
-vt 0.6755 0.1425 0.0000
-vt 0.6454 0.1528 0.0000
-vt 0.6875 0.1377 0.0000
-vt 0.5724 0.2532 0.0000
-vt 0.5865 0.1723 0.0000
-vt 0.5844 0.2452 0.0000
-vt 0.6193 0.2589 0.0000
-vt 0.5938 0.1674 0.0000
-vt 0.5889 0.2558 0.0000
-vt 0.6089 0.1691 0.0000
-vt 0.6164 0.2339 0.0000
-vt 0.5744 0.1790 0.0000
-vt 0.6422 0.2545 0.0000
-vt 0.6249 0.1363 0.0000
-vt 0.6428 0.2071 0.0000
-vt 0.6386 0.1578 0.0000
-vt 0.6426 0.2217 0.0000
-vt 0.5802 0.1377 0.0000
-vt 0.6382 0.1650 0.0000
-vt 0.6377 0.1431 0.0000
-vt 0.6080 0.1297 0.0000
-vt 0.5963 0.1236 0.0000
-vt 0.6815 0.1413 0.0000
-vt 0.6543 0.1378 0.0000
-vt 0.6421 0.1506 0.0000
-vt 0.6314 0.1701 0.0000
-vt 0.6307 0.1506 0.0000
-vt 0.7008 0.1472 0.0000
-vt 0.6414 0.1640 0.0000
-vt 0.6319 0.1642 0.0000
-vt 0.6366 0.2080 0.0000
-vt 0.6554 0.1451 0.0000
-vt 0.5723 0.1468 0.0000
-vt 0.6414 0.1701 0.0000
-vt 0.6362 0.2206 0.0000
-vt 0.6177 0.1450 0.0000
-vt 0.6726 0.1392 0.0000
-vt 0.1171 0.8175 0.0000
-vt 0.0996 0.8137 0.0000
-vt 0.1074 0.9276 0.0000
-vt 0.0971 0.9343 0.0000
-vt 0.0895 0.8288 0.0000
-vt 0.1582 0.8282 0.0000
-vt 0.1511 0.9341 0.0000
-vt 0.1676 0.9337 0.0000
-vt 0.1274 0.8172 0.0000
-vt 0.1151 0.8003 0.0000
-vt 0.1286 0.8000 0.0000
-vt 0.1449 0.8111 0.0000
-vt 0.1397 0.9273 0.0000
-vt 0.1232 0.9292 0.0000
-vt 0.0981 0.8030 0.0000
-vt 0.0894 0.8016 0.0000
-vt 0.1581 0.8009 0.0000
-vt 0.1460 0.8016 0.0000
-vt 0.8961 0.2518 0.0000
-vt 0.8864 0.1335 0.0000
-vt 0.8902 0.1363 0.0000
-vt 0.8510 0.2514 0.0000
-vt 0.8561 0.1236 0.0000
-vt 0.8322 0.1284 0.0000
-vt 0.8033 0.2053 0.0000
-vt 0.8046 0.1568 0.0000
-vt 0.8615 0.1271 0.0000
-vt 0.7586 0.2512 0.0000
-vt 0.8033 0.2515 0.0000
-vt 0.7682 0.1938 0.0000
-vt 0.7144 0.9075 0.0000
-vt 0.7152 0.9064 0.0000
-vt 0.7131 0.9080 0.0000
-vt 0.7135 0.9053 0.0000
-vt 0.9034 0.5146 0.0000
-vt 0.9377 0.5020 0.0000
-vt 0.9412 0.5360 0.0000
-vt 0.9496 0.5254 0.0000
-vt 0.9455 0.5426 0.0000
-vt 0.9465 0.5156 0.0000
-vt 0.9546 0.5330 0.0000
-vt 0.9510 0.5622 0.0000
-vt 0.9070 0.5309 0.0000
-vt 0.9021 0.5563 0.0000
-vt 0.9344 0.5805 0.0000
-vt 0.9309 0.5801 0.0000
-vt 0.9057 0.5775 0.0000
-vt 0.9081 0.5372 0.0000
-vt 0.9493 0.5614 0.0000
-vt 0.8939 0.5549 0.0000
-vt 0.9094 0.5780 0.0000
-vt 0.9499 0.5624 0.0000
-vt 0.9433 0.3160 0.0000
-vt 0.9536 0.3109 0.0000
-vt 0.9714 0.3317 0.0000
-vt 0.9377 0.3407 0.0000
-vt 0.9207 0.3279 0.0000
-vt 0.9700 0.3185 0.0000
-vt 0.9081 0.3108 0.0000
-# 298 texture coords
-
-g Regroup24
-usemtl YoungLink.bmp
-f 1/1 2/2 3/3
-f 4/4 5/5 6/6
-f 7/7 8/8 9/9
-f 10/10 11/11 12/12
-f 11/11 10/10 8/8
-f 8/8 7/7 11/11
-f 11/11 13/13 6/6
-f 11/11 14/14 12/12
-f 15/15 16/16 9/9
-f 16/16 15/15 17/17
-f 9/9 16/16 18/18
-f 15/15 19/19 17/17
-f 20/20 17/17 19/19
-f 9/9 18/18 21/21
-f 14/14 5/5 22/22
-f 20/20 23/23 17/17
-f 24/24 16/16 17/17
-f 25/25 26/26 24/24
-f 27/27 28/28 23/23
-f 16/16 24/24 26/26
-f 29/29 30/30 31/31
-f 29/29 24/24 30/30
-f 16/16 26/26 18/18
-f 28/28 30/30 17/17
-f 32/32 30/30 28/28
-f 30/30 32/32 31/31
-f 30/30 24/24 17/17
-f 27/27 5/5 33/33
-f 23/23 28/28 17/17
-f 27/27 22/22 5/5
-f 27/27 32/32 28/28
-f 34/34 21/21 35/35
-f 34/34 35/35 7/7
-f 10/10 19/19 15/15
-f 27/27 33/33 32/32
-f 36/36 13/13 7/7
-f 10/10 15/15 9/9
-f 14/14 11/11 6/6
-f 6/6 5/5 14/14
-f 5/5 4/4 37/37
-f 4/4 38/38 37/37
-f 8/8 10/10 9/9
-f 13/13 11/11 7/7
-f 33/33 5/5 37/37
-f 1/1 37/37 2/2
-f 33/33 37/37 32/32
-f 29/29 25/25 24/24
-f 39/39 13/13 36/36
-f 40/40 4/4 41/41
-f 40/40 36/36 38/38
-f 42/42 4/4 6/6
-f 42/42 13/13 43/43
-f 39/39 36/36 40/40
-f 4/4 42/42 41/41
-f 13/13 42/42 6/6
-f 13/13 39/39 43/43
-f 4/4 40/40 38/38
-f 44/44 45/45 46/46
-f 47/47 45/48 48/49
-f 49/50 50/51 51/52
-f 52/53 48/49 44/44
-f 45/48 47/47 53/54
-f 45/48 44/44 48/49
-f 48/49 52/53 47/47
-f 45/48 51/52 50/51
-f 46/55 45/48 50/51
-f 50/51 49/50 46/55
-f 51/52 45/48 53/54
-f 54/56 55/57 56/58
-f 55/57 54/56 25/59
-f 55/57 29/60 57/61
-f 55/57 57/61 58/62
-f 59/63 58/62 57/61
-f 55/57 58/62 56/58
-f 60/64 59/63 61/65
-f 59/63 62/66 58/62
-f 3/67 2/68 31/69
-f 31/69 32/70 3/67
-f 60/64 2/68 59/63
-f 60/64 61/65 29/60
-f 56/58 58/62 62/66
-f 60/64 31/69 2/68
-f 59/63 2/68 62/66
-f 60/64 29/60 31/69
-f 59/63 57/61 61/65
-f 61/65 57/61 29/60
-f 55/57 25/59 29/60
-f 21/71 18/72 35/73
-f 63/74 64/75 35/73
-f 65/76 26/77 66/78
-f 65/76 18/72 26/77
-f 67/79 25/80 54/81
-f 63/74 65/76 64/75
-f 66/78 26/77 67/79
-f 67/79 26/77 25/80
-f 63/74 18/72 65/76
-f 54/81 68/82 67/79
-f 64/75 65/76 66/78
-f 64/75 66/78 69/83
-f 67/79 69/83 66/78
-f 67/79 68/82 69/83
-f 63/74 35/73 18/72
-f 64/75 69/83 35/73
-f 38/84 70/85 71/86
-f 37/87 38/84 71/86
-f 72/86 7/87 35/88
-f 71/86 2/88 37/87
-f 72/86 36/84 7/87
-f 36/84 70/85 38/84
-f 70/85 36/84 72/86
-f 41/89 42/89 73/89
-f 43/89 74/89 75/89
-f 40/89 74/89 39/89
-f 42/89 76/90 73/89
-f 41/89 77/89 40/89
-f 77/89 74/89 40/89
-f 43/89 75/89 42/89
-f 74/89 43/89 39/89
-f 75/89 76/90 42/89
-f 77/89 41/89 73/89
-f 21/91 7/92 9/93
-f 34/94 7/92 21/91
-f 3/95 32/93 37/92
-f 1/96 3/95 37/92
-f 27/97 23/98 22/99
-f 78/100 23/98 19/101
-f 14/102 22/99 78/100
-f 78/100 22/99 23/98
-f 12/103 19/101 10/104
-f 12/103 14/102 78/100
-f 12/103 78/100 19/101
-f 20/105 19/106 23/107
-f 79/108 80/108 77/108
-f 74/108 81/108 75/108
-f 82/108 74/108 77/108
-f 82/108 77/108 80/108
-f 73/108 76/108 79/108
-f 77/108 73/108 79/108
-f 82/108 81/108 74/108
-f 75/108 81/108 76/108
-f 68/109 83/110 84/111
-f 83/110 68/109 56/109
-f 54/112 56/109 68/109
-f 84/111 83/110 85/113
-f 86/111 56/109 62/114
-f 87/115 62/114 2/116
-f 86/111 87/115 85/113
-f 86/111 85/113 83/110
-f 86/111 62/114 87/115
-f 86/111 83/110 56/109
-f 69/117 84/111 88/115
-f 85/113 88/115 84/111
-f 35/116 88/115 89/118
-f 88/115 35/116 69/117
-f 90/118 71/119 70/120
-f 89/118 70/120 72/119
-f 90/118 2/116 71/119
-f 2/116 90/118 87/115
-f 35/116 89/118 72/119
-f 68/109 84/111 69/117
-f 91/121 74/122 92/123
-f 93/124 94/125 95/126
-f 96/127 97/128 98/129
-f 99/130 100/131 101/132
-f 102/133 103/127 104/134
-f 94/125 92/123 105/135
-f 100/131 106/136 107/137
-f 104/134 101/132 108/138
-f 109/124 99/130 110/139
-f 111/140 99/130 103/127
-f 112/141 95/126 106/136
-f 109/124 112/141 106/136
-f 76/142 111/140 73/143
-f 113/144 73/143 111/140
-f 76/142 110/139 99/130
-f 110/139 76/142 75/145
-f 114/146 115/147 108/138
-f 108/138 97/128 104/134
-f 105/135 98/129 94/125
-f 114/146 116/148 115/147
-f 107/137 116/148 114/146
-f 117/149 98/129 105/135
-f 118/150 98/129 117/149
-f 95/126 107/137 106/136
-f 95/126 94/125 116/148
-f 114/146 108/138 107/137
-f 92/123 74/122 105/135
-f 115/147 98/129 97/128
-f 74/122 117/149 105/135
-f 77/151 118/150 117/149
-f 101/132 107/137 108/138
-f 77/151 117/149 74/122
-f 115/147 94/125 98/129
-f 100/131 107/137 101/132
-f 97/128 102/133 104/134
-f 116/148 94/125 115/147
-f 73/143 113/144 77/151
-f 101/132 103/127 99/130
-f 74/122 91/121 75/145
-f 97/128 96/127 102/133
-f 112/141 93/124 95/126
-f 75/145 91/121 110/139
-f 99/130 111/140 76/142
-f 94/125 93/124 92/123
-f 103/127 101/132 104/134
-f 100/131 109/124 106/136
-f 107/137 95/126 116/148
-f 109/124 100/131 99/130
-f 118/150 77/151 113/144
-f 97/128 108/138 115/147
-f 98/129 118/150 96/127
-f 93/152 119/153 92/154
-f 119/153 93/152 112/155
-f 109/152 120/156 112/155
-f 120/156 119/153 112/155
-f 121/157 96/158 118/159
-f 96/158 121/157 102/160
-f 121/157 122/161 102/160
-f 122/161 103/158 102/160
-f 123/162 89/163 88/164
-f 87/164 124/162 125/165
-f 124/162 90/163 126/166
-f 88/164 127/165 123/162
-f 85/167 127/165 88/164
-f 125/165 85/167 87/164
-f 70/168 126/166 90/163
-f 85/167 125/165 128/169
-f 89/163 123/162 129/166
-f 127/165 85/167 128/169
-f 129/166 70/168 89/163
-f 90/163 124/162 87/164
-f 70/168 129/166 126/166
-f 130/170 126/166 131/171
-f 129/166 132/170 131/171
-f 133/172 131/171 132/170
-f 134/173 132/170 127/165
-f 130/170 125/165 124/162
-f 134/173 127/165 128/169
-f 130/170 134/173 125/165
-f 130/170 131/171 133/172
-f 132/170 134/173 133/172
-f 126/166 129/166 131/171
-f 125/165 134/173 128/169
-f 127/165 132/170 123/162
-f 126/166 130/170 124/162
-f 134/173 130/170 133/172
-f 132/170 129/166 123/162
-f 44/174 49/175 52/176
-f 49/175 44/174 46/177
-f 53/178 135/179 51/180
-f 136/181 53/178 47/182
-f 51/180 137/183 49/184
-f 135/179 53/178 138/185
-f 139/186 140/187 141/188
-f 142/189 143/190 144/191
-f 145/192 146/193 139/186
-f 146/193 140/187 139/186
-f 141/188 142/189 144/191
-f 147/194 146/193 145/192
-f 140/187 142/189 141/188
-f 148/195 149/196 150/197
-f 150/197 151/198 148/195
-f 152/199 147/194 145/192
-f 142/189 140/187 153/200
-f 153/200 140/187 154/201
-f 147/194 155/202 156/203
-f 156/203 155/202 157/204
-f 136/205 146/193 156/203
-f 156/203 146/193 147/194
-f 153/200 143/190 142/189
-f 140/187 136/205 154/201
-f 149/196 148/195 143/190
-f 149/196 143/190 153/200
-f 147/194 152/199 155/202
-f 136/205 140/187 146/193
-f 158/206 159/207 160/208
-f 161/209 162/210 163/211
-f 160/208 164/212 165/213
-f 166/214 159/207 158/206
-f 163/211 166/214 158/206
-f 159/207 164/212 160/208
-f 162/210 166/214 163/211
-f 167/215 168/216 161/209
-f 151/217 169/218 167/215
-f 164/212 152/219 165/213
-f 166/214 162/210 170/220
-f 170/220 162/210 137/113
-f 171/221 164/212 172/222
-f 172/222 164/212 138/223
-f 159/207 135/224 164/212
-f 164/212 135/224 138/223
-f 162/210 168/216 137/113
-f 135/224 166/214 170/220
-f 168/216 167/215 169/218
-f 161/209 168/216 162/210
-f 152/219 164/212 171/221
-f 166/214 135/224 159/207
-f 153/225 47/182 52/226
-f 157/227 171/228 172/229
-f 47/182 153/225 154/230
-f 53/178 172/229 138/185
-f 150/231 169/232 151/233
-f 47/182 154/230 136/181
-f 52/226 149/234 153/225
-f 137/183 51/180 170/235
-f 53/178 157/227 172/229
-f 171/228 155/236 152/237
-f 49/184 137/183 168/238
-f 53/178 156/239 157/227
-f 51/180 135/179 170/235
-f 49/184 149/234 52/226
-f 171/228 157/227 155/236
-f 168/238 150/231 149/234
-f 168/238 149/234 49/184
-f 169/232 150/231 168/238
-f 53/178 136/181 156/239
-f 51/180 135/179 53/178
-f 47/182 53/178 136/181
-f 49/184 137/183 51/180
-f 138/185 53/178 135/179
-f 141/188 140/187 139/186
-f 144/191 143/190 142/189
-f 139/186 146/193 145/192
-f 139/186 140/187 146/193
-f 144/191 142/189 141/188
-f 145/192 146/193 147/194
-f 141/188 142/189 140/187
-f 150/197 149/196 148/195
-f 148/195 151/198 150/197
-f 145/192 147/194 152/199
-f 153/200 140/187 142/189
-f 154/201 140/187 153/200
-f 156/203 155/202 147/194
-f 157/204 155/202 156/203
-f 156/203 146/193 136/205
-f 147/194 146/193 156/203
-f 142/189 143/190 153/200
-f 154/201 136/205 140/187
-f 143/190 148/195 149/196
-f 153/200 143/190 149/196
-f 155/202 152/199 147/194
-f 146/193 140/187 136/205
-f 160/208 159/207 158/206
-f 163/211 162/210 161/209
-f 165/213 164/212 160/208
-f 158/206 159/207 166/214
-f 158/206 166/214 163/211
-f 160/208 164/212 159/207
-f 163/211 166/214 162/210
-f 161/209 168/216 167/215
-f 167/215 169/218 151/217
-f 165/213 152/219 164/212
-f 170/220 162/210 166/214
-f 137/113 162/210 170/220
-f 172/222 164/212 171/221
-f 138/223 164/212 172/222
-f 164/212 135/224 159/207
-f 138/223 135/224 164/212
-f 137/113 168/216 162/210
-f 170/220 166/214 135/224
-f 169/218 167/215 168/216
-f 162/210 168/216 161/209
-f 171/221 164/212 152/219
-f 159/207 135/224 166/214
-f 52/226 47/182 153/225
-f 172/229 171/228 157/227
-f 154/230 153/225 47/182
-f 138/185 172/229 53/178
-f 151/233 169/232 150/231
-f 136/181 154/230 47/182
-f 153/225 149/234 52/226
-f 170/235 51/180 137/183
-f 172/229 157/227 53/178
-f 152/237 155/236 171/228
-f 168/238 137/183 49/184
-f 157/227 156/239 53/178
-f 170/235 135/179 51/180
-f 52/226 149/234 49/184
-f 155/236 157/227 171/228
-f 149/234 150/231 168/238
-f 49/184 149/234 168/238
-f 168/238 150/231 169/232
-f 156/239 136/181 53/178
-f 173/240 174/241 175/242
-f 176/243 175/242 174/241
-f 174/241 177/244 176/243
-f 177/245 178/246 176/247
-f 173/240 179/248 180/249
-f 180/249 179/248 181/250
-f 179/248 182/251 181/250
-f 182/251 183/252 178/246
-f 179/248 184/253 183/252
-f 184/253 173/240 175/242
-f 185/254 186/255 177/244
-f 179/248 173/240 184/253
-f 183/252 182/251 179/248
-f 186/256 187/257 177/245
-f 174/241 173/240 180/249
-f 177/245 182/251 178/246
-f 180/249 185/254 174/241
-f 187/257 181/250 182/251
-f 185/254 177/244 174/241
-f 177/245 187/257 182/251
-f 188/258 176/259 178/260
-f 189/261 175/262 176/259
-f 184/263 190/264 191/265
-f 192/258 176/259 188/258
-f 176/259 192/258 189/261
-f 175/262 190/264 184/263
-f 188/258 178/260 193/261
-f 183/266 193/261 178/260
-f 194/264 183/266 191/265
-f 191/265 183/266 184/263
-f 175/262 189/261 190/264
-f 193/261 183/266 194/264
-f 193/261 189/261 188/258
-f 188/258 189/261 192/258
-f 195/267 190/264 196/268
-f 193/261 194/264 197/268
-f 198/269 194/264 191/265
-f 198/269 190/264 195/267
-f 193/261 196/268 189/261
-f 197/268 196/268 193/261
-f 199/267 194/264 198/269
-f 198/269 195/267 199/267
-f 190/264 198/269 191/265
-f 194/264 199/267 197/268
-f 196/268 197/268 195/267
-f 195/267 197/268 199/267
-f 190/264 189/261 196/268
-f 200/270 180/270 201/270
-f 201/270 180/270 181/270
-f 187/271 202/271 203/271
-f 202/271 185/271 204/271
-f 203/271 201/270 181/270
-f 185/271 202/271 186/271
-f 185/271 180/270 204/271
-f 181/270 187/271 203/271
-f 200/270 204/271 180/270
-f 202/271 187/271 186/271
-f 204/271 205/270 206/271
-f 201/270 203/271 207/270
-f 207/270 208/270 201/270
-f 201/270 208/270 200/270
-f 205/270 204/271 208/270
-f 206/271 203/271 202/271
-f 203/271 209/270 207/270
-f 208/270 204/271 200/270
-f 209/270 203/271 206/271
-f 204/271 206/271 202/271
-f 210/89 207/270 209/270
-f 210/89 209/270 211/89
-f 211/89 205/270 212/89
-f 213/270 207/270 210/89
-f 211/89 209/270 206/271
-f 205/270 211/89 206/271
-f 212/89 205/270 214/270
-f 214/270 205/270 208/270
-f 214/270 208/270 213/270
-f 213/270 208/270 207/270
-f 215/89 216/90 217/90
-f 218/272 215/89 219/89
-f 215/89 218/272 220/89
-f 218/272 221/89 222/89
-f 217/90 223/89 224/89
-f 221/89 223/89 222/89
-f 221/89 218/272 219/89
-f 216/90 223/89 217/90
-f 225/273 215/89 220/89
-f 223/89 221/89 224/89
-f 216/90 215/89 225/273
-f 226/271 227/89 228/271
-f 228/271 227/89 225/273
-f 222/89 227/89 229/270
-f 229/270 227/89 226/271
-f 225/273 220/89 228/271
-f 228/271 220/89 230/270
-f 218/272 222/89 231/270
-f 231/270 222/89 229/270
-f 227/89 216/90 225/273
-f 222/89 223/89 227/89
-f 231/270 220/89 218/272
-f 223/89 216/90 227/89
-f 229/270 230/270 231/270
-f 230/270 220/89 231/270
-f 228/271 230/270 226/271
-f 226/271 230/270 229/270
-f 224/273 122/89 232/90
-f 219/89 233/89 234/89
-f 215/89 235/90 233/89
-f 217/273 235/90 215/89
-f 122/89 224/273 221/89
-f 233/89 219/89 215/89
-f 234/89 221/89 219/89
-f 217/273 232/90 235/90
-f 122/89 121/90 232/90
-f 121/90 235/90 232/90
-f 232/90 217/273 224/273
-f 221/89 234/89 122/89
-f 236/274 237/275 238/276
-f 236/274 239/277 237/275
-f 238/278 237/279 239/280
-f 240/281 238/278 239/280
-f 240/281 241/282 242/283
-f 242/283 243/284 240/281
-f 244/285 243/284 245/286
-f 239/277 241/282 240/281
-f 241/282 236/274 242/283
-f 239/277 236/274 241/282
-f 246/287 247/288 245/286
-f 248/289 245/286 242/283
-f 238/276 247/288 246/287
-f 248/289 246/287 245/286
-f 238/276 246/287 236/274
-f 236/274 246/287 248/289
-f 243/284 242/283 249/290
-f 242/283 236/274 248/289
-f 249/290 242/283 245/286
-f 243/284 249/290 245/286
-f 240/281 243/284 247/288
-f 238/278 240/281 247/291
-f 244/285 245/286 247/288
-f 243/284 244/285 247/288
-f 250/292 251/293 252/294
-f 103/158 122/161 234/295
-f 250/292 103/158 233/296
-f 233/296 103/158 234/295
-f 113/297 252/294 251/293
-f 251/293 118/159 113/297
-f 118/159 253/292 121/157
-f 118/159 251/293 253/292
-f 103/158 250/292 252/294
-f 254/298 250/292 233/296
-f 254/298 253/292 250/292
-f 233/296 235/296 254/298
-f 253/292 254/298 235/296
-f 251/293 250/292 253/292
-f 235/296 121/157 253/292
-f 255/90 256/90 257/89
-f 258/89 257/89 259/272
-f 260/89 259/272 257/89
-f 261/89 262/89 259/272
-f 263/89 264/89 255/90
-f 261/89 264/89 262/89
-f 258/89 259/272 262/89
-f 255/90 264/89 256/90
-f 260/89 257/89 265/273
-f 263/89 262/89 264/89
-f 265/273 257/89 256/90
-f 266/271 267/89 268/271
-f 265/273 267/89 266/271
-f 269/270 267/89 261/89
-f 268/271 267/89 269/270
-f 266/271 260/89 265/273
-f 270/270 260/89 266/271
-f 271/270 261/89 259/272
-f 269/270 261/89 271/270
-f 265/273 256/90 267/89
-f 267/89 264/89 261/89
-f 259/272 260/89 271/270
-f 267/89 256/90 264/89
-f 271/270 270/270 269/270
-f 271/270 260/89 270/270
-f 268/271 270/270 266/271
-f 269/270 270/270 268/271
-f 272/90 120/89 263/273
-f 273/89 274/89 258/89
-f 274/89 275/90 257/89
-f 257/89 275/90 255/273
-f 262/89 263/273 120/89
-f 257/89 258/89 274/89
-f 258/89 262/89 273/89
-f 275/90 272/90 255/273
-f 272/90 119/90 120/89
-f 272/90 275/90 119/90
-f 263/273 255/273 272/90
-f 120/89 273/89 262/89
-f 276/276 277/275 278/274
-f 277/275 279/277 278/274
-f 279/280 277/279 276/278
-f 279/280 276/278 280/281
-f 281/283 282/282 280/281
-f 280/281 283/284 281/283
-f 284/286 283/284 285/285
-f 280/281 282/282 279/277
-f 281/283 278/274 282/282
-f 282/282 278/274 279/277
-f 284/286 286/288 287/287
-f 281/283 284/286 288/289
-f 287/287 286/288 276/276
-f 284/286 287/287 288/289
-f 278/274 287/287 276/276
-f 288/289 287/287 278/274
-f 289/290 281/283 283/284
-f 288/289 278/274 281/283
-f 284/286 281/283 289/290
-f 284/286 289/290 283/284
-f 286/288 283/284 280/281
-f 286/291 280/281 276/278
-f 286/288 284/286 285/285
-f 286/288 285/285 283/284
-f 110/294 290/293 291/292
-f 273/295 120/161 109/158
-f 274/296 109/158 291/292
-f 273/295 109/158 274/296
-f 290/293 110/294 91/297
-f 91/297 92/159 290/293
-f 119/157 292/292 92/159
-f 292/292 290/293 92/159
-f 110/294 291/292 109/158
-f 274/296 291/292 293/298
-f 291/292 292/292 293/298
-f 293/298 275/296 274/296
-f 275/296 293/298 292/292
-f 292/292 291/292 290/293
-f 292/292 119/157 275/296
-f 294/242 295/241 296/240
-f 295/241 294/242 297/243
-f 297/243 298/244 295/241
-f 297/247 299/246 298/245
-f 300/249 301/248 296/240
-f 302/250 301/248 300/249
-f 302/250 303/251 301/248
-f 299/246 304/252 303/251
-f 304/252 305/253 301/248
-f 294/242 296/240 305/253
-f 298/244 306/255 307/254
-f 305/253 296/240 301/248
-f 301/248 303/251 304/252
-f 298/245 308/257 306/256
-f 300/249 296/240 295/241
-f 299/246 303/251 298/245
-f 295/241 307/254 300/249
-f 303/251 302/250 308/257
-f 295/241 298/244 307/254
-f 303/251 308/257 298/245
-f 299/260 297/259 309/258
-f 297/259 294/262 310/261
-f 311/265 312/264 305/263
-f 309/258 297/259 313/258
-f 310/261 313/258 297/259
-f 305/263 312/264 294/262
-f 314/261 299/260 309/258
-f 299/260 314/261 304/266
-f 311/265 304/266 315/264
-f 305/263 304/266 311/265
-f 312/264 310/261 294/262
-f 315/264 304/266 314/261
-f 309/258 310/261 314/261
-f 313/258 310/261 309/258
-f 316/268 312/264 317/267
-f 318/268 315/264 314/261
-f 311/265 315/264 319/269
-f 317/267 312/264 319/269
-f 310/261 316/268 314/261
-f 314/261 316/268 318/268
-f 319/269 315/264 320/267
-f 320/267 317/267 319/269
-f 311/265 319/269 312/264
-f 318/268 320/267 315/264
-f 317/267 318/268 316/268
-f 320/267 318/268 317/267
-f 316/268 310/261 312/264
-f 321/270 300/270 322/270
-f 302/270 300/270 321/270
-f 323/271 324/271 308/271
-f 325/271 307/271 324/271
-f 302/270 321/270 323/271
-f 306/271 324/271 307/271
-f 325/271 300/270 307/271
-f 323/271 308/271 302/270
-f 300/270 325/271 322/270
-f 306/271 308/271 324/271
-f 326/271 327/270 325/271
-f 328/270 323/271 321/270
-f 321/270 329/270 328/270
-f 322/270 329/270 321/270
-f 329/270 325/271 327/270
-f 324/271 323/271 326/271
-f 328/270 330/270 323/271
-f 322/270 325/271 329/270
-f 326/271 323/271 330/270
-f 324/271 326/271 325/271
-f 330/270 328/270 331/89
-f 332/89 330/270 331/89
-f 333/89 327/270 332/89
-f 331/89 328/270 334/270
-f 326/271 330/270 332/89
-f 326/271 332/89 327/270
-f 335/270 327/270 333/89
-f 329/270 327/270 335/270
-f 334/270 329/270 335/270
-f 328/270 329/270 334/270
-# 693 faces