Beispiel #1
0
        /// <summary>
        /// Test column vertices
        /// </summary>
        //[Test]
        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)
                });
        }
Beispiel #2
0
        /// <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,
                BufferUsage.WriteOnly);
            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,
                BufferUsage.WriteOnly);
            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,
                BufferUsage.WriteOnly);
            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,
                BufferUsage.WriteOnly);
            roadBackIb.SetData(backIndices);
            #endregion

            #region Generate the road tunnel vertices
            // Only generate tunnels for the parts were we want to have tunnels for.
            int totalTunnelLength = 0;
            foreach (RoadHelperPosition tunnelPos in helperPositions)
                if (tunnelPos.type == TrackData.RoadHelper.HelperType.Tunnel)
                    totalTunnelLength += 1+(tunnelPos.endNum - tunnelPos.startNum);

            // Lets use 4 vertices per segment, we could improve that later
            // by adding more vertices for a round tunnel.
            roadTunnelVertices = new TangentVertex[totalTunnelLength * 4];
            vertexIndex = 0;
            foreach (RoadHelperPosition tunnelPos in helperPositions)
                if (tunnelPos.type == TrackData.RoadHelper.HelperType.Tunnel)
                    for (int num = tunnelPos.startNum; num <= tunnelPos.endNum; num++)
                {
                    // Left side of the road
                    roadTunnelVertices[vertexIndex + 0] =
                        points[num].LeftTangentVertex;
                    roadTunnelVertices[vertexIndex + 0].uv = new Vector2(
                        roadTunnelVertices[vertexIndex + 0].U * RoadTunnelTextureWidthFactor,
                        0.0f);

                    // Left top side of the road
                    roadTunnelVertices[vertexIndex + 1] =
                        points[num].TunnelTopLeftSideTangentVertex;
                    roadTunnelVertices[vertexIndex + 1].uv = new Vector2(
                        roadTunnelVertices[vertexIndex + 1].U * RoadTunnelTextureWidthFactor,
                        RoadTunnelSideTextureHeight);

                    // Right top side of the road
                    roadTunnelVertices[vertexIndex + 2] =
                        points[num].TunnelTopRightSideTangentVertex;
                    roadTunnelVertices[vertexIndex + 2].uv = new Vector2(
                        roadTunnelVertices[vertexIndex + 2].U * RoadTunnelTextureWidthFactor,
                        1.0f - RoadTunnelSideTextureHeight);

                    // Right side of the road
                    roadTunnelVertices[vertexIndex + 3] =
                        points[num].RightTangentVertex;
                    roadTunnelVertices[vertexIndex + 3].uv = new Vector2(
                        roadTunnelVertices[vertexIndex + 3].U * RoadTunnelTextureWidthFactor,
                        1.0f);

                    // Adjust normals for the 2 lower points
                    roadTunnelVertices[vertexIndex + 0].normal *= -1;
                    roadTunnelVertices[vertexIndex + 3].normal *= -1;
                    roadTunnelVertices[vertexIndex + 0].tangent *= -1;
                    roadTunnelVertices[vertexIndex + 3].tangent *= -1;

                    vertexIndex += 4;
                } // foreach for (num)

            // Set road back vertex buffer
            if (roadTunnelVertices.Length > 0)
            {
                roadTunnelVb = new VertexBuffer(
                    BaseGame.Device,
                    typeof(TangentVertex),
                    roadTunnelVertices.Length,
                    BufferUsage.WriteOnly);
                roadTunnelVb.SetData(roadTunnelVertices);

                // 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 totalIndices = 0;
                foreach (RoadHelperPosition tunnelPos in helperPositions)
                    if (tunnelPos.type == TrackData.RoadHelper.HelperType.Tunnel)
                        totalIndices += (tunnelPos.endNum - tunnelPos.startNum);
                roadTunnelIndices = new int[totalIndices * 6 * 3];
                vertexIndex = 0;
                int tunnelIndex = 0;
                foreach (RoadHelperPosition tunnelPos in helperPositions)
                    if (tunnelPos.type == TrackData.RoadHelper.HelperType.Tunnel)
                {
                    for (int num = tunnelPos.startNum; num < tunnelPos.endNum; 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.
                            // Note: This polygons are rendered with culling off because
                            // we want to see the inside and outside of the tunnel.

                            // 1. Polygon
                            roadTunnelIndices[tunnelIndex + 0] =
                                vertexIndex + sideNum;
                            roadTunnelIndices[tunnelIndex + 2] =
                                vertexIndex + 4 + sideNum;
                            roadTunnelIndices[tunnelIndex + 1] =
                                vertexIndex + 5 + sideNum;

                            // 2. Polygon
                            roadTunnelIndices[tunnelIndex + 3] =
                                vertexIndex + 5 + sideNum;
                            roadTunnelIndices[tunnelIndex + 5] =
                                vertexIndex + 1 + sideNum;
                            roadTunnelIndices[tunnelIndex + 4] =
                                vertexIndex + sideNum;

                            tunnelIndex += 6;
                        } // for (sideNum)

                        // Go to the next 4 vertices
                        vertexIndex += 4;
                    } // for (num)

                    // Skip 4 vertices till the next tunnel
                    vertexIndex += 4;
                } // foreach (tunnelPos)

                // Set road back index buffer
                roadTunnelIb = new IndexBuffer(
                    BaseGame.Device,
                    typeof(int),
                    roadTunnelIndices.Length,
                    BufferUsage.WriteOnly);
                roadTunnelIb.SetData(roadTunnelIndices);
            } // if
            #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);
        }