public static TerrainData CreateNoiseTerrain(IntSize3 size, Random random) { var terrain = new TerrainData(size); var noise = CreateTerrainNoise(); var noisemap = CreateTerrainNoiseMap(noise, new IntSize2(size.Width, size.Height)); FillFromNoiseMap(terrain, noisemap); terrain.RescanLevelMap(); double xk = (random.NextDouble() * 2 - 1) * 0.01; double yk = (random.NextDouble() * 2 - 1) * 0.01; TerrainHelpers.CreateBaseMinerals(terrain, random, xk, yk); TerrainHelpers.CreateOreVeins(terrain, random, xk, yk); TerrainHelpers.CreateOreClusters(terrain, random); RiverGen.Generate(terrain, random); int soilLimit = size.Depth * 4 / 5; TerrainHelpers.CreateSoil(terrain, soilLimit); int grassLimit = terrain.Depth * 4 / 5; TerrainHelpers.CreateVegetation(terrain, random, grassLimit); return(terrain); }
static TerrainData CreateTerrain(IntSize3 size) { //var random = Helpers.Random; var random = new Random(1); var terrain = new TerrainData(size); var tg = new TerrainGenerator(terrain, random); var corners = new DiamondSquare.CornerData() { NE = 15, NW = 10, SW = 10, SE = 10, }; tg.Generate(corners, 5, 0.75, 2); int grassLimit = terrain.Depth * 4 / 5; TerrainHelpers.CreateVegetation(terrain, random, grassLimit); return(terrain); }
public static TerrainData CreateBallMap(IntSize3 size, int innerSide = 0) { var map = new TerrainData(size); int side = MyMath.Min(size.Width, size.Height, size.Depth); int r = side / 2 - 1; int ir = innerSide / 2 - 1; Parallel.For(0, size.Depth, z => { for (int y = 0; y < size.Height; ++y) for (int x = 0; x < size.Width; ++x) { var pr = Math.Sqrt((x - r) * (x - r) + (y - r) * (y - r) + (z - r) * (z - r)); var p = new IntVector3(x, y, z); if (pr < r && pr >= ir) map.SetTileDataNoHeight(p, TileData.GetNaturalWall(MaterialID.Granite)); else map.SetTileDataNoHeight(p, TileData.EmptyTileData); } }); map.RescanLevelMap(); return map; }
static TerrainData CreateOrLoadTerrain(IntSize3 size) { var path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location), "save"); string file = Path.Combine(path, "terrain-cache-hack.dat"); TerrainData terrain = null; try { var sw = Stopwatch.StartNew(); terrain = TerrainData.LoadTerrain(file, "fortress", size); sw.Stop(); Trace.TraceInformation("Load cached terrain {0} ms", sw.ElapsedMilliseconds); } catch (Exception e) { Trace.TraceError("Failed to load cached terrain: {0}", e.Message); } if (terrain == null) { terrain = CreateTerrain(size); var sw = Stopwatch.StartNew(); terrain.SaveTerrain(file, "fortress"); sw.Stop(); Trace.TraceInformation("Save cached terrain {0} ms", sw.ElapsedMilliseconds); } return terrain; }
public void InitializeWorld(World world, IntSize3 size) { CreateTerrain(size); IntVector3?stairs = null; foreach (var p2 in m_terrainData.Size.Plane.Range()) { var p = new IntVector3(p2, m_terrainData.Size.Depth - 1); var td = m_terrainData.GetTileData(p.Down); if (td.ID == TileID.Stairs) { stairs = p; break; } } if (stairs.HasValue == false) { throw new Exception(); } m_env = EnvironmentObject.Create(world, m_terrainData, VisibilityMode.LivingLOS, stairs.Value); CreateMonsters(); CreateDebugMonsterAtEntry(); }
static TerrainData CreateOrLoadTerrain(IntSize3 size) { var path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location), "save"); string file = Path.Combine(path, "terrain-cache-hack.dat"); TerrainData terrain = null; try { var sw = Stopwatch.StartNew(); terrain = TerrainData.LoadTerrain(file, "fortress", size); sw.Stop(); Trace.TraceInformation("Load cached terrain {0} ms", sw.ElapsedMilliseconds); } catch (Exception e) { Trace.TraceError("Failed to load cached terrain: {0}", e.Message); } if (terrain == null) { terrain = CreateTerrain(size); var sw = Stopwatch.StartNew(); terrain.SaveTerrain(file, "fortress"); sw.Stop(); Trace.TraceInformation("Save cached terrain {0} ms", sw.ElapsedMilliseconds); } return(terrain); }
public static TerrainData CreateCubeMap(IntSize3 size, int margin) { var map = new TerrainData(size); Parallel.For(0, size.Depth, z => { for (int y = 0; y < size.Height; ++y) { for (int x = 0; x < size.Width; ++x) { var p = new IntVector3(x, y, z); if (x < margin || y < margin || z < margin || x >= size.Width - margin || y >= size.Height - margin || z >= size.Depth - margin) { map.SetTileDataNoHeight(p, TileData.EmptyTileData); } else { map.SetTileDataNoHeight(p, TileData.GetNaturalWall(MaterialID.Granite)); } } } }); map.RescanLevelMap(); return(map); }
public static void Calculate3(IntVector3 viewerLocation, int visionRange, VisionMap visibilityMap, IntSize3 mapSize, Func<IntVector3, bool> blockerDelegate) { visibilityMap.Clear(); if (blockerDelegate(viewerLocation) == true) return; var g = new IntGrid3(new IntVector3(), mapSize); g = g.Offset(-viewerLocation.X, -viewerLocation.Y, -viewerLocation.Z); var vr = new IntVector3(visionRange, visionRange, visionRange); g = g.Intersect(new IntGrid3(vr, -vr)); int visionRangeSquared = (visionRange + 1) * (visionRange + 1); // +1 to get a bit bigger view area foreach (var dst in g.Range()) { if (dst.LengthSquared > visionRangeSquared) continue; bool vis = FindLos3(viewerLocation, dst, blockerDelegate); visibilityMap[dst] = vis; // XXX Cheat a bit so that the floor will be visible if (vis && dst.Z == 0 && viewerLocation.Z > 1) { visibilityMap[dst.SetZ(dst.Z - 1)] = true; } } }
protected MapChunkTestBase(IntSize3 size) { this.Size = size; //m_dict = new Dictionary<uint, Map1D>(); int cw = size.Width >> CHUNK_SHIFT_X; int ch = size.Height >> CHUNK_SHIFT_Y; int cd = size.Depth >> CHUNK_SHIFT_Z; uint max = 0; m_arr = new Chunk[512]; for (int cz = 0; cz < cd; ++cz) { for (int cy = 0; cy < ch; ++cy) { for (int cx = 0; cx < cw; ++cx) { uint hash = hashCode(cx, cy, cz); max = Math.Max(max, hash); if (cx % 2 == 0) { //if (cz > cd / 2) m_arr[hash] = new Chunk(); } } } } Console.WriteLine("max {0}", max); }
public static TerrainData CreateBallMap(IntSize3 size, int innerSide = 0) { var map = new TerrainData(size); int side = MyMath.Min(size.Width, size.Height, size.Depth); int r = side / 2 - 1; int ir = innerSide / 2 - 1; Parallel.For(0, size.Depth, z => { for (int y = 0; y < size.Height; ++y) { for (int x = 0; x < size.Width; ++x) { var pr = Math.Sqrt((x - r) * (x - r) + (y - r) * (y - r) + (z - r) * (z - r)); var p = new IntVector3(x, y, z); if (pr < r && pr >= ir) { map.SetTileDataNoHeight(p, TileData.GetNaturalWall(MaterialID.Granite)); } else { map.SetTileDataNoHeight(p, TileData.EmptyTileData); } } } }); map.RescanLevelMap(); return(map); }
public void InitializeWorld(World world, IntSize3 size) { CreateTerrain(size); IntVector3? stairs = null; foreach (var p2 in m_terrainData.Size.Plane.Range()) { var p = new IntVector3(p2, m_terrainData.Size.Depth - 1); var td = m_terrainData.GetTileData(p.Down); if (td.ID == TileID.Stairs) { stairs = p; break; } } if (stairs.HasValue == false) throw new Exception(); m_env = EnvironmentObject.Create(world, m_terrainData, VisibilityMode.LivingLOS, stairs.Value); CreateMonsters(); CreateDebugMonsterAtEntry(); }
void DoGrow(IntVector3 p) { int nw, nh, nd; if (p.X < 0 || p.Y < 0 || p.Z < 0) { throw new Exception(); } nw = Align256(Math.Max(this.Size.Width, p.X + 1)); nh = Align256(Math.Max(this.Size.Height, p.Y + 1)); nd = Align16(Math.Max(this.Size.Depth, p.Z + 1)); var newGrid = new TileData[nd, nh, nw]; /* XXX Array.Copy will probably give better speed */ foreach (var l in this.Size.Range()) { var src = m_grid[l.Z, l.Y, l.X]; newGrid[l.Z, l.Y, l.X] = src; } m_grid = newGrid; this.Size = new IntSize3(nw, nh, nd); Debug.Print("GrowingTileGrid.Grow({0})", this.Size); }
void Data_MapChanged(EnvironmentObject oldMap, EnvironmentObject newMap) { if (oldMap != null) { oldMap.MapTileTerrainChanged -= OnTileChanged; } if (newMap != null) { newMap.MapTileTerrainChanged += OnTileChanged; } if (newMap == null) { if (m_chunks != null) { foreach (var chunk in m_chunks) { if (chunk != null) { chunk.Free(); } } } this.Size = new IntSize3(); m_chunks = null; } else { this.Size = newMap.Size / Chunk.CHUNK_SIZE; m_chunks = new Chunk[this.Size.Volume]; } }
public static TerrainData CreateNoiseTerrain(IntSize3 size, Random random) { var terrain = new TerrainData(size); var noise = CreateTerrainNoise(); var noisemap = CreateTerrainNoiseMap(noise, new IntSize2(size.Width, size.Height)); FillFromNoiseMap(terrain, noisemap); terrain.RescanLevelMap(); double xk = (random.NextDouble() * 2 - 1) * 0.01; double yk = (random.NextDouble() * 2 - 1) * 0.01; TerrainHelpers.CreateBaseMinerals(terrain, random, xk, yk); TerrainHelpers.CreateOreVeins(terrain, random, xk, yk); TerrainHelpers.CreateOreClusters(terrain, random); RiverGen.Generate(terrain, random); int soilLimit = size.Depth * 4 / 5; TerrainHelpers.CreateSoil(terrain, soilLimit); int grassLimit = terrain.Depth * 4 / 5; TerrainHelpers.CreateVegetation(terrain, random, grassLimit); return terrain; }
public NavierStokesGrid(IntSize3 size, float cellSize) { Size = size; CellSize = cellSize; spanJ = size.Width; spanK = size.Width * size.Height; Cells = new NavierStokesCell[new IntSize3(size.Width + 1, size.Height + 1, size.Depth + 1).Volume()]; }
public Renderer(IntSize3 size) { m_size = size; m_sliceBmpXY = new WriteableBitmap(size.Width, size.Height, 96, 96, PixelFormats.Bgr32, null); m_sliceBmpXZ = new WriteableBitmap(size.Width, size.Depth, 96, 96, PixelFormats.Bgr32, null); m_sliceBmpYZ = new WriteableBitmap(size.Depth, size.Height, 96, 96, PixelFormats.Bgr32, null); }
public FluidSimulationFrame(IntSize3 leveSetSizeStokesSize, int numParticles, IntSize3 navierStokesSize, float navierStokesCellSize) { LeveSetSizeStokesSize = leveSetSizeStokesSize; Particles = new Vector3[numParticles]; Phi = new double[leveSetSizeStokesSize.Volume()]; ParticleMask = new bool[leveSetSizeStokesSize.Volume()]; NavierStokesGrid = new NavierStokesGrid(navierStokesSize, navierStokesCellSize); }
public void InitializeWorld(IntSize3 size) { CreateTerrain(size); var p = new IntVector2(m_terrainData.Width / 2, m_terrainData.Height / 2); var start = m_terrainData.GetSurfaceLocation(p); m_env = EnvironmentObject.Create(m_world, m_terrainData, VisibilityMode.AllVisible, start); }
public void SetSize(IntSize3 size) { if (!this.Size.IsEmpty) throw new Exception(); this.Size = size; m_grid = new TileData[size.Depth, size.Height, size.Width]; Debug.Print("GrowingTileGrid.SetSize({0})", this.Size); }
public unsafe static TerrainData LoadTerrain(string path, string expectedName, IntSize3 expectedSize) { if (File.Exists(path) == false) { return(null); } using (var stream = File.OpenRead(path)) { TerrainData terrain; using (var br = new BinaryReader(stream, Encoding.Default, true)) { var name = br.ReadString(); if (name != expectedName) { return(null); } int w = br.ReadInt32(); int h = br.ReadInt32(); int d = br.ReadInt32(); var size = new IntSize3(w, h, d); if (size != expectedSize) { return(null); } terrain = new TerrainData(size); } fixed(TileData *v = terrain.m_tileGrid) { byte *p = (byte *)v; int len = terrain.Size.Volume * sizeof(TileData); using (var memStream = new UnmanagedMemoryStream(p, 0, len, FileAccess.Write)) CopyTo(stream, memStream, len); } fixed(byte *p = terrain.m_levelMap) { int len = terrain.Size.Plane.Area * sizeof(byte); using (var memStream = new UnmanagedMemoryStream(p, 0, len, FileAccess.Write)) CopyTo(stream, memStream, len); } return(terrain); } }
public void SetSize(IntSize3 size) { if (!this.Size.IsEmpty) { throw new Exception(); } this.Size = size; m_grid = new TileData[size.Depth, size.Height, size.Width]; Debug.Print("GrowingTileGrid.SetSize({0})", this.Size); }
public static unsafe TerrainData LoadTerrain(string path, string expectedName, IntSize3 expectedSize) { if (File.Exists(path) == false) return null; using (var stream = File.OpenRead(path)) { TerrainData terrain; using (var br = new BinaryReader(stream, Encoding.Default, true)) { var name = br.ReadString(); if (name != expectedName) return null; int w = br.ReadInt32(); int h = br.ReadInt32(); int d = br.ReadInt32(); var size = new IntSize3(w, h, d); if (size != expectedSize) return null; terrain = new TerrainData(size); } fixed (TileData* v = terrain.m_tileGrid) { byte* p = (byte*)v; int len = terrain.Size.Volume * sizeof(TileData); using (var memStream = new UnmanagedMemoryStream(p, 0, len, FileAccess.Write)) CopyTo(stream, memStream, len); } fixed (byte* p = terrain.m_levelMap) { int len = terrain.Size.Plane.Area * sizeof(byte); using (var memStream = new UnmanagedMemoryStream(p, 0, len, FileAccess.Write)) CopyTo(stream, memStream, len); } return terrain; } }
void SendMapTiles(IPlayer player) { var visionTracker = player.GetVisionTracker(this); int w = this.Width; int h = this.Height; int d = this.Depth; var size = new IntSize3(w, h, 1); var arr = new ulong[w * h]; for (int z = 0; z < d; ++z) { var bounds = new IntGrid3(new IntVector3(0, 0, z), size); Parallel.For(0, h, y => { for (int x = 0; x < w; ++x) { var p = new IntVector3(x, y, z); ulong v; if (!visionTracker.Sees(p)) { v = 0; } else { v = GetTileData(p).Raw; } arr[y * w + x] = v; } }); var msg = new Messages.MapDataTerrainsMessage() { Environment = this.ObjectID, Bounds = bounds, TerrainData = arr, }; player.Send(msg); //Trace.TraceError("Sent {0}", z); } }
void CreateTerrain(IntSize3 size) { var random = Helpers.Random; var terrain = new TerrainData(size); var tg = new DungeonTerrainGenerator(terrain, random); tg.Generate(1); TerrainHelpers.CreateSoil(terrain, 9999); TerrainHelpers.CreateVegetation(terrain, random, 9999); m_rooms = tg.Rooms; m_terrainData = terrain; }
void SetWorlMatrix(IntVector3 pos, IntSize3 size, Direction dir) { var worldMatrix = Matrix.Identity; worldMatrix.Transpose(); worldMatrix *= Matrix.Translation(new Vector3(-0.5f)); worldMatrix *= Matrix.RotationQuaternion(s_rotationQuaternions[(int)dir.ToDirectionOrdinal()]); worldMatrix *= Matrix.Scaling(size.Width, size.Height, size.Depth); worldMatrix *= Matrix.Scaling(new Vector3(0.01f) / size.ToIntVector3().ToVector3() + 1); // fix z fight worldMatrix *= Matrix.Translation(new Vector3(0.5f)); worldMatrix *= Matrix.Translation((size.ToIntVector3().ToVector3() - new Vector3(1)) / 2); worldMatrix *= Matrix.Translation(pos.ToVector3()); m_effect.Parameters["worldMatrix"].SetValue(ref worldMatrix); }
public MainWindow() { const int depth = 5; const int sizeExp = 9; int side = (int)Math.Pow(2, sizeExp); m_size = new IntSize3(side, side, depth); m_terrain = new TerrainData(m_size); m_terrainGen = new DungeonTerrainGenerator(m_terrain, new Random(1)); m_renderer = new Renderer(m_size); this.SliceBmpXY = m_renderer.SliceBmpXY; this.SliceBmpXZ = m_renderer.SliceBmpXZ; this.SliceBmpYZ = m_renderer.SliceBmpYZ; InitializeComponent(); }
void CreateTerrain(IntSize3 size) { TerrainData terrain; switch (m_mapMode) { case GameMap.Ball: terrain = ArtificialGen.CreateBallMap(size); break; case GameMap.Cube: terrain = ArtificialGen.CreateCubeMap(size, 2); break; default: throw new NotImplementedException(); } m_terrainData = terrain; }
public static EnvironmentObject InitializeWorld(World world, IntSize3 size) { #if CACHE_TERRAIN var terrain = CreateOrLoadTerrain(size); #else var terrain = CreateTerrain(size); #endif // XXX this is where WorldPopulator creates some buildings var p2 = new IntVector2(terrain.Width / 2, terrain.Height / 2); var startLoc = terrain.GetSurfaceLocation(p2); var env = EnvironmentObject.Create(world, terrain, VisibilityMode.GlobalFOV, startLoc); //CreateWaterTest(env); FortressWorldPopulator.FinalizeEnv(env); return env; }
public static EnvironmentObject InitializeWorld(World world, IntSize3 size) { #if CACHE_TERRAIN var terrain = CreateOrLoadTerrain(size); #else var terrain = CreateTerrain(size); #endif // XXX this is where WorldPopulator creates some buildings var p2 = new IntVector2(terrain.Width / 2, terrain.Height / 2); var startLoc = terrain.GetSurfaceLocation(p2); var env = EnvironmentObject.Create(world, terrain, VisibilityMode.GlobalFOV, startLoc); //CreateWaterTest(env); FortressWorldPopulator.FinalizeEnv(env); return(env); }
public LevelSet(IntSize3 size, float cellSize, INavierStokesGrid grid) { Size = size; CellSize = cellSize; phi = new double[size.Volume()]; backPhi = new double[size.Volume()]; mass = new float[size.Volume()]; backMass = new float[size.Volume()]; states = new NavierStokesCellState[size.Volume()]; particleMass = new float[size.Volume()]; particleMask = new bool[size.Volume()]; for (int j = 0; j < Size.Height - 1; j++) { for (int i = 0; i < Size.Width - 1; i++) { var point = new Vector3(i, j, 0) * CellSize; State(i, j) = grid.StateAtPoint(point); } } }
private void Reset() { simulationRunning = false; simulationTimestamp = 0; prevQueue = new Queue <FluidSimulationFrame>(); var size = new IntSize3(Width, Height, 1); var cellSize = CellSize; fluidSimulation.Reset(CreateConfig()); model = CreateModel(size, cellSize, fluidSimulation.Particles.Length); levelSetImageData = new byte[fluidSimulation.LevelSet.Size.Width * fluidSimulation.LevelSet.Size.Height * 4]; levelSetImage = new RawImage(ResourceVolatility.Volatile, new IntSize2(fluidSimulation.LevelSet.Size.Width, fluidSimulation.LevelSet.Size.Height), true, levelSetImageData); squareModel = embeddedResources.SimplePlaneXyModel(); visualElements.Clear(); visualElements.Add(ModelVisualElement.New() .SetModel(model) .SetMaterial(StandardMaterial.New() .SetDiffuseColor(Color4.Yellow) .SetIgnoreLighting(true) .FromGlobalCache())); visualElements.Add(ModelVisualElement.New() .SetModel(model) .SetModelPartIndex(1) .SetMaterial(StandardMaterial.New() .SetDiffuseColor(Color4.White) .SetIgnoreLighting(true) .FromGlobalCache()) .SetRenderState(StandardRenderState.New() .SetPointSize(3) .FromGlobalCache())); visualElements.Add(ModelVisualElement.New() .SetModel(squareModel) .SetMaterial(StandardMaterial.New() .SetDiffuseMap(levelSetImage) .SetIgnoreLighting(true) .FromGlobalCache()) .SetTransform(new Transform(cellSize * size.Width / 2, Quaternion.Identity, new Vector3(cellSize * size.Width / 2, cellSize * size.Height / 2, -0.1f)))); }
public static TerrainData CreateCubeMap(IntSize3 size, int margin) { var map = new TerrainData(size); Parallel.For(0, size.Depth, z => { for (int y = 0; y < size.Height; ++y) for (int x = 0; x < size.Width; ++x) { var p = new IntVector3(x, y, z); if (x < margin || y < margin || z < margin || x >= size.Width - margin || y >= size.Height - margin || z >= size.Depth - margin) map.SetTileDataNoHeight(p, TileData.EmptyTileData); else map.SetTileDataNoHeight(p, TileData.GetNaturalWall(MaterialID.Granite)); } }); map.RescanLevelMap(); return map; }
static TerrainData CreateTerrain(IntSize3 size) { //var random = Helpers.Random; var random = new Random(1); var terrain = new TerrainData(size); var tg = new TerrainGenerator(terrain, random); var corners = new DiamondSquare.CornerData() { NE = 15, NW = 10, SW = 10, SE = 10, }; tg.Generate(corners, 5, 0.75, 2); int grassLimit = terrain.Depth * 4 / 5; TerrainHelpers.CreateVegetation(terrain, random, grassLimit); return terrain; }
void OnTimerTick(object sender, EventArgs e) { m_timer.IsEnabled = false; if (m_needCreate) { Stopwatch sw = Stopwatch.StartNew(); int depth = this.Depth; int side = this.Side; m_size = new IntSize3(side, side, depth); this.X = side / 2; this.Y = side / 2; this.Z = depth; //m_terrain = new TerrainData(m_size); this.Renderer = new Renderer(m_size); Notify("Renderer"); sw.Stop(); Trace.TraceInformation("Create took {0} ms", sw.ElapsedMilliseconds); levelSlider.Minimum = 0; levelSlider.Maximum = m_size.Depth; this.Z = m_size.Depth; m_needCreate = false; } if (m_needGenerate) { Stopwatch sw = Stopwatch.StartNew(); var random = new Random(1); m_terrain = NoiseTerrainGen.CreateNoiseTerrain(m_size, random); sw.Stop(); Trace.TraceInformation("Generate took {0} ms", sw.ElapsedMilliseconds); m_needGenerate = false; } if (m_needRender) { Stopwatch sw = Stopwatch.StartNew(); this.Renderer.ShowWaterEnabled = this.ShowWaterEnabled; this.Renderer.Render(m_terrain, new IntVector3(this.X, this.Y, this.Z)); sw.Stop(); Trace.TraceInformation("Render took {0} ms", sw.ElapsedMilliseconds); m_needRender = false; } }
public GrowingTileGrid(IntSize3 size) { SetSize(size); }
protected MapChunkTestBase(IntSize3 size) { this.Size = size; //m_dict = new Dictionary<uint, Map1D>(); int cw = size.Width >> CHUNK_SHIFT_X; int ch = size.Height >> CHUNK_SHIFT_Y; int cd = size.Depth >> CHUNK_SHIFT_Z; uint max = 0; m_arr = new Chunk[512]; for (int cz = 0; cz < cd; ++cz) for (int cy = 0; cy < ch; ++cy) for (int cx = 0; cx < cw; ++cx) { uint hash = hashCode(cx, cy, cz); max = Math.Max(max, hash); if (cx % 2 == 0) //if (cz > cd / 2) m_arr[hash] = new Chunk(); } Console.WriteLine("max {0}", max); }
public static bool PickVoxel(EnvironmentObject env, GameSurfaceView view, IntVector2 screenPos, IntGrid3 cropGrid, MapControlPickMode pickMode, out IntVector3 pos, out Direction face) { var camera = view.Camera; var ray = Ray.GetPickRay(screenPos.X, screenPos.Y, view.ViewPort, view.Camera.View * view.Camera.Projection); IntVector3 outpos = new IntVector3(); Direction outdir = Direction.None; var corner = cropGrid.Corner2; var size = new IntSize3(corner.X + 1, corner.Y + 1, corner.Z + 1); IntVector3 prevoutpos = new IntVector3(); Direction prevoutdir = Direction.None; VoxelRayCast.RunRayCast(size, ray.Position, ray.Direction, view.Camera.FarZ, (x, y, z, dir) => { var p = new IntVector3(x, y, z); if (cropGrid.Contains(p) == false) return false; var td = env.GetTileData(p); switch (pickMode) { case MapControlPickMode.Underground: if (!td.IsUndefined && !td.IsWall) return false; outpos = p; outdir = dir; return true; case MapControlPickMode.AboveGround: if (!td.IsUndefined && !td.IsWall) { prevoutpos = p; prevoutdir = dir; return false; } if (prevoutpos.IsNull) { outpos = p; outdir = dir; } else { outpos = prevoutpos; outdir = prevoutdir; } return true; case MapControlPickMode.Constant: if (p.Z > cropGrid.Z2) return false; outpos = p; outdir = dir; return true; default: throw new NotImplementedException(); } }); pos = outpos; face = outdir; return face != Direction.None; }
void DoGrow(IntVector3 p) { int nw, nh, nd; if (p.X < 0 || p.Y < 0 || p.Z < 0) throw new Exception(); nw = Align256(Math.Max(this.Size.Width, p.X + 1)); nh = Align256(Math.Max(this.Size.Height, p.Y + 1)); nd = Align16(Math.Max(this.Size.Depth, p.Z + 1)); var newGrid = new TileData[nd, nh, nw]; /* XXX Array.Copy will probably give better speed */ foreach (var l in this.Size.Range()) { var src = m_grid[l.Z, l.Y, l.X]; newGrid[l.Z, l.Y, l.X] = src; } m_grid = newGrid; this.Size = new IntSize3(nw, nh, nd); Debug.Print("GrowingTileGrid.Grow({0})", this.Size); }
public static bool PickVoxel(EnvironmentObject env, GameSurfaceView view, IntVector2 screenPos, IntGrid3 cropGrid, MapControlPickMode pickMode, out IntVector3 pos, out Direction face) { var camera = view.Camera; var ray = Ray.GetPickRay(screenPos.X, screenPos.Y, view.ViewPort, view.Camera.View * view.Camera.Projection); IntVector3 outpos = new IntVector3(); Direction outdir = Direction.None; var corner = cropGrid.Corner2; var size = new IntSize3(corner.X + 1, corner.Y + 1, corner.Z + 1); IntVector3 prevoutpos = new IntVector3(); Direction prevoutdir = Direction.None; VoxelRayCast.RunRayCast(size, ray.Position, ray.Direction, view.Camera.FarZ, (x, y, z, dir) => { var p = new IntVector3(x, y, z); if (cropGrid.Contains(p) == false) { return(false); } var td = env.GetTileData(p); switch (pickMode) { case MapControlPickMode.Underground: if (!td.IsUndefined && !td.IsWall) { return(false); } outpos = p; outdir = dir; return(true); case MapControlPickMode.AboveGround: if (!td.IsUndefined && !td.IsWall) { prevoutpos = p; prevoutdir = dir; return(false); } if (prevoutpos.IsNull) { outpos = p; outdir = dir; } else { outpos = prevoutpos; outdir = prevoutdir; } return(true); case MapControlPickMode.Constant: if (p.Z > cropGrid.Z2) { return(false); } outpos = p; outdir = dir; return(true); default: throw new NotImplementedException(); } }); pos = outpos; face = outdir; return(face != Direction.None); }
public DungeonTerrainGenerator(TerrainData data, Random random) { m_data = data; m_size = data.Size; m_random = random; }
public Map3D(IntSize3 size) { this.Size = size; this.Grid = new TileData[size.Depth, size.Height, size.Width]; }
void CreateTerrain(IntSize3 size) { var random = new Random(1); m_terrainData = NoiseTerrainGen.CreateNoiseTerrain(size, random); }
protected Map3DTestBase(IntSize3 size) { m_map = new Map3D(size); }
public VoxelMap(IntSize3 size) { this.Size = size; this.Grid = new Voxel[size.Depth, size.Height, size.Width]; }
protected Map1DTestBase(IntSize3 size) { m_map = new Map1D(size); }
void CreateTerrain() { var random = Helpers.Random; int side = MyMath.Pow2(MAP_SIZE); var size = new IntSize3(side, side, MAP_DEPTH); var terrain = new TerrainData(size); var tg = new DungeonTerrainGenerator(terrain, random); tg.Generate(1); TerrainHelpers.CreateSoil(terrain, 9999); TerrainHelpers.CreateGrass(terrain, random, 9999); TerrainHelpers.CreateTrees(terrain, random); m_rooms = tg.Rooms; m_terrainData = terrain; }
public Map1D(IntSize3 size) { this.Size = size; this.Grid = new TileData[size.Depth * size.Height * size.Width]; }
public TerrainGenerator(TerrainData data, Random random) { m_data = data; m_size = data.Size; m_random = random; }
public MapChunkIterateM0Test(IntSize3 size) : base(size) { }
public Map3DIterateM0Test(IntSize3 size) : base(size) { }
public static void RunRayCast(IntSize3 worldSize, Vector3 origin, Vector3 direction, float radius, RayCastDelegate callback) { int wx = worldSize.Width; int wy = worldSize.Height; int wz = worldSize.Depth; // From "A Fast Voxel Traversal Algorithm for Ray Tracing" // by John Amanatides and Andrew Woo, 1987 // <http://www.cse.yorku.ca/~amana/research/grid.pdf> // <http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.42.3443> // Extensions to the described algorithm: // • Imposed a distance limit. // • The face passed through to reach the current cube is provided to // the callback. // The foundation of this algorithm is a parameterized representation of // the provided ray, // origin + t * direction, // except that t is not actually stored; rather, at any given point in the // traversal, we keep track of the *greater* t values which we would have // if we took a step sufficient to cross a cube boundary along that axis // (i.e. change the integer part of the coordinate) in the variables // tMaxX, tMaxY, and tMaxZ. // Cube containing origin point. int x = MyMath.Floor(origin[0]); int y = MyMath.Floor(origin[1]); int z = MyMath.Floor(origin[2]); // Break out direction vector. float dx = direction.X; float dy = direction.Y; float dz = direction.Z; // Direction to increment x,y,z when stepping. int stepX = Math.Sign(dx); int stepY = Math.Sign(dy); int stepZ = Math.Sign(dz); // See description above. The initial values depend on the fractional // part of the origin. float tMaxX = IntBound(origin.X, dx); float tMaxY = IntBound(origin.Y, dy); float tMaxZ = IntBound(origin.Z, dz); // The change in t when taking a step (always positive). float tDeltaX = stepX / dx; float tDeltaY = stepY / dy; float tDeltaZ = stepZ / dz; // Buffer for reporting faces to the callback. Direction face = Direction.None; // Avoids an infinite loop. if (dx == 0 && dy == 0 && dz == 0) throw new Exception("Raycast in zero direction!"); // Rescale from units of 1 cube-edge to units of 'direction' so we can // compare with 't'. radius /= (float)Math.Sqrt(dx * dx + dy * dy + dz * dz); while (/* ray has not gone past bounds of world */ (stepX > 0 ? x < wx : x >= 0) && (stepY > 0 ? y < wy : y >= 0) && (stepZ > 0 ? z < wz : z >= 0)) { // Invoke the callback, unless we are not *yet* within the bounds of the // world. if (!(x < 0 || y < 0 || z < 0 || x >= wx || y >= wy || z >= wz)) { if (callback(x, y, z, face)) break; } // tMaxX stores the t-value at which we cross a cube boundary along the // X axis, and similarly for Y and Z. Therefore, choosing the least tMax // chooses the closest cube boundary. Only the first case of the four // has been commented in detail. if (tMaxX < tMaxY) { if (tMaxX < tMaxZ) { if (tMaxX > radius) break; // Update which cube we are now in. x += stepX; // Adjust tMaxX to the next X-oriented boundary crossing. tMaxX += tDeltaX; // Record the normal vector of the cube face we entered. face = -stepX > 0 ? Direction.East : Direction.West; } else { if (tMaxZ > radius) break; z += stepZ; tMaxZ += tDeltaZ; face = -stepZ > 0 ? Direction.Up : Direction.Down; } } else { if (tMaxY < tMaxZ) { if (tMaxY > radius) break; y += stepY; tMaxY += tDeltaY; face = -stepY > 0 ? Direction.South : Direction.North; } else { // Identical to the second case, repeated for simplicity in // the conditionals. if (tMaxZ > radius) break; z += stepZ; tMaxZ += tDeltaZ; face = -stepZ > 0 ? Direction.Up : Direction.Down; } } } }
public TerrainData(IntSize3 size) { this.Size = size; m_levelMap = new byte[size.Height, size.Width]; m_tileGrid = new TileData[size.Depth, size.Height, size.Width]; }
public Map1DIterateM1Test(IntSize3 size) : base(size) { }