/// <summary> /// Applies a random material distribution to the terrain grid. /// </summary> public void ApplyMaterialLayer(GridMaterial mat, float scale, Vector2 seed, float chance) { int s2 = Size * 2; for (int i = 1; i < s2; i++) { for (int j = 0; j < Size; j++) { GridFace face = new GridFace(i, j); Vector2 pos = face.ToCartesianCoords2D(); // pos += face.PointsUp() ? new Vector2(0f, 0.333f * 0.866f) : pos += new Vector2(0f, 0.667f * 0.866f); if (SimplexNoise.Generate(seed.X + pos.X * scale, seed.Y + pos.Y * scale) < chance) { Materials[i, j] = mat; } } } }
/// <summary> /// Applies a material distribution to the terrain grid, based on height. /// </summary> public void ApplyLowMaterialLayer(GridMaterial mat, float scale, Vector2 seed, float clamp, float mul) { int s2 = Size * 2; for (int i = 1; i < s2; i++) { for (int j = 0; j < Size; j++) { GridFace face = new GridFace(i, j); double h = 0; foreach (GridVertex vert in face.Corners()) { h += HeightMap[vert.U, vert.V]; } h *= 0.333f; Vector2 pos = face.ToCartesianCoords2D(); // pos += face.PointsUp() ? new Vector2(0f, 0.333f * 0.866f) : pos += new Vector2(0f, 0.667f * 0.866f); if ((SimplexNoise.Generate(seed.X + pos.X * scale, seed.Y + pos.Y * scale) - 0.5) * mul + h < clamp) { Materials[i, j] = mat; } } } }
/// <summary> /// Fired when entity is spawned. /// </summary> public override void OnSpawn() { Game game = Engine3D.Source as Game; // Generate the layer seeds, height map and materials int s2 = Size * 2; Seeds = new Vector2[Layers]; for (int i = 0; i < Layers; i++) { Seeds[i] = new Vector2((float)game.Random.NextDouble(), (float)game.Random.NextDouble()); } GenerateHeightMap(2.0f); ApplyClampedHeightMap(8.0f, 0.025f, 0.0f, 0.75f, Seeds[0]); ApplyHeightMap(0.5f, 0.25f, 0.5f, Seeds[1]); ApplyHighHeightMap(2.0f, 0.15f, 0.5f, 7.0f, Seeds[2]); GenerateMaterialLayer(GridMaterial.Grass); ApplyHighMaterialLayer(GridMaterial.Dirt, 0.05f, Seeds[3], 7.0f, 3.0f); ApplyHighMaterialLayer(GridMaterial.Rock, 0.025f, Seeds[4], 9.0f, 1.0f); ApplyLowMaterialLayer(GridMaterial.Water, 0.1f, Seeds[5], 3.0f, 0.5f); // Generate the terrain grid mesh: Vertices, Normals and Indices Builder = new Renderable.ListBuilder(); int n = s2 * Size * 3; Builder.Prepare(n); for (int i = 1; i < s2; i++) { for (int j = 0; j < Size; j++) { GridFace face = new GridFace(i, j); List <Vector3> vertices = new List <Vector3>(); foreach (GridVertex vert in face.Corners()) { vertices.Add(vert.ToCartesianCoords3D(HeightMap)); Builder.AddEmptyBoneInfo(); } Builder.Vertices.AddRange(vertices); Vector3[] vArray = vertices.ToArray(); Vector3 normal = Vector3.Cross(vArray[2] - vArray[0], vArray[1] - vArray[0]); normal.Normalize(); Builder.Normals.Add(normal); Builder.Normals.Add(normal); Builder.Normals.Add(normal); Vector4 c = Materials[i, j].Color.ToOpenTK(); Builder.Colors.Add(c); Builder.Colors.Add(c); Builder.Colors.Add(c); if (face.PointsUp()) { Builder.TexCoords.Add(new Vector3(0, 0, 0)); Builder.TexCoords.Add(new Vector3(0.5f, 1, 0)); Builder.TexCoords.Add(new Vector3(1, 0, 0)); } else { Builder.TexCoords.Add(new Vector3(1, 1, 0)); Builder.TexCoords.Add(new Vector3(0.5f, 0, 0)); Builder.TexCoords.Add(new Vector3(0, 1, 0)); } } } int count = Builder.Vertices.Count; for (uint k = 0; k < count; k++) { Builder.Indices.Add(k); } Rend = Builder.Generate(); BEPUutilities.Vector3 scaling = new BEPUutilities.Vector3(0.5, 1, -0.866); BEPUutilities.Quaternion rotation = BEPUutilities.Quaternion.CreateFromAxisAngle(BEPUutilities.Vector3.UnitX, MathHelper.PiOver2); BEPUutilities.Vector3 translation = BEPUutilities.Vector3.Zero; Body = new Terrain(new TerrainShape(HeightMap), new BEPUutilities.AffineTransform(ref scaling, ref rotation, ref translation)) { ImproveBoundaryBehavior = true }; }
/// <summary> /// Wether this grid face equals an object. /// </summary> /// <param name="obj">The object to compare to.</param> /// <returns>Wether they are equal.</returns> public override bool Equals(object obj) { GridFace face = (GridFace)obj; return(face.U == U && face.V == V); }