private void CalculateTextureWeights()
        {
            lowMark  = 15 * scale.Y;
            highMark = 180 * scale.Y;

            for (int i = 0; i < vertices.Length; i++)
            {
                float   height      = vertices[i].Position.Y;
                double  normalAngle = GMath.AngleOfIncline(vertices[i].Normal);
                Vector4 weights     = Vector4.Zero;                        // start all weights at 0

                if (height < lowMark)                                      // height is in the lower third
                {
                    weights.Y = height / lowMark;                          // percent weight 2
                    weights.X = 1 - weights.Y;                             // percent weight 1
                }
                else if (height < highMark)                                // height is in the middle third
                {
                    weights.Z = (height - lowMark) / (highMark - lowMark); // percent weight 3
                    weights.Y = 1 - weights.Z;                             // percent weight 2
                }
                else // height is in the top third
                {
                    weights.W = (height - highMark) / (255 - highMark) * (float)(90 - normalAngle) / 90.0f; // percent weight 4
                    weights.Z = 1 - weights.W;                                                              // percent weight 3
                }

                // surfaces which have steep surfaces should be rocky
                if (normalAngle < 50)
                {
                    float rockyness = MathHelper.Clamp((float)(90 - normalAngle) / 90.0f, 0, 1);
                    weights   *= 1 - rockyness;
                    weights.W += rockyness;
                }
                // surfaces which have shallow angles mix in some of the third texture
                if (normalAngle > 75 && vertices[i].Position.Y > lowMark)
                {
                    weights   *= 0.4f;
                    weights.Z += 0.6f;
                }

                vertices[i].TextureWeights = weights;
            }
        }
Пример #2
0
        /// <summary>
        /// Creates and connects all nodes in the grid
        /// </summary>
        private void BuildGrid(Sim.Environment.Terrain terrain)
        {
            // create the nodes at their proper locations
            nodes = new Node[width * length];
            for (int z = 0; z < length; z++)
            {
                for (int x = 0; x < width; x++)
                {
                    int   i = x + z * width;
                    float y = terrain.CalculateHeight(x * spacing, z * spacing);
                    nodes[i] = new Node(new Vector3(x * spacing, y, z * spacing));

                    if (y < 5) // underwater
                    {
                        nodes[i].State = NodeState.Invalid;
                    }
                    else if (GMath.AngleOfIncline(terrain.CalculateSurfaceNormal(x * spacing, z * spacing)) < 50)
                    {
                        nodes[i].State = NodeState.Invalid;
                    }
                }
            }

            // connect adjacent nodes
            for (int z = 0; z < length; z++)
            {
                for (int x = 0; x < width; x++)
                {
                    Node n = nodes[x + z * width];

                    // adjacent nodes exist in all 8 directions if the current node is part of the
                    // interior of the grid; if the node is on an edge, certain spots are empty
                    bool addN = z > 0;
                    bool addS = z < length - 1;
                    bool addW = x > 0;
                    bool addE = x < width - 1;

                    if (addN)
                    {
                        n.AdjacentNodes.Add(nodes[x + (z - 1) * width]);                    // N
                        if (addE)
                        {
                            n.AdjacentNodes.Add(nodes[(x + 1) + (z - 1) * width]);          // NE
                        }
                        if (addW)
                        {
                            n.AdjacentNodes.Add(nodes[(x - 1) + (z - 1) * width]);          // NW
                        }
                    }

                    if (addS)
                    {
                        n.AdjacentNodes.Add(nodes[x + (z + 1) * width]);                    // S
                        if (addE)
                        {
                            n.AdjacentNodes.Add(nodes[(x + 1) + (z + 1) * width]);          // SE
                        }
                        if (addW)
                        {
                            n.AdjacentNodes.Add(nodes[(x - 1) + (z + 1) * width]);          // SW
                        }
                    }

                    if (addE)
                    {
                        n.AdjacentNodes.Add(nodes[(x + 1) + z * width]);                    // E
                    }
                    if (addW)
                    {
                        n.AdjacentNodes.Add(nodes[(x - 1) + z * width]);                    // W
                    }
                }
            }
        }