/// <summary> /// Creates the geometry to draw a spot light /// </summary> /// <param name="verts">Vertex list</param> /// <param name="indx">Index list</param> private void CreateSpotLight(List <VertexPosition> verts, List <uint> indx) { GeometryUtil.CreateSphere( 1, 16, 16, out Vector3[] cv, out uint[] indices); var vertices = new VertexPosition[cv.Length]; for (int i = 0; i < vertices.Length; i++) { vertices[i] = new VertexPosition() { Position = cv[i] }; } this.spotLightGeometry.Offset = indx.Count; this.spotLightGeometry.IndexCount = indices.Length; //Sum offsets for (int i = 0; i < indices.Length; i++) { indices[i] += (uint)verts.Count; } verts.AddRange(vertices); indx.AddRange(indices); }
public Line2D(Vector3 p1, Vector3 p2) { vertexBuffer = new VertexBuffer(GraphicsDeviceHolder.Device, sizeof(float) * 6, BufferUsage.None); var data = new VertexPosition[] { new VertexPosition(p1), new VertexPosition(p2) }; vertexBuffer.SetData <VertexPosition>(data); }
private void GenerateMeshes() { var vertices = new VertexPosition[this.linePoints.Count * VerticesPerPoint]; var colliderVertices = new Vector2[this.linePoints.Count]; for (int i = 0, j = 0; i < this.linePoints.Count; i++) { var currentPoint = this.linePoints[i]; var currentPosition = new Vector3(currentPoint.Position.X, -currentPoint.Position.Y, 0); colliderVertices[i] = currentPosition.ToVector2(); vertices[j++] = new VertexPosition(currentPosition); currentPosition.Y = 0; vertices[j++] = new VertexPosition(currentPosition); } var center = this.boundingBox.Center.ToVector2(); this.collider.Offset = new Vector2(-center.X, center.Y); this.collider.Vertices = colliderVertices; var indices = new ushort[this.linePoints.Count * IndicesPerPoint]; for (int i = 1; i < indices.Length; i++) { indices[i] = (ushort)i; } this.AddMesh(vertices, indices, PrimitiveType.TriangleStrip); }
protected static int ToPointsBuffer ( Rhino.Geometry.Point point, out VertexFormatBits vertexFormatBits, out VertexBuffer vb, out int vertexCount, out IndexBuffer ib ) { int pointsCount = 0; if (point.Location.IsValid) { pointsCount = 1; vertexCount = 1; vertexFormatBits = VertexFormatBits.Position; vb = new VertexBuffer(pointsCount * VertexPosition.GetSizeInFloats()); vb.Map(pointsCount * VertexPosition.GetSizeInFloats()); using (var vstream = vb.GetVertexStreamPosition()) { vstream.AddVertex(new VertexPosition(RawEncoder.ToHost(point.Location))); } vb.Unmap(); ib = IndexPointsBuffer(pointsCount); } else { vertexFormatBits = 0; vb = null; vertexCount = 0; ib = null; } return(pointsCount); }
private void AddVertex(VertexPosition vert) { Array.Resize(ref Vertices, Vertices.Length + 1); Vertices[Vertices.Length - 1] = vert; NeedToRecreateVertBuffer = true; }
public override bool Add(Geometry geometry) { if (count >= BatchSize) { return(false); } if (!geometry.GeometryData.Equals(sharedGeometry) || !geometry.RenderOptions.Equals(sharedRenderOptions)) { return(false); } VertexTransform transform = geometry.GetVertexTransform(); VertexColor color = geometry.GetVertexColor(); for (int i = 0; i < TotalVertices; i++) { vertexPositions[index + i] = new VertexPosition(sharedGeometry.Mesh.Vertices[i]); transforms[index + i] = transform; colors[index + i] = color; } dataModified = true; index += (uint)TotalVertices; count++; totalPrimitives += (uint)TotalTriangles; return(true); }
// A helper function, analogous to ProcessFaces. private void ProcessEdges(RenderingPassBufferStorage bufferStorage) { List <IList <XYZ> > edges = bufferStorage.EdgeXYZs; if (edges.Count == 0) { return; } // Edges are encoded as line segment primitives whose vertices contain only position information. bufferStorage.FormatBits = VertexFormatBits.Position; int edgeVertexBufferSizeInFloats = VertexPosition.GetSizeInFloats() * bufferStorage.VertexBufferCount; List <int> numVerticesInEdgesBefore = new List <int>(); numVerticesInEdgesBefore.Add(0); bufferStorage.VertexBuffer = new VertexBuffer(edgeVertexBufferSizeInFloats); bufferStorage.VertexBuffer.Map(edgeVertexBufferSizeInFloats); { VertexStreamPosition vertexStream = bufferStorage.VertexBuffer.GetVertexStreamPosition(); foreach (IList <XYZ> xyzs in edges) { foreach (XYZ vertex in xyzs) { vertexStream.AddVertex(new VertexPosition(vertex + m_offset)); } numVerticesInEdgesBefore.Add(numVerticesInEdgesBefore.Last() + xyzs.Count); } } bufferStorage.VertexBuffer.Unmap(); int edgeNumber = 0; bufferStorage.IndexBufferCount = bufferStorage.PrimitiveCount * IndexLine.GetSizeInShortInts(); int indexBufferSizeInShortInts = 1 * bufferStorage.IndexBufferCount; bufferStorage.IndexBuffer = new IndexBuffer(indexBufferSizeInShortInts); bufferStorage.IndexBuffer.Map(indexBufferSizeInShortInts); { IndexStreamLine indexStream = bufferStorage.IndexBuffer.GetIndexStreamLine(); foreach (IList <XYZ> xyzs in edges) { int startIndex = numVerticesInEdgesBefore[edgeNumber]; for (int i = 1; i < xyzs.Count; i++) { // Add two indices that define a line segment. indexStream.AddLine(new IndexLine((int)(startIndex + i - 1), (int)(startIndex + i))); } edgeNumber++; } } bufferStorage.IndexBuffer.Unmap(); bufferStorage.VertexFormat = new VertexFormat(bufferStorage.FormatBits); bufferStorage.EffectInstance = new EffectInstance(bufferStorage.FormatBits); }
public BoundingBox(GraphicsDevice device, Vector3 position, Vector3 scale, Color color) : base(device, position, scale) { Color = color; // Vertices for creating outlines of bounding box VertexPosition[] boundingBox = new VertexPosition[8] { new VertexPosition(new Vector3(-1, -1, 1)), new VertexPosition(new Vector3(-1, 1, 1)), new VertexPosition(new Vector3(1, 1, 1)), new VertexPosition(new Vector3(1, -1, 1)), new VertexPosition(new Vector3(1, -1, -1)), new VertexPosition(new Vector3(-1, -1, -1)), new VertexPosition(new Vector3(-1, 1, -1)), new VertexPosition(new Vector3(1, 1, -1)), }; linesVertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPosition), boundingBox.Length, BufferUsage.WriteOnly); linesVertexBuffer.SetData <VertexPosition>(boundingBox); short[] boundingBoxIndices = new short[48] { 0, 1, 1, 2, 2, 3, 3, 0, 3, 4, 4, 7, 7, 2, 2, 3, 4, 5, 5, 6, 6, 7, 7, 4, 5, 0, 0, 1, 1, 6, 6, 5, 1, 2, 2, 7, 7, 6, 6, 1, 0, 3, 3, 4, 4, 5, 5, 0 }; linesIndexBuffer = new IndexBuffer(GraphicsDevice, typeof(short), boundingBoxIndices.Length, BufferUsage.WriteOnly); linesIndexBuffer.SetData <short>(boundingBoxIndices); }
/// <summary> /// Creates a Wire Cube. /// </summary> /// <param name="graphicsDevice">A GraphicsDevice to bind the geometry.</param> public CubeGizmoGeometry(GraphicsDevice graphicsDevice) : base(graphicsDevice) { var vertices = new VertexPosition[8] { new VertexPosition(new Vector3(0.5f, 0.5f, 0.5f)), new VertexPosition(new Vector3(-0.5f, 0.5f, 0.5f)), new VertexPosition(new Vector3(0.5f, -0.5f, 0.5f)), new VertexPosition(new Vector3(-0.5f, -0.5f, 0.5f)), new VertexPosition(new Vector3(0.5f, 0.5f, -0.5f)), new VertexPosition(new Vector3(-0.5f, 0.5f, -0.5f)), new VertexPosition(new Vector3(0.5f, -0.5f, -0.5f)), new VertexPosition(new Vector3(-0.5f, -0.5f, -0.5f)) }; var indices = new ushort[24] { 0, 1, 0, 2, 1, 3, 3, 2, 4, 5, 4, 6, 5, 7, 7, 6, 0, 4, 1, 5, 2, 6, 3, 7 }; InitializeVertices(vertices); InitializeIndices(indices); }
public virtual void CopyToVertexArray(VertexPosition[] vertexArray, int startIndex) { for (int i = 0; i < VertexCount; i++) { vertexArray[startIndex + i] = new VertexPosition(ReadOnlyVertices[i].ToVector3()); } }
/// <summary> /// Constructs a Wire Sphere. /// </summary> /// <param name="graphicsDevice">Graphics Device to bind the geometry to.</param> /// <param name="subdivisions">The amount of the subdivisions each sphere ring will have.</param> public SphereGizmoGeometry(GraphicsDevice graphicsDevice, int subdivisions) : base(graphicsDevice) { var positions = GeneratePolygonPositions(subdivisions); var originalIndices = GeneratePolygonIndices(subdivisions); var subdivisionsTimesTwo = subdivisions * 2; var indices = new ushort[subdivisions * 6]; Array.Copy(originalIndices, 0, indices, 0, subdivisionsTimesTwo); Array.Copy(originalIndices.Select(index => (ushort)(index + subdivisions)).ToArray(), 0, indices, subdivisionsTimesTwo, subdivisionsTimesTwo); Array.Copy(originalIndices.Select(index => (ushort)(index + subdivisionsTimesTwo)).ToArray(), 0, indices, subdivisionsTimesTwo * 2, subdivisionsTimesTwo); var vertices = new VertexPosition[subdivisions * 3]; positions .Select(position => new VertexPosition(new Vector3(position, 0f))) .ToArray() .CopyTo(vertices, 0); Array.Copy(positions .Select(position => new VertexPosition(new Vector3(position.Y, 0f, position.X))) .ToArray(), 0, vertices, subdivisions, subdivisions); Array.Copy(positions .Select(position => new VertexPosition(new Vector3(0f, position.Y, position.X))) .ToArray(), 0, vertices, subdivisionsTimesTwo, subdivisions); InitializeVertices(vertices); InitializeIndices(indices); }
public static ModelMeshPart LoadModel(GraphicsDevice graphicsDevice) { const int primitiveCount = 36; VertexPosition[] vertices = new VertexPosition[] { new VertexPosition(new Vector3(-1.0f, -1.0f, 1.0f)), new VertexPosition(new Vector3(1.0f, -1.0f, 1.0f)), new VertexPosition(new Vector3(1.0f, 1.0f, 1.0f)), new VertexPosition(new Vector3(-1.0f, 1.0f, 1.0f)), // back new VertexPosition(new Vector3(-1.0f, -1.0f, -1.0f)), new VertexPosition(new Vector3(1.0f, -1.0f, -1.0f)), new VertexPosition(new Vector3(1.0f, 1.0f, -1.0f)), new VertexPosition(new Vector3(-1.0f, 1.0f, -1.0f)) }; short[] indices = new short[primitiveCount] { // front 0, 1, 2, 2, 3, 0, // right 1, 5, 6, 6, 2, 1, // back 7, 6, 5, 5, 4, 7, // left 4, 0, 3, 3, 7, 4, // bottom 4, 5, 1, 1, 0, 4, // top 3, 2, 6, 6, 7, 3 }; VertexBuffer vertexBuffer; IndexBuffer indexBuffer; ModelMeshPart modelMeshPart; vertexBuffer = new VertexBuffer(graphicsDevice, VertexPosition.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);; vertexBuffer.SetData(vertices); indexBuffer = new IndexBuffer(graphicsDevice, typeof(short), indices.Length, BufferUsage.WriteOnly); indexBuffer.SetData(indices); modelMeshPart = new ModelMeshPart() { IndexBuffer = indexBuffer, PrimitiveCount = primitiveCount, StartIndex = 0, VertexBuffer = vertexBuffer }; return(modelMeshPart); }
public OBJFile(FileStream stream) { this.vertices = new List <VertexPosition>(); this.triangleFaces = new List <TriangleFace>(); this.quadFaces = new List <QuadFace>(); StreamReader reader = new StreamReader(stream); string text = reader.ReadToEnd(); text = text.Replace("\r", ""); text = text.Replace('.', ','); string[] lines = text.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (string line in lines) { string[] words = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); //if (words[0] == "v") //{ // float x = float.Parse(words[1]); // float y = float.Parse(words[2]); // float z = float.Parse(words[3]); // VertexPosition coord = new VertexPosition(x, y, z); // this.vertices.Add(coord); //} switch (words[0]) { case "v": float x = float.Parse(words[1]); float y = float.Parse(words[2]); float z = float.Parse(words[3]); VertexPosition coord = new VertexPosition(x, y, z); this.vertices.Add(coord); break; case "f": if (words.Length == 5) { int a4 = int.Parse(words[1].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); int b4 = int.Parse(words[2].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); int c4 = int.Parse(words[3].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); int d4 = int.Parse(words[4].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); QuadFace face4 = new QuadFace(a4, b4, c4, d4); this.quadFaces.Add(face4); break; } int a = int.Parse(words[1].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); int b = int.Parse(words[2].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); int c = int.Parse(words[3].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); TriangleFace face = new TriangleFace(a, b, c); this.triangleFaces.Add(face); break; } } this.mesh = new MeshBase(); this.mesh.QuadFaces = this.quadFaces; this.mesh.TriangleFaces = this.triangleFaces; this.mesh.Vertices = this.vertices; string[] path = stream.Name.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); this.mesh.Name = HeadFile.ReplaceExtention(path[path.Length - 1], ""); }
/// <summary> /// Creates a Wire Cylinder with a number of subdivisions for the top and bottom. /// </summary> /// <param name="device">The device to bind geometry to.</param> /// <param name="subdivisions">The number of subdivisions to </param> public CylinderGizmoGeometry(GraphicsDevice device, int subdivisions) : base(device) { var positions = GeneratePolygonPositions(subdivisions); var originalIndices = GeneratePolygonIndices(subdivisions); var subdivisionsTimesTwo = subdivisions * 2; // Lines for each circle, and four lines joining them var indices = new ushort[subdivisions * 6 + 8]; Array.Copy(originalIndices, 0, indices, 0, subdivisionsTimesTwo); Array.Copy(originalIndices.Select(index => (ushort)(index + subdivisions)).ToArray(), 0, indices, subdivisionsTimesTwo, subdivisionsTimesTwo); Array.Copy(originalIndices.Select(index => (ushort)(index + subdivisionsTimesTwo)).ToArray(), 0, indices, subdivisionsTimesTwo * 2, subdivisionsTimesTwo); var index = subdivisions * 6; var firstQuadrant = (ushort)(subdivisions / 4); var firstQuadrantAdded = (ushort)(firstQuadrant + subdivisions); var secondQuadrant = (ushort)(subdivisions / 2); var secondQuadrantAdded = (ushort)(secondQuadrant + subdivisions); var thirdQuadrant = (ushort)(firstQuadrant + secondQuadrant); var thirdQuadrantAdded = (ushort)(thirdQuadrant + subdivisions); // Joining lines indices[index] = 0; index++; indices[index] = (ushort)subdivisions; index++; indices[index] = firstQuadrant; index++; indices[index] = firstQuadrantAdded; index++; indices[index] = secondQuadrant; index++; indices[index] = secondQuadrantAdded; index++; indices[index] = thirdQuadrant; index++; indices[index] = thirdQuadrantAdded; index++; var vertices = new VertexPosition[subdivisions * 3]; positions .Select(position => new VertexPosition(new Vector3(position.X, 1f, position.Y))) .ToArray() .CopyTo(vertices, 0); Array.Copy(positions .Select(position => new VertexPosition(new Vector3(position.X, -1f, position.Y))) .ToArray(), 0, vertices, subdivisions, subdivisions); Array.Copy(positions .Select(position => new VertexPosition(new Vector3(position.X, 0f, position.Y))) .ToArray(), 0, vertices, subdivisionsTimesTwo, subdivisions); InitializeVertices(vertices); InitializeIndices(indices); }
void GenerateGeometry(GraphicsDevice device) { VertexPosition[] vertices = new VertexPosition[24]; vertices[0].Position = new Vector3(-1, 1, -1); vertices[1].Position = new Vector3(1, 1, -1); vertices[2].Position = new Vector3(-1, 1, 1); vertices[3].Position = new Vector3(1, 1, 1); vertices[4].Position = new Vector3(-1, -1, 1); vertices[5].Position = new Vector3(1, -1, 1); vertices[6].Position = new Vector3(-1, -1, -1); vertices[7].Position = new Vector3(1, -1, -1); vertices[8].Position = new Vector3(-1, 1, -1); vertices[9].Position = new Vector3(-1, 1, 1); vertices[10].Position = new Vector3(-1, -1, -1); vertices[11].Position = new Vector3(-1, -1, 1); vertices[12].Position = new Vector3(-1, 1, 1); vertices[13].Position = new Vector3(1, 1, 1); vertices[14].Position = new Vector3(-1, -1, 1); vertices[15].Position = new Vector3(1, -1, 1); vertices[16].Position = new Vector3(1, 1, 1); vertices[17].Position = new Vector3(1, 1, -1); vertices[18].Position = new Vector3(1, -1, 1); vertices[19].Position = new Vector3(1, -1, -1); vertices[20].Position = new Vector3(1, 1, -1); vertices[21].Position = new Vector3(-1, 1, -1); vertices[22].Position = new Vector3(1, -1, -1); vertices[23].Position = new Vector3(-1, -1, -1); _geometryBuffer = new VertexBuffer(device, VertexPosition.VertexDeclaration, 24, BufferUsage.WriteOnly); _geometryBuffer.SetData(vertices); int[] indices = new int[36]; indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 1; indices[4] = 3; indices[5] = 2; indices[6] = 4; indices[7] = 5; indices[8] = 6; indices[9] = 5; indices[10] = 7; indices[11] = 6; indices[12] = 8; indices[13] = 9; indices[14] = 10; indices[15] = 9; indices[16] = 11; indices[17] = 10; indices[18] = 12; indices[19] = 13; indices[20] = 14; indices[21] = 13; indices[22] = 15; indices[23] = 14; indices[24] = 16; indices[25] = 17; indices[26] = 18; indices[27] = 17; indices[28] = 19; indices[29] = 18; indices[30] = 20; indices[31] = 21; indices[32] = 22; indices[33] = 21; indices[34] = 23; indices[35] = 22; _indexBuffer = new IndexBuffer(device, typeof(int), 36, BufferUsage.WriteOnly); _indexBuffer.SetData(indices); }
public static SharpDX.Direct3D11.Buffer CreateVertexBuffer(Device device, Kinect2.Kinect2Calibration kinect2Calibration) { // generate depthFrameToCameraSpace table var depthFrameToCameraSpaceTable = kinect2Calibration.ComputeDepthFrameToCameraSpaceTable(depthImageWidth, depthImageHeight); int numVertices = 6 * (depthImageWidth - 1) * (depthImageHeight - 1); var vertices = new VertexPosition[numVertices]; Int3[] quadOffsets = new Int3[] { new Int3(0, 0, 0), new Int3(1, 0, 0), new Int3(0, 1, 0), new Int3(1, 0, 0), new Int3(1, 1, 0), new Int3(0, 1, 0), }; int vertexIndex = 0; for (int y = 0; y < depthImageHeight - 1; y++) { for (int x = 0; x < depthImageWidth - 1; x++) { for (int i = 0; i < 6; i++) { int vertexX = x + quadOffsets[i].X; int vertexY = y + quadOffsets[i].Y; var point = depthFrameToCameraSpaceTable[depthImageWidth * vertexY + vertexX]; var vertex = new VertexPosition(); vertex.position = new SharpDX.Vector4(point.X, point.Y, vertexX, vertexY); vertices[vertexIndex++] = vertex; } } } var stream = new DataStream(numVertices * VertexPosition.SizeInBytes, true, true); stream.WriteRange(vertices); stream.Position = 0; var vertexBufferDesc = new BufferDescription() { BindFlags = BindFlags.VertexBuffer, CpuAccessFlags = CpuAccessFlags.None, Usage = ResourceUsage.Default, SizeInBytes = numVertices * VertexPosition.SizeInBytes, }; var vertexBuffer = new SharpDX.Direct3D11.Buffer(device, stream, vertexBufferDesc); stream.Dispose(); return(vertexBuffer); }
public static List <Vector3> GetPath(Vector3 start, Vector3 exit, bool[] obstaclesArray, MapGrid grid) { VertexPosition startVertex = new VertexPosition(start); VertexPosition exitVertex = new VertexPosition(exit); List <Vector3> path = new List <Vector3>(); List <VertexPosition> openedList = new List <VertexPosition>(); HashSet <VertexPosition> closedList = new HashSet <VertexPosition>(); startVertex.estimatedCost = ManhattanDistance(startVertex, exitVertex); openedList.Add(startVertex); VertexPosition currentVertex = null; while (openedList.Count > 0) { openedList.Sort(); currentVertex = openedList[0]; if (currentVertex.Equals(exitVertex)) { while (currentVertex != startVertex) { path.Add(currentVertex.Position); currentVertex = currentVertex.previousVertex; } path.Reverse(); break; } var arrayOfNeighbors = FindNeighborsFor(currentVertex, grid, obstaclesArray); foreach (var neighbor in arrayOfNeighbors) { if (neighbor == null || closedList.Contains(neighbor)) { continue; } if (neighbor.IsTaken == false) { var totalCost = currentVertex.totalCost + 1; var neighborEstimatedCost = ManhattanDistance(neighbor, exitVertex); neighbor.totalCost = totalCost; neighbor.previousVertex = currentVertex; neighbor.estimatedCost = totalCost + neighborEstimatedCost; if (openedList.Contains(neighbor) == false) { openedList.Add(neighbor); } } } closedList.Add(currentVertex); openedList.Remove(currentVertex); } return(path); }
/// <summary> /// Builds a new truncated cone buffer. /// The cone is aligned to the x axis. /// </summary> /// <param name="description">The description used to build the cone</param> /// <param name="tesselation">The tesselation, must be greater than 2</param> public VertexPosition[] Build(TruncatedConeDescription description, int tesselation = 32) { var sections = description.Sections; if (sections.Length < 2) { throw new ArgumentException("sections must contain more than 1 element."); } if (tesselation < 3) { throw new ArgumentException("tesselation must be greater than 2."); } // build tesselation angles var tessInverse = (float)1 / tesselation; var tesselationAngles = new Vector2[tesselation]; for (var i = 0; i < tesselationAngles.Length; i++) { var quat = Quaternion.RotationAxis(Vector3.BackwardRH, tessInverse * i * MathUtil.TwoPi); var transformed = Vector3.Transform(Vector3.Up, quat); tesselationAngles[i] = new Vector2(transformed.X, transformed.Y);//discard x value } var vertCount = (sections.Length - 1) * tesselation * 6; var buffer = new VertexPosition[vertCount]; // the first time this gets used it increments to 0 int bufferIndex = -1; var prevSection = sections[0]; for (var i = 1; i < description.Sections.Length; i++) { var section = description.Sections[i]; // start at the last item var prevAngle = tesselationAngles.Last(); for (var j = 0; j < tesselation; j++) { var angle = tesselationAngles[j]; buffer[++bufferIndex] = GetVertex(prevSection, angle); buffer[++bufferIndex] = GetVertex(section, angle); buffer[++bufferIndex] = GetVertex(prevSection, prevAngle); buffer[++bufferIndex] = GetVertex(section, angle); buffer[++bufferIndex] = GetVertex(section, prevAngle); buffer[++bufferIndex] = GetVertex(prevSection, prevAngle); prevAngle = tesselationAngles[j]; } prevSection = sections[i]; } Debug.Assert(bufferIndex + 1 == buffer.Length); return(buffer); }
public OBJFile(FileStream stream) { this.vertices = new List<VertexPosition>(); this.triangleFaces = new List<TriangleFace>(); this.quadFaces = new List<QuadFace>(); StreamReader reader = new StreamReader(stream); string text = reader.ReadToEnd(); text = text.Replace("\r", ""); text = text.Replace('.', ','); string[] lines = text.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (string line in lines) { string[] words = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); //if (words[0] == "v") //{ // float x = float.Parse(words[1]); // float y = float.Parse(words[2]); // float z = float.Parse(words[3]); // VertexPosition coord = new VertexPosition(x, y, z); // this.vertices.Add(coord); //} switch (words[0]) { case "v": float x = float.Parse(words[1]); float y = float.Parse(words[2]); float z = float.Parse(words[3]); VertexPosition coord = new VertexPosition(x, y, z); this.vertices.Add(coord); break; case "f": if (words.Length == 5) { int a4 = int.Parse(words[1].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); int b4 = int.Parse(words[2].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); int c4 = int.Parse(words[3].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); int d4 = int.Parse(words[4].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); QuadFace face4 = new QuadFace(a4, b4, c4, d4); this.quadFaces.Add(face4); break; } int a = int.Parse(words[1].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); int b = int.Parse(words[2].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); int c = int.Parse(words[3].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0]); TriangleFace face = new TriangleFace(a, b, c); this.triangleFaces.Add(face); break; } } this.mesh = new MeshBase(); this.mesh.QuadFaces = this.quadFaces; this.mesh.TriangleFaces = this.triangleFaces; this.mesh.Vertices = this.vertices; string[] path = stream.Name.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); this.mesh.Name = HeadFile.ReplaceExtention(path[path.Length - 1],""); }
public QuadtreeLeaf(BoundingBox boundingBox, Color[] heightMapColors, GraphicsDevice graphicsDevice) : base(boundingBox) { float tileSize = 2; float maxHeight = 100.0f; int heightMapWidth = 2048; int sx = (int)(boundingBox.Min.X / tileSize); int sy = (int)(boundingBox.Min.Z / tileSize); int width = (int)((boundingBox.Max.X - boundingBox.Min.X) / tileSize) + (sx < 2016 ? 1 : 0); int height = (int)((boundingBox.Max.Z - boundingBox.Min.Z) / tileSize) + (sy < 2016 ? 1 : 0); // vertex buffer generation VertexPosition[] vertices = new VertexPosition[width * height]; this.boundingBox.Min.Y = maxHeight; this.boundingBox.Max.Y = 0; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { float depth = heightMapColors[(sy + y) * heightMapWidth + sx + x].R / 255.0f; vertices[y * width + x] = new VertexPosition(new Vector3(sx + x, depth, sy + y)); depth *= maxHeight; this.boundingBox.Min.Y = MathHelper.Min(this.boundingBox.Min.Y, depth); this.boundingBox.Max.Y = MathHelper.Max(this.boundingBox.Max.Y, depth); } } vertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPosition), vertices.Length, BufferUsage.WriteOnly); vertexBuffer.SetData <VertexPosition>(vertices); // index buffer generation int indicesPerRow = width * 2 + 2; int[] indices = new int[indicesPerRow * (height - 1)]; for (int i = 0; i < height - 1; ++i) { int index; for (int ii = 0; ii < width; ++ii) { index = i * indicesPerRow + ii * 2; indices[index] = ((i) * width + ii); indices[index + 1] = ((i + 1) * width + ii); //Debug.WriteLine(((i + ii % 2) * width + ii) + " " + ((i + 1 - ii % 2) * width + ii)); } index = i * indicesPerRow + width * 2; indices[index] = indices[index - 1]; indices[index + 1] = ((i + 1) * width); } indexBuffer = new IndexBuffer(graphicsDevice, typeof(int), indices.Length, BufferUsage.WriteOnly); indexBuffer.SetData(indices); }
public void AddTri(Vector3 a, Vector3 b, Vector3 c) { //var dir = Vector3.Cross(b - a, c - a); //var norm = Vector3.Normalize(dir); var vertA = new VertexPosition(a); var vertB = new VertexPosition(b); var vertC = new VertexPosition(c); int vertIndexA = Array.IndexOf(Vertices, vertA); int vertIndexB = Array.IndexOf(Vertices, vertB); int vertIndexC = Array.IndexOf(Vertices, vertC); //If vertex A can't be recycled from an old one, make a new one. if (vertIndexA == -1) { AddVertex(vertA); vertIndexA = Vertices.Length - 1; } //If vertex B can't be recycled from an old one, make a new one. if (vertIndexB == -1) { AddVertex(vertB); vertIndexB = Vertices.Length - 1; } //If vertex C can't be recycled from an old one, make a new one. if (vertIndexC == -1) { AddVertex(vertC); vertIndexC = Vertices.Length - 1; } AddIndex(vertIndexA); AddIndex(vertIndexB); AddIndex(vertIndexC); //if (NeedToRecreateVertBuffer) //{ // VertBuffer = new VertexBuffer(GFX.Device, // typeof(VertexPositionColor), Vertices.Length, BufferUsage.WriteOnly); // VertBuffer.SetData(Vertices); // NeedToRecreateVertBuffer = false; //} //if (NeedToRecreateIndexBuffer) //{ // IndexBuffer = new IndexBuffer(GFX.Device, IndexElementSize.ThirtyTwoBits, Indices.Length, BufferUsage.WriteOnly); // IndexBuffer.SetData(Indices); // NeedToRecreateIndexBuffer = false; //} }
public static List <Vector3> Verticies(this ModelMesh mesh) { List <Vector3> verticies = new List <Vector3>(); foreach (ModelMeshPart meshPart in mesh.MeshParts) { VertexPosition[] v = new VertexPosition[meshPart.NumVertices]; meshPart.VertexBuffer.GetData(v); verticies.AddRange(v.Select(x => x.Position)); } return(verticies); }
public IEnumerable <Vector3> GetPrimitivePositions() { Vector3[] result = new Vector3[primitiveCount]; for (int i = 0; i < primitiveCount; i++) { T copy = vertices[i]; VertexPosition c = (VertexPosition)(object)copy; result[i] = c.Position; } return(result); }
public VertexPosition[] ToVertexPositions() { var vPos = new VertexPosition[this.Vertices.Count]; var i = 0; foreach (var vertex in this.Vertices) { vPos[i] = new VertexPosition(vertex); } return(vPos); }
/// <summary> /// Creates a wire Line Segment. /// </summary> /// <param name="graphicsDevice">Graphics Device to bind the geometry to.</param> public LineSegmentGizmoGeometry(GraphicsDevice graphicsDevice) : base(graphicsDevice) { var vertices = new VertexPosition[2] { new VertexPosition(Vector3.Zero), new VertexPosition(Vector3.One), }; var indices = new ushort[2] { 0, 1 }; InitializeVertices(vertices); InitializeIndices(indices); }
public void Resize(int w, int h) { if (buf != null) { buf.Dispose(); } width = w; height = h; buf = new RenderTarget2D(gdev, w, h, false, format, DepthFormat.Depth24); fullScreen[0] = new VertexPosition(new Vector3(0, 0, smallNum)); fullScreen[1] = new VertexPosition(new Vector3(w, 0, smallNum)); fullScreen[2] = new VertexPosition(new Vector3(0, h, smallNum)); fullScreen[3] = new VertexPosition(new Vector3(w, h, smallNum)); }
VertexPosition[] GenerateVerts(Vector2[] points) { // we need to make tris from the points. all points will be shared with the center (0,0) var verts = new VertexPosition[points.Length + 1]; // the first point is the center so we start at 1 for (var i = 1; i <= points.Length; i++) { verts[i].Position.X = points[i - 1].X; verts[i].Position.Y = points[i - 1].Y; } return(verts); }
public static VertexPosition[] CreateSkyBoxVerticies() { var rv = new VertexPosition[36]; rv[0].Position = new Vector3(-1.0f, 1.0f, -1.0f); rv[1].Position = new Vector3(-1.0f, -1.0f, -1.0f); rv[2].Position = new Vector3(1.0f, -1.0f, -1.0f); rv[3].Position = new Vector3(1.0f, -1.0f, -1.0f); rv[4].Position = new Vector3(1.0f, 1.0f, -1.0f); rv[5].Position = new Vector3(-1.0f, 1.0f, -1.0f); rv[6].Position = new Vector3(-1.0f, -1.0f, 1.0f); rv[7].Position = new Vector3(-1.0f, -1.0f, -1.0f); rv[8].Position = new Vector3(-1.0f, 1.0f, -1.0f); rv[9].Position = new Vector3(-1.0f, 1.0f, -1.0f); rv[10].Position = new Vector3(-1.0f, 1.0f, 1.0f); rv[11].Position = new Vector3(-1.0f, -1.0f, 1.0f); rv[12].Position = new Vector3(1.0f, -1.0f, -1.0f); rv[13].Position = new Vector3(1.0f, -1.0f, 1.0f); rv[14].Position = new Vector3(1.0f, 1.0f, 1.0f); rv[15].Position = new Vector3(1.0f, 1.0f, 1.0f); rv[16].Position = new Vector3(1.0f, 1.0f, -1.0f); rv[17].Position = new Vector3(1.0f, -1.0f, -1.0f); rv[18].Position = new Vector3(-1.0f, -1.0f, 1.0f); rv[19].Position = new Vector3(-1.0f, 1.0f, 1.0f); rv[20].Position = new Vector3(1.0f, 1.0f, 1.0f); rv[21].Position = new Vector3(1.0f, 1.0f, 1.0f); rv[22].Position = new Vector3(1.0f, -1.0f, 1.0f); rv[23].Position = new Vector3(-1.0f, -1.0f, 1.0f); rv[24].Position = new Vector3(-1.0f, 1.0f, -1.0f); rv[25].Position = new Vector3(1.0f, 1.0f, -1.0f); rv[26].Position = new Vector3(1.0f, 1.0f, 1.0f); rv[27].Position = new Vector3(1.0f, 1.0f, 1.0f); rv[28].Position = new Vector3(-1.0f, 1.0f, 1.0f); rv[29].Position = new Vector3(-1.0f, 1.0f, -1.0f); rv[30].Position = new Vector3(-1.0f, -1.0f, -1.0f); rv[31].Position = new Vector3(-1.0f, -1.0f, 1.0f); rv[32].Position = new Vector3(1.0f, -1.0f, -1.0f); rv[33].Position = new Vector3(1.0f, -1.0f, -1.0f); rv[34].Position = new Vector3(-1.0f, -1.0f, 1.0f); rv[35].Position = new Vector3(1.0f, -1.0f, 1.0f); return(rv); }
private static VertexPosition[] FindNeighborsFor(VertexPosition currentVertex, MapGrid grid, bool[] obstaclesArray) { VertexPosition[] arrayOfNeighbors = new VertexPosition[4]; int arrayIndex = 0; foreach (var possibleNeighbor in VertexPosition.possibleNeighbors) { Vector3 position = new Vector3(currentVertex.X + possibleNeighbor.x, 0, currentVertex.Z + possibleNeighbor.y); if (grid.IsCellValid(position.x, position.z)) { int index = grid.CalculateIndexFromCoordinates(position.x, position.z); arrayOfNeighbors[arrayIndex] = new VertexPosition(position, obstaclesArray[index]); arrayIndex++; } } return(arrayOfNeighbors); }
public static int GetVertexSize(VertexFormatBits format) { switch (format) { case VertexFormatBits.Position: return(VertexPosition.GetSizeInFloats()); case VertexFormatBits.PositionColored: return(VertexPositionColored.GetSizeInFloats()); case VertexFormatBits.PositionNormal: return(VertexPositionNormal.GetSizeInFloats()); case VertexFormatBits.PositionNormalColored: return(VertexPositionNormalColored.GetSizeInFloats()); default: break; } return(VertexPosition.GetSizeInFloats()); }
public static void Draw(GraphicsDevice device, Vector3 p0, Vector3 p1, Effect Effect, Matrix World, Matrix View, Matrix Proj) { var ant_technique = Effect.CurrentTechnique; Effect.CurrentTechnique = Effect.Techniques["ColorDrawing"]; Effect.Parameters["World"].SetValue(World); Effect.Parameters["View"].SetValue(View); Effect.Parameters["Projection"].SetValue(Proj); VertexPosition[] vertices = new VertexPosition[2]; vertices[0].Position = p0; vertices[1].Position = p1; foreach (var pass in Effect.CurrentTechnique.Passes) { pass.Apply(); device.DrawUserPrimitives(PrimitiveType.LineList, vertices, 0, 1); } Effect.CurrentTechnique = ant_technique; }
private void initCube() { VertexPosition[] vertices = new VertexPosition[8]; int[] index = new int[36]; int i = 0, j = 0; vertices[i++] = new VertexPosition(new Vector3(-1, 1, -1)); vertices[i++] = new VertexPosition(new Vector3(1, 1, -1)); vertices[i++] = new VertexPosition(new Vector3(-1, -1, -1)); vertices[i++] = new VertexPosition(new Vector3(1, -1, -1)); vertices[i++] = new VertexPosition(new Vector3(-1, 1, 1)); vertices[i++] = new VertexPosition(new Vector3(1, 1, 1)); vertices[i++] = new VertexPosition(new Vector3(-1, -1, 1)); vertices[i++] = new VertexPosition(new Vector3(1, -1, 1)); // front face index[j++] = 2; index[j++] = 0; index[j++] = 1; index[j++] = 2; index[j++] = 1; index[j++] = 3; // back face index[j++] = 7; index[j++] = 5; index[j++] = 4; index[j++] = 7; index[j++] = 4; index[j++] = 6; // upper face index[j++] = 0; index[j++] = 4; index[j++] = 5; index[j++] = 0; index[j++] = 5; index[j++] = 1; // lower face index[j++] = 6; index[j++] = 2; index[j++] = 3; index[j++] = 6; index[j++] = 3; index[j++] = 7; // right face index[j++] = 3; index[j++] = 1; index[j++] = 5; index[j++] = 3; index[j++] = 5; index[j++] = 7; // left face index[j++] = 6; index[j++] = 4; index[j++] = 0; index[j++] = 6; index[j++] = 0; index[j++] = 2; vertexBuffer = new VertexBuffer(GraphicsDevice, VertexPosition.SizeInBytes * vertices.Length, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); indexBuffer = new IndexBuffer(GraphicsDevice, typeof(int), index.Length, BufferUsage.WriteOnly); indexBuffer.SetData(index); vertexDeclaration = new VertexDeclaration(GraphicsDevice, VertexPosition.VertexElements); }
void DrawFrustrum() { Vector3[] verts = Control.Frustum.GetCorners(); VertexPosition[] verticies = new VertexPosition[8]; for (int i = 0; i < 8; i++) verticies[i] = new VertexPosition(verts[i]); Control.SolidShader.Parameters["World"].SetValue(Matrix.Identity); foreach (EffectPass pass in Control.SolidShader.CurrentTechnique.Passes) { pass.Apply(); GraphicsDevice.DrawUserIndexedPrimitives<VertexPosition>(PrimitiveType.LineList, verticies, 0, 8, FrustumIndicies, 0, 12, VertexPosition.VertexDeclaration); } }
private HeadFile ApplyAbsolute() { Dictionary<Expression, List<Triple<double, double, double>>> offsets = new Dictionary<Expression, List<Triple<double, double, double>>>(); foreach (KeyValuePair<Expression, MeshBase> expression in this.expressions) { offsets.Add(expression.Key, this.CalculateOffsets(this.target.TRI.Vertices, expression.Value.Vertices)); } Dictionary<Morph, List<VertexPosition>> unmorphs = new Dictionary<Morph, List<VertexPosition>>(); for (int i = 0; i < 4; i++) { Morph morph = (Morph)i; List<Triple<double, double, double>> unmorph = new List<Triple<double, double, double>>(); for (int j = 0; j < this.target.TRI.Header.VertexCount; j++) { unmorph.Add(new Triple<double, double, double>()); } foreach (KeyValuePair<Expression, Dictionary<Morph, double>> weight in this.weights) { if (weight.Value.ContainsKey(morph)) { List<Triple<double, double, double>> mlist = offsets[weight.Key]; double w = weight.Value[morph]; for (int k = 0; k < mlist.Count; k++) { Triple<double, double, double> aux = unmorph[k]; aux.X = aux.X + w * (double)(mlist[k].X); aux.Y = aux.Y + w * (double)(mlist[k].Y); aux.Z = aux.Z + w * (double)(mlist[k].Z); unmorph[k] = aux; } } } List<VertexPosition> unmorph2 = new List<VertexPosition>(); for (int j = 0; j < unmorph.Count; j++) { Triple<double, double, double> aux = unmorph[j]; VertexPosition pos = new VertexPosition(); pos.X = this.target.TRI.Vertices[j].X - (float)(aux.X / 100d); pos.Y = this.target.TRI.Vertices[j].Y - (float)(aux.Y / 100d); pos.Z = this.target.TRI.Vertices[j].Z - (float)(aux.Z / 100d); unmorph2.Add(pos); } unmorphs.Add(morph, unmorph2); } Dictionary<Morph, List<VertexDisplacement>> displacements = new Dictionary<Morph, List<VertexDisplacement>>(); for (int i = 0; i < 4; i++) { Morph morph = (Morph)i; displacements.Add(morph, this.CalculateDisplacements(this.target.TRI.Vertices, unmorphs[morph], this.ignoreList, this.accuracy)); } HeadFile ret = new HeadFile(this.target); try { foreach (KeyValuePair<Morph, List<VertexDisplacement>> keypair in displacements) { foreach (TRIMorphData morph in ret.TRI.Morphs) { if (morph.Name.ToLower().StartsWith(keypair.Key.ToString().ToLower())) { for (int i = 0; i < ret.TRI.Header.VertexCount; i++) morph[i] = keypair.Value[i]; } } } } catch (Exception) { return this.target; } this.applied = true; return ret; }
public void HashCodes_ShouldNotBeEqual_ForUnequalVertices(VertexPosition other) { vertex.GetHashCode().ShouldNotBe(other.GetHashCode()); }
public void SetUp() { vertex = new VertexPosition(position); }
public void TypeEquals_ReturnsFalse_OnUnequalVertex(VertexPosition other) { vertex.Equals(other).ShouldBeFalse(); }
public void EqualsOperator_ReturnsTrue_OnEqualVertex(VertexPosition other) { (vertex == other).ShouldBeTrue(); }
public void NotEqualsOperator_ReturnsTrue_OnUnequalVertex(VertexPosition other) { (vertex != other).ShouldBeTrue(); }
public PatchMesh(GraphicsDevice graphicsDevice, int gridSize) { // GridSize must be leafNodeSize * n, and n must be power of 2. GridSize = gridSize; int vertexSize = gridSize + 1; NumVertices = vertexSize * vertexSize; VertexBuffer = new VertexBuffer(graphicsDevice, VertexPosition.VertexDeclaration, NumVertices, BufferUsage.WriteOnly); var vertices = new VertexPosition[NumVertices]; for (int z = 0; z < vertexSize; z++) for (int x = 0; x < vertexSize; x++) vertices[vertexSize * z + x] = new VertexPosition(new Vector3(x / (float) gridSize, 0, z / (float) gridSize)); VertexBuffer.SetData(vertices); PrimitiveCount = gridSize * gridSize * 2; var indexCount = PrimitiveCount * 3; IndexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.SixteenBits, indexCount, BufferUsage.WriteOnly); var indices = new ushort[indexCount]; int index = 0; int halfSize = gridSize / 2; // Top left. for (int z = 0; z < halfSize; z++) { for (int x = 0; x < halfSize; x++) { indices[index++] = (ushort) ((x + 0) + (z + 0) * vertexSize); indices[index++] = (ushort) ((x + 1) + (z + 0) * vertexSize); indices[index++] = (ushort) ((x + 0) + (z + 1) * vertexSize); indices[index++] = (ushort) ((x + 1) + (z + 0) * vertexSize); indices[index++] = (ushort) ((x + 1) + (z + 1) * vertexSize); indices[index++] = (ushort) ((x + 0) + (z + 1) * vertexSize); } } TopLeftEndIndex = index; // Top right. for (int z = 0; z < halfSize; z++) { for (int x = halfSize; x < gridSize; x++) { indices[index++] = (ushort) ((x + 0) + (z + 0) * vertexSize); indices[index++] = (ushort) ((x + 1) + (z + 0) * vertexSize); indices[index++] = (ushort) ((x + 0) + (z + 1) * vertexSize); indices[index++] = (ushort) ((x + 1) + (z + 0) * vertexSize); indices[index++] = (ushort) ((x + 1) + (z + 1) * vertexSize); indices[index++] = (ushort) ((x + 0) + (z + 1) * vertexSize); } } TopRightEndIndex = index; // Bottom left. for (int z = halfSize; z < gridSize; z++) { for (int x = 0; x < halfSize; x++) { indices[index++] = (ushort) ((x + 0) + (z + 0) * vertexSize); indices[index++] = (ushort) ((x + 1) + (z + 0) * vertexSize); indices[index++] = (ushort) ((x + 0) + (z + 1) * vertexSize); indices[index++] = (ushort) ((x + 1) + (z + 0) * vertexSize); indices[index++] = (ushort) ((x + 1) + (z + 1) * vertexSize); indices[index++] = (ushort) ((x + 0) + (z + 1) * vertexSize); } } BottomLeftEndIndex = index; // Bottom right. for (int z = halfSize; z < gridSize; z++) { for (int x = halfSize; x < gridSize; x++) { indices[index++] = (ushort) ((x + 0) + (z + 0) * vertexSize); indices[index++] = (ushort) ((x + 1) + (z + 0) * vertexSize); indices[index++] = (ushort) ((x + 0) + (z + 1) * vertexSize); indices[index++] = (ushort) ((x + 1) + (z + 0) * vertexSize); indices[index++] = (ushort) ((x + 1) + (z + 1) * vertexSize); indices[index++] = (ushort) ((x + 0) + (z + 1) * vertexSize); } } BottomRightEndIndex = index; IndexBuffer.SetData(indices); }
public void NotEqualsOperator_ReturnsFalse_OnEqualVertex(VertexPosition other) { (vertex != other).ShouldBeFalse(); }
//heightMap must be 2^n+1, squareSize must be 2^n+1, both are constants of the Quadtree. //nodedepth will not go below a level that will make square size impossible given the height field. /// <summary> /// This constructs a single complete quadNode in the Quadtree. /// </summary> /// <param name="heightMap">This should be a reference to the Terrains heightmap. Inherited from Quadterrain.</param> /// <param name="squareSize">This is the number of vertices along the edge of the quadnode. Inherited from Quadterrain.</param> /// <param name="VertBuffSize">This is the number of vertices along the edge of a Vertex buffer. Inherited from Quadterrain.</param> /// <param name="terrainScale">The scale of the terrain. Inherited from Quadterrain.</param> /// <param name="nodeDepth">The depth of this individual node. Vitally important for generating many properties of the node.</param> /// <param name="xPosition">The X origin of the node on the heightmap.</param> /// <param name="yPosition">The Y origin of the node on the heightmap.</param> /// <param name="parentFullQuad">The parent node of this node in the Tree.</param> /// <param name="Identifier">An ID number. I can't actually remember what I used it for... :?</param> /// <param name="Vertices">This should be a reference to the Vertex Buffers. Inherited from Quadterrain.</param> public QuadNode(Texture2D heightMap, Vector3[,] normStore, int squareSize, int VertBuffSize, float terrainScale, int nodeDepth, int xPosition, int yPosition, QuadNode parentFullQuad, VertexPosition[][] Vertices) { stitchedSides = 0; //Initialise x and y position variables. XPosition = xPosition; YPosition = yPosition; //Initialise parent variable parent = parentFullQuad; //Initialise status status = 0; //Get number of Vertex Buffers int numberOfVBs = (int)Math.Pow((heightMap.Height - 1) / (VertBuffSize - 1), 2); int sqrtNumberOfVBs = (int)Math.Sqrt(numberOfVBs); ///////////////////////////////////////////////////// // For: // SquareSize = 5 // Height = 257 // NodeDepth, NodeLevel, NodeScale, stepSize // 0, 1, 257, 64 // 1, 2, 129, 32 // 2, 4, 65, 16 // 3, 8, 33, 8 // 4, 16, 19, 4 // 5, 32, 9, 2 // 6, 64, 5, 1 //////////////////////////////////////////////////// int stitching = 0; NodeLevel = (int)Math.Pow(2, (nodeDepth)); NodeScale = ((heightMap.Height - 1) / NodeLevel) + 1; stepSize = (NodeScale - 1) / (squareSize - 1); indices = new int[9][]; //////////////////////////////////////////////////// //Gather the vertex buffer of this node VBuffer = (int)(Math.Floor(((float)(xPosition + 1) / heightMap.Width) * sqrtNumberOfVBs) + (Math.Floor(((float)(yPosition + 1) / heightMap.Height) * sqrtNumberOfVBs) * sqrtNumberOfVBs)) + 1; int VBufferRootScale = 1; //Set this nodes buffer to the root buffer if the Node is too big if (NodeScale > VertBuffSize) { VBuffer = 0; VBufferRootScale = (heightMap.Width - 1) / (VertBuffSize - 1); // ~~ HeightMapWidth/VBufferSize ~~ VBXOffset = 0; VBYOffset = 0; } else { VBXOffset = ((VBuffer - 1) % (int)sqrtNumberOfVBs) * (VertBuffSize - 1); VBYOffset = ((VBuffer - 1) / (int)sqrtNumberOfVBs) * (VertBuffSize - 1); } //Initialised Bounding Box variables float minHeight = 10000; float maxHeight = 0; //indices[0] = none //indices[1] = LEFT //indices[2] = TOP //indices[3] = RIGHT //indices[4] = DOWN //indices[5] = LEFT-TOP //indices[6] = TOP-RIGHT //indices[7] = RIGHT-DOWN //indices[8] = DOWN-LEFT //Generate Index array for this node. for (stitching = 0; stitching < 9; stitching++) { List<int> tempIndices = new List<int>(); //These variables are used for creating flatstrips bool addingFlats = false; int xOffset = 0; Vector3 oldNormal = new Vector3(); //Build Index arrays for each stitching type for (int y = yPosition; y < yPosition + ((NodeScale - 1) - stepSize + 1); y += stepSize) { for (int x = xPosition; x < xPosition + ((NodeScale - 1) - stepSize + 1); x += stepSize) { // Test if (y < heightMap.Width - stepSize && x < heightMap.Height - stepSize) { //Edge stitching: // // //1 Lrge stitch // /\ // /__\ // // //2 Sml stitches // ___ ___ // | / \ | // |/ \| bool standard = false; if (Vertices[VBuffer][Math.Abs((x - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale].Position.Y > maxHeight) { maxHeight = Vertices[VBuffer][Math.Abs((x - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale].Position.Y; } else { if (Vertices[VBuffer][Math.Abs((x - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale].Position.Y < minHeight) { minHeight = Vertices[VBuffer][Math.Abs((x - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale].Position.Y; } } ///////////////////////////////////////////////////// //STITCH BOTTOM if (x <= xPosition) { if (stitching == 4 || stitching == 7 || stitching == 8) { if (y % (stepSize * 2) == 0) { standard = false; //1 Lrge stitch tempIndices.Add(Math.Abs((x - VBXOffset) + ((y - VBYOffset) + stepSize * 2) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); numberOfIndices += 3; //2 Sml stitches (Don't do edges) if (y != yPosition || stitching == 8 || stitching == 4) { tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset)) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale); } if (y != yPosition + (NodeScale - 1) - stepSize * 2 || stitching == 7 || stitching == 4) { tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - VBXOffset) + ((y - VBYOffset) + stepSize * 2) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize * 2) * VertBuffSize) / VBufferRootScale); } } } else { standard = true; } } ////////////////////////////////////////// //STITCH TOP if (x == xPosition + ((NodeScale - 1) - stepSize)) { if (stitching == 2 || stitching == 5 || stitching == 6) { if (y % (stepSize * 2) == 0) { standard = false; //1 Lrg Stich tempIndices.Add(Math.Abs(((x - VBXOffset)) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize * 2) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); //2 Smll Stitches (don't do edges) if (y != yPosition || stitching == 2 || stitching == 5) { tempIndices.Add(Math.Abs(((x - VBXOffset)) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset)) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale); } if (y != yPosition + (NodeScale - 1) - stepSize * 2 || stitching == 2 || stitching == 6) { tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize * 2) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset)) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset)) + ((y - VBYOffset) + stepSize * 2) * VertBuffSize) / VBufferRootScale); } } } else { standard = true; } } //////////////////////////////// //STITCH RIGHT if (y <= yPosition) { if (stitching == 3 || stitching == 6 || stitching == 7) { if (x % (stepSize * 2) == 0) { standard = false; tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize * 2) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); if (x != xPosition || stitching == 3 || stitching == 6) { tempIndices.Add(Math.Abs(((x - VBXOffset)) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset)) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale); } if (x != xPosition + (NodeScale - 1) - stepSize * 2 || stitching == 3 || stitching == 7) { tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize * 2) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize * 2) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); } } } else { standard = true; } } ////////////////////////////////////////// //STITCH LEFT if (y == yPosition + ((NodeScale - 1) - stepSize)) { if (stitching == 1 || stitching == 5 || stitching == 8) { if (x % (stepSize * 2) == 0) { standard = false; //1 Lrg Stich tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize * 2) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset)) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); //2 Smll Stitches (don't do edges) if (x != xPosition || stitching == 1 || stitching == 5) { tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset)) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset)) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); } if (x != xPosition + (NodeScale - 1) - stepSize * 2 || stitching == 1 || stitching == 8) { tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize * 2) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize * 2) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale); } } } else { standard = true; } } if (x > xPosition && y > yPosition && x != xPosition + ((NodeScale - 1) - stepSize) && y != yPosition + ((NodeScale - 1) - stepSize)) { standard = true; } //NO STITCHING (Centre piece) if (standard == true) { #region depricated //indices[stitching][i++] = Math.Abs((x - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale; //indices[stitching][i++] = Math.Abs(((x - VBXOffset) + stepSize) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale; //indices[stitching][i++] = Math.Abs((x - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale; //indices[stitching][i++] = Math.Abs((x - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale; //indices[stitching][i++] = Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale; //indices[stitching][i++] = Math.Abs(((x - VBXOffset) + stepSize) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale; #endregion ///////////////////////////////////////////////////////////////////// //This section is used to cut the number of polygons by removing detail on flat planes Vector3 next1Normal = normStore[x, y]; Vector3 next2Normal = normStore[x, y + stepSize]; Vector3 next1Position = Vertices[VBuffer][Math.Abs((x - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale].Position; Vector3 next2Position = Vertices[VBuffer][Math.Abs((x - VBXOffset) + (y + stepSize - VBYOffset) * VertBuffSize) / VBufferRootScale].Position; Vector3 nn = Vertices[VBuffer][Math.Abs((x + stepSize - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale].Position - next1Position; nn.Normalize(); Vector3 nn2 = Vertices[VBuffer][Math.Abs((x + stepSize - VBXOffset) + (y + stepSize - VBYOffset) * VertBuffSize) / VBufferRootScale].Position - next2Position; nn2.Normalize(); Vector3 next1Normalised = Vector3.Cross(next1Normal, Vector3.UnitZ); next1Normalised.Normalize(); Vector3 next2Normalised = Vector3.Cross(next2Normal, Vector3.UnitZ); next2Normalised.Normalize(); //MessageBox.Show("nn: "+ nn +", next2Position: " + next2Position.ToString() + ", next1Position: " + next1Position.ToString() + ",n1normalised: " + next1Normalised.ToString() + ", Formula: " + Vector3.Add(next1Position, Vector3.Multiply(next1Normalised, terrainScale * stepSize))); //if (Math.Abs(oldNormal.X - next1Normal.X) < 0.000001 && Math.Abs(oldNormal.X - next2Normal.X) < 0.000001 && Math.Abs(oldNormal.Y - next1Normal.Y) < 0.000001 && Math.Abs(oldNormal.Y - next2Normal.Y) < 0.000001 && x < xPosition + ((NodeScale - 1) - stepSize * 2)) //if (oldNormal == next1Normal && oldNormal == next2Normal && Math.Abs((nn.Y) - (next1Normalised.Y)) < .00001 && Math.Abs((nn2.Y) - (next2Normalised.Y)) < .00001 && x < xPosition + ((NodeScale - 1) - stepSize * 2) || oldNormal == next1Normal && oldNormal == next2Normal && float.IsNaN(Math.Abs(Math.Abs(nn.Z) - Math.Abs(next1Normalised.Z))) && x < xPosition + ((NodeScale - 1) - stepSize * 2)) if (oldNormal == next1Normal && oldNormal == next2Normal && nn == next1Normalised && nn2 == next2Normalised && x < xPosition + ((NodeScale - 1) - stepSize * 2) || oldNormal == next1Normal && oldNormal == next2Normal && float.IsNaN((next1Normalised.Z)) && nn.X == 1 && nn2.X == 1 && x < xPosition + ((NodeScale - 1) - stepSize * 2)) { //MessageBox.Show(nn+" "+next1Normalised); if (addingFlats == false) { //Activates when we enter a flatstrip addingFlats = true; xOffset = x; oldNormal = normStore[x, y + stepSize]; } else { //In the middle of a flatstip, we do nothing } } else { if (addingFlats == true) { //Activaes when we leave a flatstrip addingFlats = false; tempIndices.Add(Math.Abs(((xOffset - VBXOffset)) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - stepSize - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - stepSize - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((xOffset - VBXOffset)) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - stepSize - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((xOffset - VBXOffset)) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); ///////////////////////////////////////////////////////////////////// //This makes cliffs look better by reorientating the diagonal, and thus removing "cliff feet". VertexPosition v0 = Vertices[VBuffer][Math.Abs((x - VBXOffset) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale]; VertexPosition vX = Vertices[VBuffer][Math.Abs((x - VBXOffset + stepSize) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale]; VertexPosition vY = Vertices[VBuffer][Math.Abs((x - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale]; VertexPosition vXY = Vertices[VBuffer][Math.Abs((x - VBXOffset + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale]; float rightDiagDifference = Math.Abs(v0.Position.Y - vXY.Position.Y); float leftDiagDifference = Math.Abs(vX.Position.Y - vY.Position.Y); if (rightDiagDifference < leftDiagDifference) { tempIndices.Add(Math.Abs((x - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset)) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); } else { tempIndices.Add(Math.Abs((x - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); } tempIndices.Add(Math.Abs((x - stepSize - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - stepSize - VBXOffset) + stepSize) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - stepSize - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - stepSize - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - stepSize - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - stepSize - VBXOffset) + stepSize) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); oldNormal = normStore[x, y + stepSize]; ///////////////////////////////////////////////////////////////////// } else { ///////////////////////////////////////////////////////////////////// //Generate a normal square: nothing special, except for removing cliff feet oldNormal = normStore[x, y + stepSize]; //Make cliffs look better by reorientating the diagonal VertexPosition v0 = Vertices[VBuffer][Math.Abs((x - VBXOffset) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale]; VertexPosition vX = Vertices[VBuffer][Math.Abs((x - VBXOffset + stepSize) + ((y - VBYOffset)) * VertBuffSize) / VBufferRootScale]; VertexPosition vY = Vertices[VBuffer][Math.Abs((x - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale]; VertexPosition vXY = Vertices[VBuffer][Math.Abs((x - VBXOffset + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale]; float rightDiagDifference = Math.Abs(v0.Position.Y - vXY.Position.Y); float leftDiagDifference = Math.Abs(vX.Position.Y - vY.Position.Y); if (rightDiagDifference < leftDiagDifference) { tempIndices.Add(Math.Abs((x - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset)) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); } else { tempIndices.Add(Math.Abs((x - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - VBXOffset) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs((x - VBXOffset) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + ((y - VBYOffset) + stepSize) * VertBuffSize) / VBufferRootScale); tempIndices.Add(Math.Abs(((x - VBXOffset) + stepSize) + (y - VBYOffset) * VertBuffSize) / VBufferRootScale); } } } } } } } ///////////////////////////////////////////////////////////////////// //Keep track of the number of indices. indices[stitching] = new int[tempIndices.Count]; if (numberOfIndices < tempIndices.Count) numberOfIndices = tempIndices.Count; indices[stitching] = tempIndices.ToArray(); } //////////////////////////////////////////////// //Create Nodes Bounding Box. boundBox = new BoundingBox(new Vector3((float)(xPosition) * terrainScale, minHeight, (float)(yPosition) * terrainScale), new Vector3((float)(xPosition + NodeScale) * terrainScale, maxHeight, (float)(yPosition + NodeScale) * terrainScale)); ///////////////////////////////////////////////////////////////////// //Set node Depth. NodeDepth = nodeDepth; }
/// <summary> /// Initialises a complete QuadTerrain. ///This is the Constructor method. As you might have guessed, it constructs a quad terrain. /// Quasar. /// </summary> /// <param name="factory">The factory.</param> /// <param name="heightMap">The Texture2D to use as a heightmap. Must have square dimensions of (2^n)+1, where n is an integer.</param> /// <param name="squareSize">The edge size of each individual LOD square. Lower values increase CPU Load, decrease GPU Load, and increase Loading times. Must be (2^n)+1, and larger than 5.</param> /// <param name="vertexBufferSize">The size of Vertex buffer to use. Lower Values increase the number of draw calls by splitting the terrain into several Vertex Buffers. Must be (2^n)+1, and larger than squareSize.</param> /// <param name="scale">The XZ scale to multiply the terrain by.</param> /// <param name="height">The Y scale to multiply the terrain by.</param> public QuadTerrain(GraphicFactory factory ,Texture2D heightMap, int squareSize, int vertexBufferSize, float scale, float height) { this.factory = factory; //I'm not entirely sure what this does, but it is used in updateTerrain. //I think it is used to prevent the Vertex Buffers being filled during the initialisation UpdateTerrain call. first = true; LODHeightImpact = 1.0f; //Set terrain width and height from heightmap. terrainHeight = heightMap.Height; terrainWidth = heightMap.Width; //Set some obvious public variables HeightMap = heightMap; SquareSize = squareSize; Scale = scale; HeightScale = height; VBsize = vertexBufferSize; //Copy the heightmap from a Texture to an array of colours... Color[] heightMapColors = new Color[terrainWidth * terrainHeight]; heightMap.GetData(heightMapColors); //Initialise the HeightStore and heightStore = new float[heightMap.Width, heightMap.Height]; normStore = new Vector3[heightMap.Width, heightMap.Height]; //this is the Normal texture for the entire terrain. It is used within the shader to prevent normal popup. normalTexture = factory.CreateTexture2D(heightMap.Width, heightMap.Height, true, SurfaceFormat.Color); Color[] normalData = new Color[heightMap.Width * heightMap.Height]; #region depricated /* int NodeDepth= 0; int NodeLevel = (int)Math.Pow(2, (NodeDepth)); int NodeScale = ((heightMap.Height - 1) / NodeLevel) + 1; int stepSize = (NodeScale - 1) / (squareSize - 1); */ //////////////////////////////////////////////////// // For: // SquareSize = 9 // Height = 257 // NodeDepth, NodeLevel, NodeScale, stepSize // 0, 1, 257, 64 // 1, 2, 129, 32 // 2, 4, 65, 16 // 3, 8, 33, 8 // 4, 16, 19, 4 // 5, 32, 9, 2 // 6, 64, 5, 1 //////////////////////////////////////////////////// //Get node depth: //int NodeScale = stepSize*(squareSize-1)+1; //int NodeLevel = (NodeScale - 1) * (heightMap.Height - 1); //int maxNodeDepth = (int)Math.Log(NodeLevel, 2); //int maxNodeDepth; #endregion //Determine Maximum Node Depth from Square Size and height of heightmap int NodeScale = 1 * (squareSize - 1) + 1; int NodeLevel = (heightMap.Height - 1) / (NodeScale - 1); maxNodeDepth = (int)Math.Log(NodeLevel, 2); //Work out number of vertex arrays needed: //Math.Pow(HeightMap.HEIGHT / 512, 2))+1; numberOfVBs = (int)Math.Pow((terrainHeight - 1) / (VBsize - 1), 2); sqrtNumberOfVBs = (int)Math.Sqrt(numberOfVBs); //Initialise the Array of Vertex Arrays, accompanying Array of Vertex Buffers and the Array of Integer Index Arrays. allVertices = new VertexPosition[numberOfVBs + 1][]; allVBs = new VertexBuffer[numberOfVBs + 1]; allIndices = new int[numberOfVBs + 1][]; //And as if that wasn't confusing enough... //Now I initialise each Array in the Array of Vertex Arrays, each corresponding Buffer in the Array of Vertex Buffers, //and each Integer Index Array in the Array of Integer Index Arrays. for (int i = 0; i < numberOfVBs + 1; i++) { allVertices[i] = new VertexPosition[(VBsize + 1) * (VBsize + 1)]; allVBs[i] = factory.CreateVertexBuffer(VertexPosition.VertexDeclaration, (VBsize + 1) * (VBsize + 1), BufferUsage.WriteOnly); allIndices[i] = new int[VBsize * VBsize * 6]; } //Array. //This list is used to sort the Quadnodes to be drawn by distance to save on Overdraw. qnl = new List<QuadNode>(); //Create a 2D array of floats from the heightmap colour array. for (int y = 0; y < terrainHeight; y++) { for (int x = 0; x < terrainWidth; x++) { //heightstore Array heightStore[x, y] = heightMapColors[x + y * terrainWidth].R; } } //Define the 'renderedIndices' array, which keeps track of the number of indices from each vertex buffer each frame. renderedindices = new int[numberOfVBs + 1]; ///////////////////////////////////////////////////// //Generate Vertex Positions and normals int PlusXVBIndex; int PlusYVBIndex; int PlusXYVBIndex; int PlusVBIndex; for (int y = 0; y < terrainHeight; y++) { for (int x = 0; x < terrainWidth; x++) { PlusXYVBIndex = (int)(Math.Floor(((float)(x + 1) / terrainWidth) * sqrtNumberOfVBs) + (Math.Floor(((float)(y + 1) / terrainWidth) * sqrtNumberOfVBs) * sqrtNumberOfVBs)); PlusXVBIndex = (int)(Math.Floor(((float)(x + 1) / terrainWidth) * sqrtNumberOfVBs) + (Math.Floor(((float)(y) / terrainWidth) * sqrtNumberOfVBs) * sqrtNumberOfVBs)); PlusYVBIndex = (int)(Math.Floor(((float)(x) / terrainWidth) * sqrtNumberOfVBs) + (Math.Floor(((float)(y + 1) / terrainWidth) * sqrtNumberOfVBs) * sqrtNumberOfVBs)); PlusVBIndex = (int)(Math.Floor(((float)(x) / terrainWidth) * sqrtNumberOfVBs) + (Math.Floor(((float)(y) / terrainWidth) * sqrtNumberOfVBs) * sqrtNumberOfVBs)); Vector3 normX = Vector3.Zero; Vector3 normY = Vector3.Zero; Vector3 normalVector = new Vector3(); if (x > 0 && y > 0 && x < terrainWidth - 1 && y < terrainHeight - 1) { normX = new Vector3((heightStore[x - 1, y] - heightStore[x + 1, y]) / 2 * height, 0, scale); normY = new Vector3(0, (heightStore[x, y - 1] - heightStore[x, y + 1]) / 2 * height, scale); normalVector = normX + normY; normalVector.Normalize(); Vector3 texVector = new Vector3(); texVector.X = (normalVector.X + 1) / 2f; texVector.Y = (normalVector.Y + 1) / 2f; texVector.Z = (normalVector.Z + 1) / 2f; normalData[x + y * terrainHeight] = new Color(texVector); //MessageBox.Show(normalVector.ToString() + " "+new Color(normalVector)); } else { normX = new Vector3(0, 0, scale); normY = new Vector3(0, 0, scale); normalVector = normX + normY; normalVector.Normalize(); Vector3 texVector = new Vector3(); texVector.X = (normalVector.X + 1) / 2f; texVector.Y = (normalVector.Y + 1) / 2f; texVector.Z = (normalVector.Z + 1) / 2f; normalData[x + y * terrainHeight] = new Color(texVector); } normStore[x, y] = normalVector; ///////////////////////////////////////////// //Fill Vertex Arrays //Foreach vertex array... for (int i = 0; i < numberOfVBs; i++) { //Vertex Buffers // 0, 1, 2, 3... What about root 0? // 4, 5, 6, 7 // 8, 9,10,11 //12,13,14,15 //Change to... // 1, 2, 3, 4... root=0 // 5, 6, 7, 8 // 9,10,11,12 //13,14,15,16 //This works to sort the VB's. //It works to align the x,y and VBi values: only if an x/y coord is in an i VB. Uses 1st VB chart. Just use i+1 /////////////////////////////////////////////////////////// //^^ If you understood the above comment, you're doing better than me. ^^ /////////////////////////////////////////////////////////// //This is the 'multiple vertex buffers' algorithm, which puts vertices into their own VBuffers. Anything involving //it won't be very well documented, because I can only vaguely remember writing it in the first place. //I'm not entirely sure what that means, but I suspect I was either drunk or asleep at the time. Possibly both. if (PlusXYVBIndex == i) { //allVertices[i+1][(x % VBsize) + (y % VBsize) * VBsize].Position = new Vector3(x * scale, heightStore[x, y] * height, -y * scale); if (x < terrainHeight - 1) { //MessageBox.Show(x + " " + y + " " + x % (VBsize - 1) + " " + y % (VBsize - 1) + " " + i); allVertices[i + 1][x % (VBsize - 1) + y % (VBsize - 1) * VBsize].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale); //allVertices[i + 1][x % (VBsize - 1) + y % (VBsize - 1) * VBsize].Normal = normalVector; //Add this vertex to VB i+1, at location (x % (VBsize-1) + y % (VBsize-1) * VBsize) } } else { //Bottom or left if (PlusVBIndex == i) { if (PlusYVBIndex == i) { //MessageBox.Show(x + "BotLeft&Y " + y + " " + (x % (VBsize - 1) + (VBsize - 1)) + " " + y % (VBsize - 1) + " " + i); allVertices[i + 1][(x % (VBsize - 1) + (VBsize - 1)) + (y % (VBsize - 1)) * VBsize].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale); //allVertices[i + 1][(x % (VBsize - 1) + (VBsize - 1)) + (y % (VBsize - 1)) * VBsize].Normal = normalVector; //Add this vertex to VB i+1, at location (x % (VBsize - 1) + (VBsize - 1)) + (y % (VBsize - 1)) * VBsize) } else { if (PlusXVBIndex == i) { //MessageBox.Show(x + "BotLeft&X " + y + " " + x % (VBsize - 1) + " " + (y % (VBsize - 1) + (VBsize - 1)) + " " + i); allVertices[i + 1][x % (VBsize - 1) + (y % (VBsize - 1) + (VBsize - 1)) * VBsize].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale); //allVertices[i + 1][x % (VBsize - 1) + (y % (VBsize - 1) + (VBsize - 1)) * VBsize].Normal = normalVector; //Add this vertex to VB i+1, at location (x % (VBsize - 1)) + (y % (VBsize - 1) + (VBsize - 1)) * VBsize) } else { //MessageBox.Show(x + "BotLeft " + y + " " + (x % (VBsize - 1) + (VBsize - 1)) + " " + (y % (VBsize - 1) + (VBsize - 1)) + " " + i); allVertices[i + 1][x % (VBsize - 1) + (VBsize - 1) + (y % (VBsize - 1) + (VBsize - 1)) * VBsize].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale); //allVertices[i + 1][x % (VBsize - 1) + (VBsize - 1) + (y % (VBsize - 1) + (VBsize - 1)) * VBsize].Normal = normalVector; //Add this vertex to VB i+1, at location (x % (VBsize - 1) + (VBsize - 1)) + (y % (VBsize - 1) + (VBsize - 1)) * VBsize) } } } else { //Corner Left if (PlusYVBIndex == i) { if (y < terrainHeight - 1) { //MessageBox.Show(x + "Left " + y + " " + (x % (VBsize - 1) + (VBsize - 1)) + " " + y % (VBsize - 1) + " " + i); allVertices[i + 1][(x % (VBsize - 1) + (VBsize - 1) + (y % (VBsize - 1)) * VBsize)].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale); //allVertices[i + 1][(x % (VBsize - 1) + (VBsize - 1) + (y % (VBsize - 1)) * VBsize)].Normal = normalVector; //Add this vertex to VB i+1, at location ((x % (VBsize - 1) + (VBsize - 1)) + (y % (VBsize - 1)) * VBsize) } } //Corner Bottom if (PlusXVBIndex == i) { if (x < terrainHeight - 1) { //MessageBox.Show(x + "Bot " + y + " " + x % (VBsize - 1) + " " + (y % (VBsize - 1) + (VBsize - 1)) + " " + i); allVertices[i + 1][(x % (VBsize - 1)) + ((y % (VBsize - 1) + (VBsize - 1)) * VBsize)].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale); //allVertices[i + 1][(x % (VBsize - 1)) + ((y % (VBsize - 1) + (VBsize - 1)) * VBsize)].Normal = normalVector; //Add this vertex to VB i+1, at location ((x % (VBsize - 1)) + ((y % (VBsize - 1) + (VBsize - 1)) * VBsize) } } } } if (i == 0) { int stepSize = (terrainWidth - 1) / (vertexBufferSize - 1); int numberOfSteps = (terrainWidth - 1) / stepSize; if (x % stepSize == 0 && y % stepSize == 0) { allVertices[0][(x / stepSize) + (y / stepSize) * VBsize].Position = new Vector3(x * scale, heightStore[x, y] * height, y * scale); //allVertices[0][(x / stepSize) + (y / stepSize) * VBsize].Normal = normalVector; //Add this vertex to VB 0, at location ((x/stepSize) + (y/stepSize) * VBsize) } } } } } //Generate the normal texture from the normal data generated a second ago. normalTexture.SetData<Color>(normalData); factory.MipMapTexture(ref normalTexture); //////////////////////////////////////////////////////////// //Add to vertex buffer for (int j = 0; j < numberOfVBs + 1; j++) { allVBs[j].SetData<VertexPosition>(allVertices[j]); } //////////////////////////////////////////////////////////// #region depricated // int[] nodeStatsArray = new int[6,6]; //for (i=HeightMap.Height-1;i> // rootNode = new QuadNode(HeightMap, SquareSize, 4, 0, 0); //NodeDepth Nodes Total Nodes //0 1 1 //1 4 5 //2 16 21 //3 64 85 //4 256 341 //5 1024 1365 //allQuadNodes = new List<QuadNode>(); //int NodeDepth = 0; //NodeLevel = (int)Math.Pow(2, (NodeDepth)); //NodeScale = ((heightMap.Height - 1) / NodeLevel) + 1; //int stepSize = (NodeScale - 1) / (squareSize - 1); //QuadNode qNode; //QuadNode[] parentNode = new QuadNode[1]; //int xPosition = 0; //int yPosition = 0; //qNode = new QuadNode(HeightMap, SquareSize, NodeDepth, xPosition, yPosition); //NodeDepth++; //while (xPosition < terrainWidth) //{ // while (yPosition < terrainHeight) // { // while (NodeDepth < maxNodeDepth - 5) // { // NodeLevel = (int)Math.Pow(2, (NodeDepth)); // NodeScale = ((heightMap.Height - 1) / NodeLevel) + 1; // qNode = new QuadNode(HeightMap, SquareSize, NodeDepth, xPosition, yPosition); // allQuadNodes.Add(qNode); // qNode = new QuadNode(HeightMap, SquareSize, NodeDepth, xPosition + NodeScale - 1, yPosition); // allQuadNodes.Add(qNode); // qNode = new QuadNode(HeightMap, SquareSize, NodeDepth, xPosition, yPosition + NodeScale - 1); // allQuadNodes.Add(qNode); // qNode = new QuadNode(HeightMap, SquareSize, NodeDepth, xPosition + NodeScale - 1, yPosition + NodeScale - 1); // allQuadNodes.Add(qNode); // parentNode[0] = qNode; // NodeDepth++; // } // NodeDepth--; // NodeLevel = (int)Math.Pow(2, (NodeDepth-1)); // NodeScale = ((heightMap.Height - 1) / NodeLevel) + 1; // //NodeDepth--; // yPosition += NodeScale - 1; // } // xPosition += NodeScale - 1; // yPosition = 0; //} //NodeDepth++; //int numQuadNodes = allQuadNodes.Count; //int[] indexBufferArray = new int[numQuadNodes * ((squareSize - 1) * (squareSize - 1) * 6)]; #endregion //Define Quadnode List allQuadNodes = new List<QuadNode>(); //Create RootNode RootNode = new QuadNode(HeightMap, normStore, SquareSize, VBsize, Scale, 0, 0, 0, null, allVertices); allQuadNodes.Add(RootNode); //////////////////////////////////////////////// //Creates all quadnodes in the entire quadtree // //This is a recursive function. It breaks the rootnode into 4 new quadnodes, then applies itself to each of //these children nodes, in turn breaking them. See it's definition for a more complete explanation. RecursiveCreateQuad(RootNode); //////////////////////////////////////////////// //Set Adjacent Nodes for each Quadnode, for stitching purposes. for (int i = 0; i < allQuadNodes.Count; i++) { if (allQuadNodes[i].NodeDepth > 0) { foreach (QuadNode qNode in allQuadNodes) { if (qNode.XPosition == allQuadNodes[i].XPosition + allQuadNodes[i].NodeScale - 1 && qNode.NodeDepth == allQuadNodes[i].NodeDepth && qNode.YPosition == allQuadNodes[i].YPosition) { allQuadNodes[i].adjacentNorthQuad = qNode; } if (qNode.YPosition == allQuadNodes[i].YPosition + allQuadNodes[i].NodeScale - 1 && qNode.NodeDepth == allQuadNodes[i].NodeDepth && qNode.XPosition == allQuadNodes[i].XPosition) { allQuadNodes[i].adjacentEastQuad = qNode; } if (qNode.XPosition == allQuadNodes[i].XPosition - allQuadNodes[i].NodeScale + 1 && qNode.NodeDepth == allQuadNodes[i].NodeDepth && qNode.YPosition == allQuadNodes[i].YPosition) { allQuadNodes[i].adjacentSouthQuad = qNode; } if (qNode.YPosition == allQuadNodes[i].YPosition - allQuadNodes[i].NodeScale + 1 && qNode.NodeDepth == allQuadNodes[i].NodeDepth && qNode.XPosition == allQuadNodes[i].XPosition) { allQuadNodes[i].adjacentWestQuad = qNode; } } } } /////////////////////////////////////////////// //Run an update on the terrain for it's initial state. See the update method. //I'm not entirely sure why this is necessary, but I'm sure there's a good reason. Matrix viewMatrix = Matrix.CreateLookAt(Vector3.Zero, Vector3.Forward, Vector3.Up); Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 10f, 1, 100); BoundingFrustum startFrustrum = new BoundingFrustum(viewMatrix * projectionMatrix); #if DEBUG debugTimer = new Stopwatch(); #endif UpdateTerrain(new Vector3(), startFrustrum, 3.5f); allIBs = new DynamicIndexBuffer[allIndices.Length]; for (int l = 0; l < allIndices.Length; l++) { allIBs[l] = factory.CreateDynamicIndexBuffer(IndexElementSize.ThirtyTwoBits, (allVertices[l].Length), BufferUsage.WriteOnly); } }
public static SharpDX.Direct3D11.Buffer CreateVertexBuffer(Device device, RoomAliveToolkit.Kinect2Calibration kinect2Calibration) { // generate depthFrameToCameraSpace table var depthFrameToCameraSpaceTable = kinect2Calibration.ComputeDepthFrameToCameraSpaceTable(Kinect2Calibration.depthImageWidth, Kinect2Calibration.depthImageHeight); int numVertices = 6 * (Kinect2Calibration.depthImageWidth - 1) * (Kinect2Calibration.depthImageHeight - 1); var vertices = new VertexPosition[numVertices]; Int3[] quadOffsets = new Int3[] { new Int3(0, 0, 0), new Int3(1, 0, 0), new Int3(0, 1, 0), new Int3(1, 0, 0), new Int3(1, 1, 0), new Int3(0, 1, 0), }; int vertexIndex = 0; for (int y = 0; y < Kinect2Calibration.depthImageHeight - 1; y++) for (int x = 0; x < Kinect2Calibration.depthImageWidth - 1; x++) for (int i = 0; i < 6; i++) { int vertexX = x + quadOffsets[i].X; int vertexY = y + quadOffsets[i].Y; var point = depthFrameToCameraSpaceTable[Kinect2Calibration.depthImageWidth * vertexY + vertexX]; var vertex = new VertexPosition(); vertex.position = new SharpDX.Vector4(point.X, point.Y, vertexX, vertexY); vertices[vertexIndex++] = vertex; } var stream = new DataStream(numVertices * VertexPosition.SizeInBytes, true, true); stream.WriteRange(vertices); stream.Position = 0; var vertexBufferDesc = new BufferDescription() { BindFlags = BindFlags.VertexBuffer, CpuAccessFlags = CpuAccessFlags.None, Usage = ResourceUsage.Default, SizeInBytes = numVertices * VertexPosition.SizeInBytes, }; var vertexBuffer = new SharpDX.Direct3D11.Buffer(device, stream, vertexBufferDesc); stream.Dispose(); return vertexBuffer; }
public void TypeEquals_ReturnsTrue_OnEqualVertex(VertexPosition other) { vertex.Equals(other).ShouldBeTrue(); }
public void EqualsOperator_ReturnsFalse_OnUnequalVertex(VertexPosition other) { (vertex == other).ShouldBeFalse(); }
public LightCube() { VertexPosition[] verts = new VertexPosition[] { new VertexPosition( new Vector3(1,-1,1)), new VertexPosition( new Vector3(-1,-1,1)), new VertexPosition( new Vector3(-1,1,1)), new VertexPosition( new Vector3(1,1,1)), new VertexPosition( new Vector3(1,-1,-1)), new VertexPosition( new Vector3(-1,-1,-1)), new VertexPosition( new Vector3(-1,1,-1)), new VertexPosition( new Vector3(1,1,-1)) }; vertexBuffer = new VertexBuffer(GFX.Device, verts.Length * VertexPosition.SizeInBytes, BufferUsage.WriteOnly); vertexBuffer.SetData<VertexPosition>(verts); short[] ib = new short[] { 0, 1, 2, 2, 3, 0, 6, 5, 4, 4, 7, 6, 3, 2, 6, 6, 7, 3, 5, 1, 0, 0, 4, 5, 6, 2, 1, 1, 5, 6, 0, 3, 7, 7, 4, 0}; indexBuffer = new IndexBuffer(GFX.Device, sizeof(short) * ib.Length, BufferUsage.WriteOnly, IndexElementSize.SixteenBits); indexBuffer.SetData<short>(ib); }