} // RenderColumnVertices() #endregion #region Unit Testing #if DEBUG /// <summary> /// Test column vertices /// </summary> static public void TestColumnVertices() { TrackColumns colunms = null; TestGame.Start( delegate { colunms = new TrackColumns(new List <TrackVertex>(), null); }, delegate { // Draw the line for each line part for (int num = 0; num < colunms.BaseColumnVertices.Length - 1; num++) { BaseGame.DrawLine( colunms.BaseColumnVertices[num].pos, colunms.BaseColumnVertices[num + 1].pos, Color.White); } // Show normal and tangent vectors for each point for (int num = 0; num < colunms.BaseColumnVertices.Length; num++) { BaseGame.DrawLine( colunms.BaseColumnVertices[num].pos, colunms.BaseColumnVertices[num].pos + colunms.BaseColumnVertices[num].normal * 10, Color.Red); BaseGame.DrawLine( colunms.BaseColumnVertices[num].pos, colunms.BaseColumnVertices[num].pos + colunms.BaseColumnVertices[num].tangent * 10, Color.Blue); } // for (num) }); } // TestColumnVertices()
/// <summary> /// Test column vertices /// </summary> public static void TestColumnVertices() { TrackColumns colunms = null; TestGame.Start( delegate { colunms = new TrackColumns(new List<TrackVertex>(), null); }, delegate { // Draw the line for each line part for (int num = 0; num < colunms.BaseColumnVertices.Length - 1; num++) BaseGame.DrawLine( colunms.BaseColumnVertices[num].pos, colunms.BaseColumnVertices[num + 1].pos, Color.White); // Show normal and tangent vectors for each point for (int num = 0; num < colunms.BaseColumnVertices.Length; num++) { BaseGame.DrawLine( colunms.BaseColumnVertices[num].pos, colunms.BaseColumnVertices[num].pos + colunms.BaseColumnVertices[num].normal * 10, Color.Red); BaseGame.DrawLine( colunms.BaseColumnVertices[num].pos, colunms.BaseColumnVertices[num].pos + colunms.BaseColumnVertices[num].tangent * 10, Color.Blue); } // for (num) }); }
/// <summary> /// Generate vertices and objects /// </summary> private void GenerateVerticesAndObjects(Landscape landscape) { #region Generate the road vertices // Each road segment gets 5 points: // left, left middle, middle, right middle, right. // The reason for this is that we would bad triangle errors if the // road gets wider and wider. This happens because we need to render // quad, but we can only render triangles, which often have different // orientations, which makes the road very bumpy. This still happens // with 8 polygons instead of 2, but it is much better this way. // Another trick is not to do so much iterations in TrackLine, which // causes this problem. Better to have a not so round track, but at // least the road up/down itself is smooth. // The last point is duplicated (see TrackLine) because we have 2 sets // of texture coordinates for it (begin block, end block). // So for the index buffer we only use points.Count-1 blocks. roadVertices = new TangentVertex[points.Count * 5]; // Current texture coordinate for the roadway (in direction of movement) for (int num = 0; num < points.Count; num++) { // Get vertices with help of the properties in the TrackVertex class. // For the road itself we only need vertices for the left and right // side, which are vertex number 0 and 1. roadVertices[num * 5 + 0] = points[num].RightTangentVertex; roadVertices[num * 5 + 1] = points[num].MiddleRightTangentVertex; roadVertices[num * 5 + 2] = points[num].MiddleTangentVertex; roadVertices[num * 5 + 3] = points[num].MiddleLeftTangentVertex; roadVertices[num * 5 + 4] = points[num].LeftTangentVertex; } // for (num) roadVb = new VertexBuffer( BaseGame.Device, typeof(TangentVertex), roadVertices.Length, ResourceUsage.WriteOnly, ResourceManagementMode.Automatic); roadVb.SetData(roadVertices); // Also calculate all indices, we have 8 polygons for each segment with // 3 vertices each. We got 1 segment less than points because the // last point is duplicated (different tex coords). int[] indices = new int[(points.Count - 1) * 8 * 3]; int vertexIndex = 0; for (int num = 0; num < points.Count - 1; num++) { // We only use 3 vertices (and the next 3 vertices), // but we have to construct all 24 indices for our 4 polygons. for (int sideNum = 0; sideNum < 4; sideNum++) { // Each side needs 2 polygons. // 1. Polygon indices[num * 24 + 6 * sideNum + 0] = vertexIndex + sideNum; indices[num * 24 + 6 * sideNum + 1] = vertexIndex + 5 + 1 + sideNum; indices[num * 24 + 6 * sideNum + 2] = vertexIndex + 5 + sideNum; // 2. Polygon indices[num * 24 + 6 * sideNum + 3] = vertexIndex + 5 + 1 + sideNum; indices[num * 24 + 6 * sideNum + 4] = vertexIndex + sideNum; indices[num * 24 + 6 * sideNum + 5] = vertexIndex + 1 + sideNum; } // for (num) // Go to the next 5 vertices vertexIndex += 5; } // for (num) // Set road back index buffer roadIb = new IndexBuffer( BaseGame.Device, typeof(int), indices.Length, ResourceUsage.WriteOnly, ResourceManagementMode.Automatic); roadIb.SetData(indices); #endregion #region Generate the road back vertices // We need 4 vertices per cross-section edge of the road back hull roadBackVertices = new TangentVertex[points.Count * 4]; for (int num = 0; num < points.Count; num++) { // Left side of the road roadBackVertices[num * 4 + 0] = points[num].LeftTangentVertex; roadBackVertices[num * 4 + 0].uv = new Vector2( roadBackVertices[num * 4 + 0].U * RoadBackHullTextureWidthFactor, 0.0f); // Left lower side of the road roadBackVertices[num * 4 + 1] = points[num].BottomLeftSideTangentVertex; roadBackVertices[num * 4 + 1].uv = new Vector2( roadBackVertices[num * 4 + 0].U * RoadBackHullTextureWidthFactor, RoadBackSideTextureHeight); // Right lower side of the road roadBackVertices[num * 4 + 2] = points[num].BottomRightSideTangentVertex; roadBackVertices[num * 4 + 2].uv = new Vector2( roadBackVertices[num * 4 + 0].U * RoadBackHullTextureWidthFactor, 1.0f - RoadBackSideTextureHeight); // Right side of the road roadBackVertices[num * 4 + 3] = points[num].RightTangentVertex; roadBackVertices[num * 4 + 3].uv = new Vector2( roadBackVertices[num * 4 + 3].U * RoadBackHullTextureWidthFactor, 1.0f); } // for (num) // Set road back vertex buffer roadBackVb = new VertexBuffer( BaseGame.Device, typeof(TangentVertex), roadBackVertices.Length, ResourceUsage.WriteOnly, ResourceManagementMode.Automatic); roadBackVb.SetData(roadBackVertices); // Also calculate all indices, we have 6 polygons for each segment with // 3 vertices each. We got 1 segment less than points because the // last point is duplicated (different tex coords). int[] backIndices = new int[(points.Count-1) * 6 * 3]; vertexIndex = 0; for (int num = 0; num < points.Count-1; num++) { // We only use 4 vertices (and the next 4 vertices), // but we have to construct all 18 indices for our 6 polygons. for (int sideNum = 0; sideNum < 3; sideNum++) { // Each side needs 2 polygons. // 1. Polygon backIndices[num * 18 + 6 * sideNum + 0] = vertexIndex + sideNum; backIndices[num * 18 + 6 * sideNum + 1] = vertexIndex + 5 + sideNum; backIndices[num * 18 + 6 * sideNum + 2] = vertexIndex + 4 + sideNum; // 2. Polygon backIndices[num * 18 + 6 * sideNum + 3] = vertexIndex + 5 + sideNum; backIndices[num * 18 + 6 * sideNum + 4] = vertexIndex + sideNum; backIndices[num * 18 + 6 * sideNum + 5] = vertexIndex + 1 + sideNum; } // for (num) // Go to the next 4 vertices vertexIndex += 4; } // for (num) // Set road back index buffer roadBackIb = new IndexBuffer( BaseGame.Device, typeof(int), backIndices.Length, ResourceUsage.WriteOnly, ResourceManagementMode.Automatic); roadBackIb.SetData(backIndices); #endregion #region Generate guard rails leftRail = new GuardRail(points, GuardRail.Modes.Left, landscape); rightRail = new GuardRail(points, GuardRail.Modes.Right, landscape); #endregion #region Generate columns columns = new TrackColumns(points, landscape); #endregion GenerateObjectsForTrack(landscape); }