public override Octree <UInt16> Generate(int x, int y, int z, int size, int resolution = 1) { Octree <UInt16> octree = base.Generate(x, y, z, size, resolution); Random rand = new Random(Seed); UInt16 empty = BlockManager.GetID("Core_Empty"); UInt16[] sand = new UInt16[15]; UInt16[] rock = new UInt16[15]; for (int i = 0; i < 15; ++i) { sand[i] = BlockManager.GetID("MarsMiner_Sand", i); rock[i] = BlockManager.GetID("MarsMiner_Rock", i); } Face[] slopeFaces = new Face[] { Face.Front, Face.Left, Face.Back, Face.Right }; UInt16 boulder = BlockManager.GetID("MarsMiner_Boulder"); int min = System.Math.Min(myMinHilly, myMinPlains); int gradRange = 2; octree.SetCuboid(x, 0, z, size, System.Math.Min(myMinHilly, myMinPlains), size, rock[14]); if (y + size >= min) { int hillDiff = (myMaxHilly - myMinHilly) / 2; int hillMid = myMinHilly + hillDiff; int plainDiff = (myMinPlains - myMaxPlains) / 2; int plainMid = myMaxPlains + plainDiff; int maxCount = size / resolution; double hres = resolution / 2.0; int[,] heightmap = new int[maxCount + gradRange * 2, maxCount + gradRange * 2]; double[,] gradmap = new double[maxCount, maxCount]; for (int i = 0; i < maxCount + gradRange * 2; ++i) { double dx = (x + (i - gradRange) * resolution + hres) / 256.0; for (int j = 0; j < maxCount + gradRange * 2; ++j) { double dy = (z + (j - gradRange) * resolution + hres) / 256.0; double hillVal = Tools.Clamp(myHillyNoise.GetValue(dx, dy, 0.5) * hillDiff + hillMid, myMinHilly, myMaxHilly); double plainVal = Tools.Clamp(myHillyNoise.GetValue(dx, dy, 0.5) * plainDiff + plainMid, myMinPlains, myMaxPlains); double trans = Tools.Clamp((myTransNoise.GetValue(dx, dy, 0.5) + 1.0) / 2.0, 0.0, 1.0); //trans *= trans; int val = (int)System.Math.Floor(trans * hillVal + (1 - trans) * plainVal); heightmap[i, j] = val / resolution * resolution; } } for (int i = 0; i < maxCount; ++i) { for (int j = 0; j < maxCount; ++j) { double grad = 0; for (int gx = -gradRange; gx <= gradRange; ++gx) { for (int gy = -gradRange; gy <= gradRange; ++gy) { if (gx == 0 && gy == 0) { continue; } double dist = System.Math.Sqrt(gx * gx + gy * gy); int diff = heightmap[i + gradRange + gx, j + gradRange + gy] - heightmap[i + gradRange, j + gradRange]; grad += System.Math.Abs(diff) / dist; } } gradmap[i, j] = grad; } } Cuboid rcuboid = new Cuboid(0, 0, 0, resolution, 1, resolution); Cuboid scuboid = new Cuboid(0, 0, 0, 1, 1, 1); int[,] prev = null; for (int count = 1; count <= maxCount; count <<= 1) { int res = size / count; hres = res / 2.0; int[,] cur = new int[count, count]; int sca = res / resolution; rcuboid.Width = res; rcuboid.Depth = res; scuboid.Width = res; scuboid.Height = res; scuboid.Depth = res; for (int nx = 0; nx < count; ++nx) { int rx = x + nx * res; int px = nx >> 1; for (int nz = 0; nz < count; ++nz) { int rz = z + nz * res; int pz = nz >> 1; int realHeight = heightmap[nx * sca + gradRange, nz *sca + gradRange]; int height = realHeight / res * res; cur[nx, nz] = height; int prevHeight = (count == 1 ? 0 : prev[px, pz]); rcuboid.X = rx; rcuboid.Z = rz; rcuboid.Bottom = System.Math.Min(height, prevHeight); rcuboid.Top = System.Math.Max(height, prevHeight); if (height > prevHeight) { octree.SetCuboid(rcuboid, rock[14]); } else { octree.SetCuboid(rcuboid, empty); } if ((res == 1 || (resolution > 1 && height == realHeight)) && gradmap[nx, nz] <= 8.0 * res) { scuboid.X = rx; scuboid.Y = height - res; scuboid.Z = rz; octree.SetCuboid(scuboid, sand[14]); } } } prev = cur; } for (int colxi = 0; colxi < size / resolution; ++colxi) { int colx = colxi * resolution + x; for (int colzi = 0; colzi < size / resolution; ++colzi) { int colz = colzi * resolution + z; int height = heightmap[colxi + gradRange, colzi + gradRange]; OctreeLeaf <UInt16> curLeaf = octree.FindNode(colx, height - resolution, colz, resolution) as OctreeLeaf <UInt16>; if (curLeaf != null && curLeaf.Value != empty) { int[] ns = new int[] { heightmap[colxi + gradRange - 1, colzi + gradRange + 1], heightmap[colxi + gradRange + 0, colzi + gradRange + 1], heightmap[colxi + gradRange + 1, colzi + gradRange + 1], heightmap[colxi + gradRange - 1, colzi + gradRange + 0], heightmap[colxi + gradRange + 1, colzi + gradRange + 0], heightmap[colxi + gradRange - 1, colzi + gradRange - 1], heightmap[colxi + gradRange + 0, colzi + gradRange - 1], heightmap[colxi + gradRange + 1, colzi + gradRange - 1] }; bool[] bs = new bool[8]; for (int i = 0; i < 8; ++i) { bs[i] = ns[i] >= height; } int index = 0; if (bs[5] && (bs[3] && bs[6])) { index |= 1 << 0; } if (bs[7] && (bs[4] && bs[6])) { index |= 1 << 1; } if (bs[0] && (bs[1] && bs[3])) { index |= 1 << 2; } if (bs[2] && (bs[1] && bs[4])) { index |= 1 << 3; } if (index > 0) { octree.SetCuboid( colx, height - resolution, colz, resolution, resolution, resolution, (UInt16)(curLeaf.Value + index - 15)); } } } } } return(octree); }