private void Subdivide( double Scale, ref VertexT2dN3dV3d first, ref VertexT2dN3dV3d second, ref VertexT2dN3dV3d third, out Chunk c ) { c = new Chunk(6, 12); c.Vertices[0] = first; Vector3d.Lerp(ref first.Position, ref second.Position, 0.5,out c.Vertices[1].Normal ); c.Vertices[1].Normal.Normalize(); c.Vertices[1].Position = c.Vertices[1].Normal * Scale; OpenTK.Vector2d.Lerp(ref first.TexCoord, ref second.TexCoord, 0.5, out c.Vertices[1].TexCoord); Vector3d.Lerp( ref third.Position, ref first.Position, 0.5, out c.Vertices[2].Normal ); c.Vertices[2].Normal.Normalize(); c.Vertices[2].Position = c.Vertices[2].Normal * Scale; OpenTK.Vector2d.Lerp(ref third.TexCoord, ref first.TexCoord, 0.5, out c.Vertices[2].TexCoord); c.Vertices[3] = second; Vector3d.Lerp( ref second.Position, ref third.Position, 0.5, out c.Vertices[4].Normal ); c.Vertices[4].Normal.Normalize(); c.Vertices[4].Position = c.Vertices[4].Normal * Scale; OpenTK.Vector2d.Lerp(ref second.TexCoord, ref third.TexCoord, 0.5, out c.Vertices[4].TexCoord); c.Vertices[5] = third; #region Indices c.Indices[0]=0; c.Indices[1]=1; c.Indices[2]=2; c.Indices[3]=2; c.Indices[4]=1; c.Indices[5]=4; c.Indices[6]=1; c.Indices[7]=3; c.Indices[8]=4; c.Indices[9]=2; c.Indices[10]=4; c.Indices[11]=5; #endregion Indices }
private void DrawSide( eSides side, ref List<Chunk> chunks ) { #region Setup constants for current direction double _Zero = 0.0; // 0/3 double _Three = 0.3333333333333; // 1/3 double _Six = 0.66666666666666; // 2/3 double _One = 1.0; // 3/3 double ThirdLength = SideLength / 3f; Vector3d C0 = Center + new Vector3d( -SideLength, -SideLength, +SideLength ); Vector3d C1 = Center + new Vector3d( +SideLength, -SideLength, +SideLength ); Vector3d C2 = Center + new Vector3d( +SideLength, +SideLength, +SideLength ); Vector3d C3 = Center + new Vector3d( -SideLength, +SideLength, +SideLength ); Vector3d C4 = Center + new Vector3d( -SideLength, -SideLength, -SideLength ); Vector3d C5 = Center + new Vector3d( +SideLength, -SideLength, -SideLength ); Vector3d C6 = Center + new Vector3d( +SideLength, +SideLength, -SideLength ); Vector3d C7 = Center + new Vector3d( -SideLength, +SideLength, -SideLength ); Vector3d P0, P1, P2, P3, P4, P5, P6, P7; switch ( side ) { case eSides.Front: P0 = C0; P1 = C1; P2 = C2; P3 = C3; P4 = C4; P5 = C5; P6 = C6; P7 = C7; break; case eSides.Back: P0 = C5; P1 = C4; P2 = C7; P3 = C6; P4 = C1; P5 = C0; P6 = C3; P7 = C2; break; case eSides.Right: P0 = C1; P1 = C5; P2 = C6; P3 = C2; P4 = C0; P5 = C4; P6 = C7; P7 = C3; break; case eSides.Left: P0 = C4; P1 = C0; P2 = C3; P3 = C7; P4 = C5; P5 = C1; P6 = C2; P7 = C6; break; case eSides.Top: P0 = C3; P1 = C2; P2 = C6; P3 = C7; P4 = C0; P5 = C1; P6 = C5; P7 = C4; break; case eSides.Bottom: P0 = C1; P1 = C0; P2 = C4; P3 = C5; P4 = C2; P5 = C3; P6 = C7; P7 = C6; break; default: throw new NotImplementedException( "Unknown enum value: " + side ); } #endregion Setup constants for current direction #region Set Normal Vector3d FaceNormal; switch ( side ) { case eSides.Front: FaceNormal = Vector3d.UnitZ; break; case eSides.Back: FaceNormal = -Vector3d.UnitZ; break; case eSides.Right: FaceNormal = Vector3d.UnitX; break; case eSides.Left: FaceNormal = -Vector3d.UnitX; break; case eSides.Top: FaceNormal = Vector3d.UnitY; break; case eSides.Bottom: FaceNormal = -Vector3d.UnitY; break; default: throw new NotImplementedException( "Unknown enum value: " + side ); } #endregion Set Normal bool FaceIsVisible = false; foreach ( eSides s in VisibleSides ) { if ( s == side ) { FaceIsVisible = true; break; } } if ( FaceIsVisible ) { #region Define Layer1 Vertices Chunk Layer1 = new Chunk( 8, 8 * 3 ); Layer1.Vertices[0].TexCoord = new OpenTK.Vector2d(_Zero, _Zero); Layer1.Vertices[0].Normal = FaceNormal; Layer1.Vertices[0].Position = P0; Layer1.Vertices[1].TexCoord = new OpenTK.Vector2d(_One, _Zero); Layer1.Vertices[1].Normal = FaceNormal; Layer1.Vertices[1].Position = P1; Layer1.Vertices[2].TexCoord = new OpenTK.Vector2d(_One, _One); Layer1.Vertices[2].Normal = FaceNormal; Layer1.Vertices[2].Position = P2; Layer1.Vertices[3].TexCoord = new OpenTK.Vector2d(_Zero, _One); Layer1.Vertices[3].Normal = FaceNormal; Layer1.Vertices[3].Position = P3; Layer1.Vertices[4].TexCoord = new OpenTK.Vector2d(_Three, _Three); Layer1.Vertices[4].Normal = FaceNormal; Vector3d.Lerp( ref P0, ref P2, _Three, out Layer1.Vertices[4].Position ); Layer1.Vertices[5].TexCoord = new OpenTK.Vector2d(_Six, _Three); Layer1.Vertices[5].Normal = FaceNormal; Vector3d.Lerp( ref P1, ref P3, _Three, out Layer1.Vertices[5].Position ); Layer1.Vertices[6].TexCoord = new OpenTK.Vector2d(_Six, _Six); Layer1.Vertices[6].Normal = FaceNormal; Vector3d.Lerp( ref P0, ref P2, _Six, out Layer1.Vertices[6].Position ); Layer1.Vertices[7].TexCoord = new OpenTK.Vector2d(_Three, _Six); Layer1.Vertices[7].Normal = FaceNormal; Vector3d.Lerp( ref P1, ref P3, _Six, out Layer1.Vertices[7].Position ); #endregion Define Layer1 Vertices #region Define Layer1 Indices Layer1.Indices[0] = 0; Layer1.Indices[1] = 5; Layer1.Indices[2] = 4; Layer1.Indices[3] = 0; Layer1.Indices[4] = 1; Layer1.Indices[5] = 5; Layer1.Indices[6] = 5; Layer1.Indices[7] = 1; Layer1.Indices[8] = 2; Layer1.Indices[9] = 6; Layer1.Indices[10] = 5; Layer1.Indices[11] = 2; Layer1.Indices[12] = 7; Layer1.Indices[13] = 6; Layer1.Indices[14] = 2; Layer1.Indices[15] = 3; Layer1.Indices[16] = 7; Layer1.Indices[17] = 2; Layer1.Indices[18] = 0; Layer1.Indices[19] = 7; Layer1.Indices[20] = 3; Layer1.Indices[21] = 0; Layer1.Indices[22] = 4; Layer1.Indices[23] = 7; chunks.Add( Layer1 ); #endregion Define Layer1 Indices } #region Define Layer2 Vertices Chunk Layer2 = new Chunk( 12, 8 * 3 ); Vector3d T0, T1, T2, T3; Vector3d.Lerp( ref P0, ref P4, _Six, out T0 ); Vector3d.Lerp( ref P1, ref P5, _Six, out T1 ); Vector3d.Lerp( ref P2, ref P6, _Six, out T2 ); Vector3d.Lerp( ref P3, ref P7, _Six, out T3 ); Layer2.Vertices[0].TexCoord = new OpenTK.Vector2d(_Three, _Zero); Layer2.Vertices[0].Normal = FaceNormal; Vector3d.Lerp( ref T0, ref T1, _Three, out Layer2.Vertices[0].Position ); Layer2.Vertices[1].TexCoord = new OpenTK.Vector2d(_Six, _Zero); Layer2.Vertices[1].Normal = FaceNormal; Vector3d.Lerp( ref T0, ref T1, _Six, out Layer2.Vertices[1].Position ); Layer2.Vertices[3].TexCoord = new OpenTK.Vector2d(_One, _Three); Layer2.Vertices[3].Normal = FaceNormal; Vector3d.Lerp( ref T1, ref T2, _Three, out Layer2.Vertices[3].Position ); Layer2.Vertices[4].TexCoord = new OpenTK.Vector2d(_One, _Six); Layer2.Vertices[4].Normal = FaceNormal; Vector3d.Lerp( ref T1, ref T2, _Six, out Layer2.Vertices[4].Position ); Layer2.Vertices[6].TexCoord = new OpenTK.Vector2d(_Six, _One); Layer2.Vertices[6].Normal = FaceNormal; Vector3d.Lerp( ref T2, ref T3, _Three, out Layer2.Vertices[6].Position ); Layer2.Vertices[7].TexCoord = new OpenTK.Vector2d(_Three, _One); Layer2.Vertices[7].Normal = FaceNormal; Vector3d.Lerp( ref T2, ref T3, _Six, out Layer2.Vertices[7].Position ); Layer2.Vertices[9].TexCoord = new OpenTK.Vector2d(_Zero, _Six); Layer2.Vertices[9].Normal = FaceNormal; Vector3d.Lerp( ref T3, ref T0, _Three, out Layer2.Vertices[9].Position ); Layer2.Vertices[10].TexCoord = new OpenTK.Vector2d(_Zero, _Three); Layer2.Vertices[10].Normal = FaceNormal; Vector3d.Lerp( ref T3, ref T0, _Six, out Layer2.Vertices[10].Position ); Layer2.Vertices[2].TexCoord = new OpenTK.Vector2d(_Six, _Three); Layer2.Vertices[2].Normal = FaceNormal; Vector3d.Lerp( ref Layer2.Vertices[1].Position, ref Layer2.Vertices[6].Position, _Three, out Layer2.Vertices[2].Position ); Layer2.Vertices[5].TexCoord = new OpenTK.Vector2d(_Six, _Six); Layer2.Vertices[5].Normal = FaceNormal; Vector3d.Lerp( ref Layer2.Vertices[1].Position, ref Layer2.Vertices[6].Position, _Six, out Layer2.Vertices[5].Position ); Layer2.Vertices[8].TexCoord = new OpenTK.Vector2d(_Three, _Six); Layer2.Vertices[8].Normal = FaceNormal; Vector3d.Lerp( ref Layer2.Vertices[7].Position, ref Layer2.Vertices[0].Position, _Three, out Layer2.Vertices[8].Position ); Layer2.Vertices[11].TexCoord = new OpenTK.Vector2d(_Three, _Three); Layer2.Vertices[11].Normal = FaceNormal; Vector3d.Lerp( ref Layer2.Vertices[7].Position, ref Layer2.Vertices[0].Position, _Six, out Layer2.Vertices[11].Position ); #endregion Define Layer2 Vertices #region Define Layer2 Indices Layer2.Indices[0] = 0; Layer2.Indices[1] = 2; Layer2.Indices[2] = 11; Layer2.Indices[3] = 0; Layer2.Indices[4] = 1; Layer2.Indices[5] = 2; Layer2.Indices[6] = 2; Layer2.Indices[7] = 3; Layer2.Indices[8] = 4; Layer2.Indices[9] = 2; Layer2.Indices[10] = 4; Layer2.Indices[11] = 5; Layer2.Indices[12] = 5; Layer2.Indices[13] = 6; Layer2.Indices[14] = 8; Layer2.Indices[15] = 8; Layer2.Indices[16] = 6; Layer2.Indices[17] = 7; Layer2.Indices[18] = 11; Layer2.Indices[19] = 8; Layer2.Indices[20] = 10; Layer2.Indices[21] = 10; Layer2.Indices[22] = 8; Layer2.Indices[23] = 9; chunks.Add( Layer2 ); #endregion Define Layer2 Indices }
public ChamferCube(double Width, double Height, double Length, SubDivs subdivs, double radius) : base( ) { SlicedSphere.eSubdivisions sphereSubDivs = SlicedSphere.eSubdivisions.Zero; uint hoseSubDivs = 0; switch (subdivs) { case SubDivs.Zero: sphereSubDivs = SlicedSphere.eSubdivisions.Zero; hoseSubDivs = 0; break; case SubDivs.One: sphereSubDivs = SlicedSphere.eSubdivisions.One; hoseSubDivs = 1; break; case SubDivs.Two: sphereSubDivs = SlicedSphere.eSubdivisions.Two; hoseSubDivs = 3; break; case SubDivs.Three: sphereSubDivs = SlicedSphere.eSubdivisions.Three; hoseSubDivs = 7; break; case SubDivs.Four: sphereSubDivs = SlicedSphere.eSubdivisions.Four; hoseSubDivs = 15; break; } #region Temporary Storage List <Chunk> AllChunks = new List <Chunk>(); OpenTK.Graphics.OpenGL.BeginMode TemporaryMode; VertexT2dN3dV3d[] TemporaryVBO; uint[] TemporaryIBO; #endregion Temporary Storage Vector3d FrontTopRightEdge = new Vector3d(+Width - radius, +Height - radius, +Length - radius); Vector3d FrontTopLeftEdge = new Vector3d(+Width - radius, +Height - radius, -Length + radius); Vector3d FrontBottomRightEdge = new Vector3d(+Width - radius, -Height + radius, +Length - radius); Vector3d FrontBottomLeftEdge = new Vector3d(+Width - radius, -Height + radius, -Length + radius); Vector3d BackTopRightEdge = new Vector3d(-Width + radius, +Height - radius, +Length - radius); Vector3d BackTopLeftEdge = new Vector3d(-Width + radius, +Height - radius, -Length + radius); Vector3d BackBottomRightEdge = new Vector3d(-Width + radius, -Height + radius, +Length - radius); Vector3d BackBottomLeftEdge = new Vector3d(-Width + radius, -Height + radius, -Length + radius); #region 8 sliced Spheres SlicedSphere tempSphere; Vector3d tempVector = Vector3d.Zero; SlicedSphere.eDir[] tempEdge = new SlicedSphere.eDir[1]; for (int i = 0; i < 8; i++) { switch (i) { case 0: tempVector = FrontTopRightEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.FrontTopRight }; break; case 1: tempVector = FrontTopLeftEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.FrontTopLeft }; break; case 2: tempVector = FrontBottomRightEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.FrontBottomRight }; break; case 3: tempVector = FrontBottomLeftEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.FrontBottomLeft }; break; case 4: tempVector = BackBottomRightEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.BackBottomRight }; break; case 5: tempVector = BackBottomLeftEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.BackBottomLeft }; break; case 6: tempVector = BackTopRightEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.BackTopRight }; break; case 7: tempVector = BackTopLeftEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.BackTopLeft }; break; } tempSphere = new SlicedSphere(radius, tempVector, sphereSubDivs, tempEdge); tempSphere.GetArraysforVBO(out TemporaryMode, out TemporaryVBO, out TemporaryIBO); tempSphere.Dispose(); AllChunks.Add(new Chunk(ref TemporaryVBO, ref TemporaryIBO)); } #endregion 8 sliced Spheres #region 12 sliced Hoses SlicedHose tempHose; SlicedHose.eSide tempSide = SlicedHose.eSide.BackBottom; Vector3d tempHoseStart = Vector3d.Zero; Vector3d tempHoseEnd = Vector3d.Zero; for (int i = 0; i < 12; i++) { switch (i) { #region Around X Axis case 0: tempSide = SlicedHose.eSide.BottomRight; tempHoseStart = BackBottomRightEdge; tempHoseEnd = FrontBottomRightEdge; break; case 1: tempSide = SlicedHose.eSide.TopRight; tempHoseStart = BackTopRightEdge; tempHoseEnd = FrontTopRightEdge; break; case 2: tempSide = SlicedHose.eSide.TopLeft; tempHoseStart = BackTopLeftEdge; tempHoseEnd = FrontTopLeftEdge; break; case 3: tempSide = SlicedHose.eSide.BottomLeft; tempHoseStart = BackBottomLeftEdge; tempHoseEnd = FrontBottomLeftEdge; break; #endregion Around X Axis #region Around Y Axis case 4: tempSide = SlicedHose.eSide.FrontRight; tempHoseStart = FrontBottomRightEdge; tempHoseEnd = FrontTopRightEdge; break; case 5: tempSide = SlicedHose.eSide.BackRight; tempHoseStart = BackBottomRightEdge; tempHoseEnd = BackTopRightEdge; break; case 6: tempSide = SlicedHose.eSide.BackLeft; tempHoseStart = BackBottomLeftEdge; tempHoseEnd = BackTopLeftEdge; break; case 7: tempSide = SlicedHose.eSide.FrontLeft; tempHoseStart = FrontBottomLeftEdge; tempHoseEnd = FrontTopLeftEdge; break; #endregion Around Y Axis #region Around Z Axis case 8: tempSide = SlicedHose.eSide.FrontTop; tempHoseStart = FrontTopRightEdge; tempHoseEnd = FrontTopLeftEdge; break; case 9: tempSide = SlicedHose.eSide.BackTop; tempHoseStart = BackTopRightEdge; tempHoseEnd = BackTopLeftEdge; break; case 10: tempSide = SlicedHose.eSide.BackBottom; tempHoseStart = BackBottomRightEdge; tempHoseEnd = BackBottomLeftEdge; break; case 11: tempSide = SlicedHose.eSide.FrontBottom; tempHoseStart = FrontBottomRightEdge; tempHoseEnd = FrontBottomLeftEdge; break; #endregion Around Z Axis } tempHose = new SlicedHose(tempSide, hoseSubDivs, radius, tempHoseStart, tempHoseEnd); tempHose.GetArraysforVBO(out TemporaryMode, out TemporaryVBO, out TemporaryIBO); tempHose.Dispose(); AllChunks.Add(new Chunk(ref TemporaryVBO, ref TemporaryIBO)); } #endregion 12 sliced Hoses #region 6 quads for the sides VertexT2dN3dV3d[] tempVBO = new VertexT2dN3dV3d[4]; uint[] tempIBO = new uint[6] { 0, 1, 2, 0, 2, 3 }; // all quads share this IBO // all quads use the same texcoords tempVBO[0].TexCoord = new OpenTK.Vector2d(0.0, 1.0); tempVBO[1].TexCoord = new OpenTK.Vector2d(0.0, 0.0); tempVBO[2].TexCoord = new OpenTK.Vector2d(1.0, 0.0); tempVBO[3].TexCoord = new OpenTK.Vector2d(1.0, 1.0); // front face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = Vector3d.UnitX; tempVBO[0].Position = FrontTopRightEdge + new Vector3d(radius, 0.0, 0.0); tempVBO[1].Position = FrontBottomRightEdge + new Vector3d(radius, 0.0, 0.0); tempVBO[2].Position = FrontBottomLeftEdge + new Vector3d(radius, 0.0, 0.0); tempVBO[3].Position = FrontTopLeftEdge + new Vector3d(radius, 0.0, 0.0); AllChunks.Add(new Chunk(ref tempVBO, ref tempIBO)); // back face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = -Vector3d.UnitX; tempVBO[0].Position = BackTopLeftEdge - new Vector3d(radius, 0.0, 0.0); tempVBO[1].Position = BackBottomLeftEdge - new Vector3d(radius, 0.0, 0.0); tempVBO[2].Position = BackBottomRightEdge - new Vector3d(radius, 0.0, 0.0); tempVBO[3].Position = BackTopRightEdge - new Vector3d(radius, 0.0, 0.0); AllChunks.Add(new Chunk(ref tempVBO, ref tempIBO)); // top face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = Vector3d.UnitY; tempVBO[0].Position = BackTopRightEdge + new Vector3d(0.0, radius, 0.0); tempVBO[1].Position = FrontTopRightEdge + new Vector3d(0.0, radius, 0.0); tempVBO[2].Position = FrontTopLeftEdge + new Vector3d(0.0, radius, 0.0); tempVBO[3].Position = BackTopLeftEdge + new Vector3d(0.0, radius, 0.0); AllChunks.Add(new Chunk(ref tempVBO, ref tempIBO)); // bottom face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = -Vector3d.UnitY; tempVBO[0].Position = BackBottomLeftEdge - new Vector3d(0.0, radius, 0.0); tempVBO[1].Position = FrontBottomLeftEdge - new Vector3d(0.0, radius, 0.0); tempVBO[2].Position = FrontBottomRightEdge - new Vector3d(0.0, radius, 0.0); tempVBO[3].Position = BackBottomRightEdge - new Vector3d(0.0, radius, 0.0); AllChunks.Add(new Chunk(ref tempVBO, ref tempIBO)); // right face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = Vector3d.UnitZ; tempVBO[0].Position = BackTopRightEdge + new Vector3d(0.0, 0.0, radius); tempVBO[1].Position = BackBottomRightEdge + new Vector3d(0.0, 0.0, radius); tempVBO[2].Position = FrontBottomRightEdge + new Vector3d(0.0, 0.0, radius); tempVBO[3].Position = FrontTopRightEdge + new Vector3d(0.0, 0.0, radius); AllChunks.Add(new Chunk(ref tempVBO, ref tempIBO)); // left face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = -Vector3d.UnitZ; tempVBO[0].Position = FrontTopLeftEdge - new Vector3d(0.0, 0.0, radius); tempVBO[1].Position = FrontBottomLeftEdge - new Vector3d(0.0, 0.0, radius); tempVBO[2].Position = BackBottomLeftEdge - new Vector3d(0.0, 0.0, radius); tempVBO[3].Position = BackTopLeftEdge - new Vector3d(0.0, 0.0, radius); AllChunks.Add(new Chunk(ref tempVBO, ref tempIBO)); #endregion 6 quads for the sides #region Final Assembly of Chunks PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.Triangles; Chunk.GetArray(ref AllChunks, out VertexArray, out IndexArray); AllChunks.Clear(); #endregion Final Assembly of Chunks }