예제 #1
0
        }         // 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);
        }