public TerrainBlock(Terrain terrain, int depth, GraphicsDevice GraphicsDevice, Effect effect, PlanetBlock planetBlock, Planet.GetNeighbourDelegate method, Point location,TerrainBlock parent, Vector3 blockOffset = new Vector3()) { this.GraphicsDevice = GraphicsDevice; this.effect = effect; this.depth = depth; this.planet = true; this.waterSphere = new BoundingSphere(Vector3.Zero, Terrain.PlanetRadius + Planet.HeightMag); this.GetNeighbour = method; this.location = location; this.parent = parent; if (blockOffset == Vector3.Zero) this.blockOffset = new Vector3(0, 0, Planet.PlanetRes); else this.blockOffset = new Vector3(blockOffset.X, blockOffset.Y, blockOffset.Z); this.planet = planet; this.pWidth = terrain.Size; this.busy = false; this.baseTexture = terrain.baseTexture; this.children = new TerrainBlock[BlockRes, BlockRes]; this.terrain = new Terrain[BlockRes, BlockRes]; if (planet) this.SplitMainTerrainPlanet(terrain); this.visible = true; //this.SplitChildren(Vector3.Zero); }
public void SplitChildrenPlanet(object input) { Vector3 position = (Vector3)input; if (this.depth >= maxDepth) return; if (this.busy) return; this.busy = true; for (int x = 0; x < BlockRes; x++) for (int y = 0; y < BlockRes; y++) { int t = this.terrain[x, y].Size - 1; Vector3 a = this.terrain[x, y].Center + this.terrain[x, y].Position;//c Vector3 b = this.terrain[x, y].GetAdjustedPos(this.terrain[x, y].vertices[0].Position) + this.terrain[x, y].Position;//NW Vector3 c = this.terrain[x, y].GetAdjustedPos(this.terrain[x, y].vertices[t].Position) + this.terrain[x, y].Position;//NE Vector3 d = this.terrain[x, y].GetAdjustedPos(this.terrain[x, y].vertices[this.terrain[x, y].vertices.Count() - 1].Position) + this.terrain[x, y].Position;//SE Vector3 e = this.terrain[x, y].GetAdjustedPos(this.terrain[x, y].vertices[this.terrain[x, y].vertices.Count() - t - 1].Position) + this.terrain[x, y].Position;//SW //float d = (Vector3.Cross((a - b), (b - position))).Length() / (a - b).Length(); if (((a - position).Length() > Terrain.PlanetRadius / (1.1f * (Math.Pow(2, this.depth))) && (b - position).Length() > Terrain.PlanetRadius / (1.1f * (Math.Pow(2, this.depth))) && (c - position).Length() > Terrain.PlanetRadius / (1.1f * (Math.Pow(2, this.depth))) && (d - position).Length() > Terrain.PlanetRadius / (1.1f * (Math.Pow(2, this.depth))) && (e - position).Length() > Terrain.PlanetRadius / (1.1f * (Math.Pow(2, this.depth)))) || waterSphere.Contains(new BoundingBox(b, d)) == ContainmentType.Contains) { if (this.children[x, y] != null) { this.children[x, y].nullChildren(); this.children[x, y] = null; } continue; } if (children[x, y] == null) { int size = Planet.PlanetRes; Terrain tmp = new Terrain(terrain[x, y].CellSize / 4.0f, terrain[x, y].Height, terrain[x, y].TextureTiling, size, new Vector3(terrain[x, y].Position.X, terrain[x, y].Position.Y, terrain[x, y].Position.Z), effect, baseTexture, Terrain.Type.CubeFace, this.depth + 1); float[,] heights = new float[size, size]; for (int x1 = 0; x1 < size; x1++) for (int y1 = 0; y1 < size; y1++) heights[x1, y1] = this.terrain[x, y].heightMaps[x1 / 2, y1 / 2]; Vector3 blcOff = new Vector3(blockOffset.X, blockOffset.Y, (blockOffset.Z - 1) * 2 + 1); blcOff.X *= 2; blcOff.Y *= 2; blcOff.X += (size - 1) * x; blcOff.Y += (size - 1) * y; tmp.GenerateCustom(new Fractal(size, (this.depth + 1) * 8).stepFrac(heights, 1), blcOff); tmp.GlobalRot = terrain[x, y].GlobalRot; TerrainBlock tb = new TerrainBlock(tmp, this.depth + 1, GraphicsDevice, effect, this.planetBlock, this.GetNeighbour, new Point(x, y), this, blcOff); children[x, y] = tb; } if (children[x, y] != null) children[x, y].SplitChildrenPlanet(position); } this.busy = false; }
public List<float>[] GetNeighbourTerrain(Point myLoc, TerrainBlock parent) { //ltrb List<float>[] result = new List<float>[4]; if (parent == null) return result; if (myLoc.X == 0 && myLoc.Y == 0) { result[2] = parent.terrain[1, 0].MyRawHeightBorders[0]; result[3] = parent.terrain[0, 1].MyRawHeightBorders[1]; } else if (myLoc.X == 0 && myLoc.Y == 1) { result[1] = parent.terrain[0, 0].MyRawHeightBorders[3]; result[2] = parent.terrain[1, 1].MyRawHeightBorders[0]; } else if (myLoc.X == 1 && myLoc.Y == 0) { result[0] = parent.terrain[0, 0].MyRawHeightBorders[2]; result[3] = parent.terrain[1, 1].MyRawHeightBorders[1]; } else if (myLoc.X == 1 && myLoc.Y == 1) { result[0] = parent.terrain[0, 1].MyRawHeightBorders[2]; result[1] = parent.terrain[1, 0].MyRawHeightBorders[3]; } return result; }
public Planet(GraphicsDevice GraphicsDevice, ContentManager Content) { this.isWater = false; Effect effect = Content.Load<Effect>(@"effects/PPModel"); Texture2D texture = Content.Load<Texture2D>(@"textures/base"); Vector3 pos = Vector3.Zero; top = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, effect, texture, Terrain.Type.CubeFace); top.GenerateFractual(); float[][] borders = new float[4][]; borders[2] = top.MyHeightBorders[0].ToArray(); left = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, effect, texture, Terrain.Type.CubeFace); left.GenerateFractualSlice(new Vector3(0, 0, 90), borders, Fractal.BorderType.Right); borders = new float[4][]; borders[0] = top.MyHeightBorders[2].ToArray(); right = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, effect, texture, Terrain.Type.CubeFace); right.GenerateFractualSlice(new Vector3(0, 0, -90), borders, Fractal.BorderType.Left); borders = new float[4][]; borders[0] = left.MyHeightBorders[3].ToArray(); borders[1] = top.MyHeightBorders[3].ToArray(); borders[2] = right.MyHeightBorders[3].ToArray(); Array.Reverse(borders[0]); front = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, effect, texture, Terrain.Type.CubeFace); front.GenerateFractualSlice(new Vector3(90, 0, 0), borders, Fractal.BorderType.Left | Fractal.BorderType.Top | Fractal.BorderType.Right); borders = new float[4][]; borders[0] = left.MyHeightBorders[1].ToArray(); borders[2] = right.MyHeightBorders[1].ToArray(); borders[3] = top.MyHeightBorders[1].ToArray(); Array.Reverse(borders[2]); back = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, effect, texture, Terrain.Type.CubeFace); back.GenerateFractualSlice(new Vector3(-90, 0, 0), borders, Fractal.BorderType.Left | Fractal.BorderType.Bottom | Fractal.BorderType.Right); borders = new float[4][]; borders[0] = left.MyHeightBorders[0].ToArray(); borders[1] = front.MyHeightBorders[3].ToArray(); borders[2] = right.MyHeightBorders[2].ToArray(); borders[3] = back.MyHeightBorders[1].ToArray(); Array.Reverse(borders[0]); Array.Reverse(borders[2]); bottom = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, effect, texture, Terrain.Type.CubeFace); bottom.GenerateFractualSlice(new Vector3(180, 0, 0), borders, Fractal.BorderType.All); /////////////////// top.loadPosBorders(left.MyRawHeightBorders[2], Fractal.BorderType.Left, false); top.loadPosBorders(right.MyRawHeightBorders[0], Fractal.BorderType.Right, false); top.loadPosBorders(front.MyRawHeightBorders[1], Fractal.BorderType.Bottom, false); top.loadPosBorders(back.MyRawHeightBorders[3], Fractal.BorderType.Top, false); top.PostNormalize(); left.loadPosBorders(top.MyRawHeightBorders[0], Fractal.BorderType.Right, false); left.loadPosBorders(front.MyRawHeightBorders[0], Fractal.BorderType.Bottom, true); left.loadPosBorders(back.MyRawHeightBorders[0], Fractal.BorderType.Top, false); left.loadPosBorders(bottom.MyRawHeightBorders[0], Fractal.BorderType.Left, true); left.PostNormalize(); right.loadPosBorders(top.MyRawHeightBorders[2], Fractal.BorderType.Left, false); right.loadPosBorders(front.MyRawHeightBorders[2], Fractal.BorderType.Bottom, false); right.loadPosBorders(back.MyRawHeightBorders[2], Fractal.BorderType.Top, true); right.loadPosBorders(bottom.MyRawHeightBorders[2], Fractal.BorderType.Right, true); right.PostNormalize(); front.loadPosBorders(top.MyRawHeightBorders[3], Fractal.BorderType.Top, false); front.loadPosBorders(left.MyRawHeightBorders[3], Fractal.BorderType.Left, true); front.loadPosBorders(right.MyRawHeightBorders[3], Fractal.BorderType.Right, false); front.loadPosBorders(bottom.MyRawHeightBorders[1], Fractal.BorderType.Bottom, false); front.PostNormalize(); back.loadPosBorders(top.MyRawHeightBorders[1], Fractal.BorderType.Bottom, false); back.loadPosBorders(right.MyRawHeightBorders[1], Fractal.BorderType.Right, true); back.loadPosBorders(left.MyRawHeightBorders[1], Fractal.BorderType.Left, false); back.loadPosBorders(bottom.MyRawHeightBorders[3], Fractal.BorderType.Top, false); back.PostNormalize(); bottom.loadPosBorders(left.MyRawHeightBorders[0], Fractal.BorderType.Left, true); bottom.loadPosBorders(front.MyRawHeightBorders[3], Fractal.BorderType.Top, false); bottom.loadPosBorders(right.MyRawHeightBorders[2], Fractal.BorderType.Right, true); bottom.loadPosBorders(back.MyRawHeightBorders[1], Fractal.BorderType.Bottom, false); bottom.PostNormalize(); topBlock = new TerrainBlock(top, 0, GraphicsDevice, effect, TerrainBlock.PlanetBlock.Top, this.GetNeighbourTerrain, new Point(), null); leftBlock = new TerrainBlock(left, 0, GraphicsDevice, effect, TerrainBlock.PlanetBlock.Left, this.GetNeighbourTerrain, new Point(), null); rightBlock = new TerrainBlock(right, 0, GraphicsDevice, effect, TerrainBlock.PlanetBlock.Right, this.GetNeighbourTerrain, new Point(), null); frontBlock = new TerrainBlock(front, 0, GraphicsDevice, effect, TerrainBlock.PlanetBlock.Front, this.GetNeighbourTerrain, new Point(), null); backBlock = new TerrainBlock(back, 0, GraphicsDevice, effect, TerrainBlock.PlanetBlock.Back, this.GetNeighbourTerrain, new Point(), null); bottomBlock = new TerrainBlock(bottom, 0, GraphicsDevice, effect, TerrainBlock.PlanetBlock.Bottom, this.GetNeighbourTerrain, new Point(), null); topBlock.GetNeighbour = this.GetNeighbourTerrain; leftBlock.GetNeighbour = this.GetNeighbourTerrain; rightBlock.GetNeighbour = this.GetNeighbourTerrain; frontBlock.GetNeighbour = this.GetNeighbourTerrain; backBlock.GetNeighbour = this.GetNeighbourTerrain; bottomBlock.GetNeighbour = this.GetNeighbourTerrain; water = new Planet(GraphicsDevice, Content, true); }
public Planet(GraphicsDevice GraphicsDevice, ContentManager Content, Vector3 sunPosition) { this.isWater = false; Vector3 pos = Vector3.Zero; top = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, new Vector3(1, -1, 0), GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"), Content.Load<Texture2D>(@"textures/base"), Terrain.Type.CubeFace); top.GenerateFractual(); top.LightPosition = sunPosition; topBlock = new TerrainBlock(top, 0, true, GraphicsDevice, Content.Load<Effect>(@"effects/Terrain")); //l,t,r,b float[,] borders = new float[4, PlanetRes]; for (int i = 0; i < 4; i++) for (int c = 0; c < PlanetRes; c++) if (i == 2) borders[i, c] = top.heightMaps[0, c]; left = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, new Vector3(1, -1, 0), GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"), Content.Load<Texture2D>(@"textures/base"), Terrain.Type.CubeFace); left.GenerateFractualSlice(new Vector3(0, 0, 90), borders, Fractal.BorderType.Right); left.LightPosition = sunPosition; leftBlock = new TerrainBlock(left, 0, true, GraphicsDevice, Content.Load<Effect>(@"effects/Terrain")); //l,t,r,b borders = new float[4, PlanetRes]; for (int i = 0; i < 4; i++) for (int c = 0; c < PlanetRes; c++) if (i == 0) borders[i, c] = top.heightMaps[(PlanetRes - 1), c]; right = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, new Vector3(1, -1, 0), GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"), Content.Load<Texture2D>(@"textures/base"), Terrain.Type.CubeFace); right.GenerateFractualSlice(new Vector3(0, 0, -90), borders, Fractal.BorderType.Left); right.LightPosition = sunPosition; rightBlock = new TerrainBlock(right, 0, true, GraphicsDevice, Content.Load<Effect>(@"effects/Terrain")); //l,t,r,b borders = new float[4, PlanetRes]; for (int i = 0; i < 4; i++) for (int c = 0; c < PlanetRes; c++) if (i == 0) borders[i, c] = left.heightMaps[(PlanetRes - 1) - c, (PlanetRes - 1)]; else if (i == 1) borders[i, c] = top.heightMaps[c, (PlanetRes - 1)]; else if (i == 2) borders[i, c] = right.heightMaps[c, (PlanetRes - 1)]; front = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, new Vector3(1, -1, 0), GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"), Content.Load<Texture2D>(@"textures/base"), Terrain.Type.CubeFace); front.GenerateFractualSlice(new Vector3(90, 0, 0), borders, Fractal.BorderType.Left | Fractal.BorderType.Top | Fractal.BorderType.Right); front.LightPosition = sunPosition; frontBlock = new TerrainBlock(front, 0, true, GraphicsDevice, Content.Load<Effect>(@"effects/Terrain")); //l,t,r,b borders = new float[4, PlanetRes]; for (int i = 0; i < 4; i++) for (int c = 0; c < PlanetRes; c++) if (i == 0) borders[i, c] = left.heightMaps[c, 0]; else if (i == 2) borders[i, c] = right.heightMaps[(PlanetRes - 1) - c, 0]; else if (i == 3) borders[i, c] = top.heightMaps[c, 0]; back = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, new Vector3(1, -1, 0), GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"), Content.Load<Texture2D>(@"textures/base"), Terrain.Type.CubeFace); back.GenerateFractualSlice(new Vector3(-90, 0, 0), borders, Fractal.BorderType.Left | Fractal.BorderType.Bottom | Fractal.BorderType.Right); back.LightPosition = sunPosition; backBlock = new TerrainBlock(back, 0, true, GraphicsDevice, Content.Load<Effect>(@"effects/Terrain")); //l,t,r,b borders = new float[4, PlanetRes]; for (int i = 0; i < 4; i++) for (int c = 0; c < PlanetRes; c++) if (i == 0) borders[i, c] = left.heightMaps[0, (PlanetRes - 1) - c]; else if (i == 1) borders[i, c] = front.heightMaps[c, (PlanetRes - 1)]; else if (i == 2) borders[i, c] = right.heightMaps[(PlanetRes - 1), (PlanetRes - 1) - c]; else if (i == 3) borders[i, c] = back.heightMaps[c, 0]; bottom = new Terrain(4096, HeightMag, 1f, PlanetRes, pos, new Vector3(1, -1, 0), GraphicsDevice, Content.Load<Effect>(@"effects/Terrain"), Content.Load<Texture2D>(@"textures/base"), Terrain.Type.CubeFace); bottom.GenerateFractualSlice(new Vector3(180, 0, 0), borders, Fractal.BorderType.All); bottom.LightPosition = sunPosition; bottomBlock = new TerrainBlock(bottom, 0, true, GraphicsDevice, Content.Load<Effect>(@"effects/Terrain")); water = new Planet(GraphicsDevice, Content, true, sunPosition); }
public void SplitChildrenPlanet(object input) { Vector3 position = (Vector3)input; if (this.depth >= maxDepth) return; if (this.busy) return; this.busy = true; for (int i = 0; i < 4; i++) { int t = this.terrain[i].width - 1; Vector3 a = this.terrain[i].Center + this.terrain[i].Position;//c Vector3 b = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[0].Position) + this.terrain[i].Position;//NW Vector3 c = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[t].Position) + this.terrain[i].Position;//NE Vector3 d = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[this.terrain[i].vertices.Count() - 1].Position) + this.terrain[i].Position;//SE Vector3 e = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[this.terrain[i].vertices.Count() - t - 1].Position) + this.terrain[i].Position;//SW //float d = (Vector3.Cross((a - b), (b - position))).Length() / (a - b).Length(); if (((a - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (2.5f - (0 * depth)) && (b - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (2.5f - (0 * depth)) && (c - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (2.5f - (0 * depth)) && (d - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (2.5f - (0 * depth)) && (e - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (2.5f - (0 * depth))) || waterSphere.Contains(new BoundingBox(b, d)) == ContainmentType.Contains) { if (this.children[i] != null) { this.children[i].nullChildren(); this.children[i] = null; } continue; } if (children[i] == null) { Terrain tmp = new Terrain(terrain[i].cellSize / 2.0f, terrain[i].height, terrain[i].textureTiling, (int)(terrain[i].width * 2 - 1), new Vector3(terrain[i].Position.X, terrain[i].Position.Y, terrain[i].Position.Z), terrain[i].lightDirection, GraphicsDevice, effect, baseTexture, Terrain.Type.CubeFace); int size = terrain[i].width * 2 - 1; float[,] heights = new float[size, size]; for (int x = 0; x < size; x += 2) for (int y = 0; y < size; y += 2) heights[x, y] = terrain[i].heightMaps[x / 2, y / 2]; Vector3 blcOff = new Vector3(blockOffset.X, blockOffset.Y, -1); switch (i) { case 0: blcOff.X *= 2; blcOff.Y *= 2; break; case 1: blcOff.X *= 2; blcOff.X += size - 1; blcOff.Y *= 2; break; case 2: blcOff.X *= 2; blcOff.Y *= 2; blcOff.Y += size - 1; break; case 3: blcOff.X *= 2; blcOff.X += size - 1; blcOff.Y *= 2; blcOff.Y += size - 1; break; } tmp.GenerateCustom(new Fractal(size, this.depth + 8).singleStep(heights), terrain[i].LightPosition, blcOff); tmp.GlobalRot = terrain[i].GlobalRot; TerrainBlock tb = new TerrainBlock(tmp, this.depth + 1, this.planet, GraphicsDevice, effect, blcOff); children[i] = tb; } if (children[i] != null) children[i].SplitChildren(position); } this.busy = false; }
public void SplitChildren(object input) { if (this.planet) { this.SplitChildrenPlanet(input); return; } Vector3 position = (Vector3)input; if (this.depth >= maxDepth) return; if (this.busy) return; this.busy = true; for (int i = 0; i < 4; i++) { int t = this.terrain[i].width - 1; Vector3 a = this.terrain[i].Center + this.terrain[i].Position;//c Vector3 b = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[0].Position) + this.terrain[i].Position;//NW Vector3 c = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[t].Position) + this.terrain[i].Position;//NE Vector3 d = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[this.terrain[i].vertices.Count() - 1].Position) + this.terrain[i].Position;//SE Vector3 e = this.terrain[i].getAdjustedPos(this.terrain[i].vertices[this.terrain[i].vertices.Count() - t - 1].Position) + this.terrain[i].Position;//SW //float d = (Vector3.Cross((a - b), (b - position))).Length() / (a - b).Length(); if ((a - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (1.75f + (0.075f * depth)) && (b - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (1.25f + (0.075f * depth)) && (c - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (1.25f + (0.075f * depth)) && (d - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (1.25f + (0.075f * depth)) && (e - position).Length() > this.terrain[i].width * this.terrain[i].cellSize * (1.25f + (0.075f * depth))) { if (this.children[i] != null) { this.children[i].nullChildren(); this.children[i] = null; } continue; } float sizeOffset = (float)terrain[i].cellSize * ((float)terrain[i].width / 8.0f); Terrain tmp = new Terrain(terrain[i].cellSize / 2.0f, terrain[i].height, terrain[i].textureTiling, (int)(terrain[i].width * 2 - 1), new Vector3(terrain[i].Position.X - sizeOffset, terrain[i].Position.Y, terrain[i].Position.Z - sizeOffset), terrain[i].lightDirection,GraphicsDevice,effect, baseTexture); int size = terrain[i].width * 2 - 1; float[,] heights = new float[size, size]; for (int x = 0; x < size; x += 2) for (int y = 0; y < size; y += 2) heights[x, y] = terrain[i].heightMaps[x / 2, y / 2]; if (children[i] == null) { tmp.GenerateCustom(new Fractal(size, this.depth + 8).singleStep(heights)); TerrainBlock tb = new TerrainBlock(tmp, this.depth + 1, this.planet, GraphicsDevice, effect); children[i] = tb; } if (children[i] != null) children[i].SplitChildren(position); } this.busy = false; }