public static VoxLocation?GetLevel(Ray camRay, VoxState state, int h) { camRay.Position -= new Vector3(state.World.worldMin.X * Region.WIDTH, 0, state.World.worldMin.Y * Region.DEPTH); VRay vr = new VRay(camRay.Position, camRay.Direction); Vector3I loc = vr.GetNextLocation(); // Check For World Intersect BoundingBox bb = new BoundingBox(new Vector3(0, h - 1, 0), new Vector3(VoxWorld.WIDTH * Region.WIDTH, h, VoxWorld.DEPTH * Region.DEPTH)); if (!camRay.Intersects(bb).HasValue) { return(null); } // Move In World while (!IsInBounds(loc)) { loc = vr.GetNextLocation(); } // Move Through World while (IsInBounds(loc)) { VoxLocation vl = new VoxLocation(loc); Region region = state.World.regions[vl.RegionIndex]; ushort id = region.voxels[vl.VoxelIndex].ID; if (loc.Y == h) { return(vl); } loc = vr.GetNextLocation(); } return(null); }
private void WriteRegions(string file, int w, int h) { w /= 2; h /= 2; byte[] data = new byte[w * h * 4]; Vector3I loc = Vector3I.Zero; int i = 0, t; for (loc.Z = 0; loc.Z < h * 2; loc.Z += 2) { for (loc.X = 0; loc.X < w * 2; loc.X += 2) { t = 0; loc.Y = LETPaint.HEIGHT; VoxLocation vl = new VoxLocation(loc); Region r = state.World.regions[vl.RegionIndex]; t = r.voxels[vl.VoxelIndex].ID - MINID_REGION; if (t < 0 || t >= REGION_COLORS.Length) { t = 0; } data[i++] = REGION_COLORS[t].B; data[i++] = REGION_COLORS[t].G; data[i++] = REGION_COLORS[t].R; data[i++] = REGION_COLORS[t].A; } } // Save The Image using (var bmp = new System.Drawing.Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) { System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.WriteOnly, bmp.PixelFormat); System.Runtime.InteropServices.Marshal.Copy(data, 0, bmpData.Scan0, data.Length); bmp.UnlockBits(bmpData); bmp.Save(file, System.Drawing.Imaging.ImageFormat.Png); } }
public static VoxLocation? GetOuter(Ray camRay, VoxState state) { camRay.Position -= new Vector3(state.World.worldMin.X * Region.WIDTH, 0, state.World.worldMin.Y * Region.DEPTH); VRay vr = new VRay(camRay.Position, camRay.Direction); Vector3I loc = vr.GetNextLocation(); // Check For World Intersect BoundingBox bb = new BoundingBox(Vector3.Zero, new Vector3(VoxWorld.WIDTH * Region.WIDTH, Region.HEIGHT, VoxWorld.DEPTH * Region.DEPTH)); if(!camRay.Intersects(bb).HasValue) return null; // Move In World while(!IsInBounds(loc)) loc = vr.GetNextLocation(); // Move Through World VoxLocation pvl = new VoxLocation(loc); while(IsInBounds(loc)) { VoxLocation vl = new VoxLocation(loc); Region region = state.World.regions[vl.RegionIndex]; if(region != null) { ushort id = region.voxels[vl.VoxelIndex].ID; if(id != 0) return pvl; } loc = vr.GetNextLocation(); pvl = vl; } return null; }
public override void LESave(VoxWorld world, int w, int h, DirectoryInfo dir) { // Create File FileInfo fi = new FileInfo(dir.FullName + @"\horde.dat"); BinaryWriter s = new BinaryWriter(fi.Create()); // Search Through Columns Vector3I loc = Vector3I.Zero; for (loc.Z = 0; loc.Z < h; loc.Z++) { for (loc.X = 0; loc.X < w; loc.X++) { loc.Y = 0; VoxLocation vl = new VoxLocation(loc); Region r = world.regions[vl.RegionIndex]; // Search Through The Region int team, type; for (; vl.VoxelLoc.Y < Region.HEIGHT; vl.VoxelLoc.Y++) { ushort id = r.voxels[vl.VoxelIndex].ID; if (id < minID || id > maxID) { continue; } // Write Team And Type team = id - minID; type = team & 0x01; team >>= 1; s.Write(team); s.Write(type); s.Write(loc.X); s.Write(loc.Z); break; } } } s.Write(-1); // Flush And Close s.Flush(); s.BaseStream.Dispose(); }
public Point HeightIndex(VoxWorld world, int x, int z, int direction) { Point p = Point.Zero; VoxLocation vl = new VoxLocation(new Vector3I(x, 0, z)); Region r = world.regions[vl.RegionIndex]; x = vl.VoxelLoc.X; z = vl.VoxelLoc.Z; for (int y = Region.HEIGHT - 1; y >= 0; y--) { int i = Region.ToIndex(x, y, z); ushort id = r.voxels[i].ID; if (TryGetFlat(id)) { p.X = y + 1; p.Y = 0; return(p); } else { int ramp; if (TryGetRamp(id, out ramp)) { if (direction == ramp) { p.X = y + 1; p.Y = 0; } else if ((direction ^ 0x01) == ramp) { p.X = y; p.Y = 0; } else { p.X = y; p.Y = ((direction + ramp) & 0x01) == 0 ? 1 : -1; } return(p); } } } return(p); }
public override void LESave(VoxWorld world, int w, int h, DirectoryInfo dir) { // Create File FileInfo fi = new FileInfo(dir.FullName + @"\camera.dat"); BinaryWriter s = new BinaryWriter(fi.Create()); // Search Through Columns Vector3I loc = Vector3I.Zero; for (loc.Z = 0; loc.Z < h; loc.Z++) { for (loc.X = 0; loc.X < w; loc.X++) { loc.Y = 0; VoxLocation vl = new VoxLocation(loc); Region r = world.regions[vl.RegionIndex]; // Search Through The Region for (; vl.VoxelLoc.Y < Region.HEIGHT; vl.VoxelLoc.Y++) { ushort id = r.voxels[vl.VoxelIndex].ID; if (id == camID) { // Write Camera Position s.Write(loc.X); s.Write(vl.VoxelLoc.Y); s.Write(loc.Z); s.Flush(); s.BaseStream.Dispose(); return; } } } } // Flush And Close (No Data) s.Write(w / 2); s.Write((Grey.Vox.Region.HEIGHT * 3) / 4); s.Write(h / 2); s.Flush(); s.BaseStream.Dispose(); }
public static VoxLocation?GetOuter(Ray camRay, VoxState state) { camRay.Position -= new Vector3(state.World.worldMin.X * Region.WIDTH, 0, state.World.worldMin.Y * Region.DEPTH); VRay vr = new VRay(camRay.Position, camRay.Direction); Vector3I loc = vr.GetNextLocation(); // Check For World Intersect BoundingBox bb = new BoundingBox(Vector3.Zero, new Vector3(VoxWorld.WIDTH * Region.WIDTH, Region.HEIGHT, VoxWorld.DEPTH * Region.DEPTH)); if (!camRay.Intersects(bb).HasValue) { return(null); } // Move In World while (!IsInBounds(loc)) { loc = vr.GetNextLocation(); } // Move Through World VoxLocation pvl = new VoxLocation(loc); while (IsInBounds(loc)) { VoxLocation vl = new VoxLocation(loc); Region region = state.World.regions[vl.RegionIndex]; if (region != null) { ushort id = region.voxels[vl.VoxelIndex].ID; if (id != 0) { return(pvl); } } loc = vr.GetNextLocation(); pvl = vl; } return(null); }
public static VoxLocation? GetLevel(Ray camRay, VoxState state, int h) { camRay.Position -= new Vector3(state.World.worldMin.X * Region.WIDTH, 0, state.World.worldMin.Y * Region.DEPTH); VRay vr = new VRay(camRay.Position, camRay.Direction); Vector3I loc = vr.GetNextLocation(); // Check For World Intersect BoundingBox bb = new BoundingBox(new Vector3(0, h - 1, 0), new Vector3(VoxWorld.WIDTH * Region.WIDTH, h, VoxWorld.DEPTH * Region.DEPTH)); if(!camRay.Intersects(bb).HasValue) return null; // Move In World while(!IsInBounds(loc)) loc = vr.GetNextLocation(); // Move Through World while(IsInBounds(loc)) { VoxLocation vl = new VoxLocation(loc); Region region = state.World.regions[vl.RegionIndex]; ushort id = region.voxels[vl.VoxelIndex].ID; if(loc.Y == h) return vl; loc = vr.GetNextLocation(); } return null; }
public static ColumnResult GetColumn(VoxWorld vw, int x, int z, int w, int h, IVoxGridResolver vgr) { VoxLocation vl = new VoxLocation(new Vector3I(x, Region.HEIGHT - 1, z)); ColumnResult cr = new ColumnResult(); ushort id; // Get Height Information cr.Height = new RTSEngine.Data.HeightTile(); Region r = vw.regions[vl.RegionIndex]; int ramp; for (; vl.VoxelLoc.Y > 0; vl.VoxelLoc.Y--) { id = r.voxels[vl.VoxelIndex].ID; if (vgr.TryGetFlat(id)) { cr.Height.XNZN = vl.VoxelLoc.Y + 1; cr.Height.XPZN = vl.VoxelLoc.Y + 1; cr.Height.XNZP = vl.VoxelLoc.Y + 1; cr.Height.XPZP = vl.VoxelLoc.Y + 1; break; } else if (vgr.TryGetRamp(id, out ramp)) { switch (ramp) { case 0: cr.Height.XNZN = vl.VoxelLoc.Y + 1; cr.Height.XPZN = vl.VoxelLoc.Y + 0; cr.Height.XNZP = vl.VoxelLoc.Y + 1; cr.Height.XPZP = vl.VoxelLoc.Y + 0; break; case 1: cr.Height.XNZN = vl.VoxelLoc.Y + 0; cr.Height.XPZN = vl.VoxelLoc.Y + 1; cr.Height.XNZP = vl.VoxelLoc.Y + 0; cr.Height.XPZP = vl.VoxelLoc.Y + 1; break; case 2: cr.Height.XNZN = vl.VoxelLoc.Y + 1; cr.Height.XPZN = vl.VoxelLoc.Y + 1; cr.Height.XNZP = vl.VoxelLoc.Y + 0; cr.Height.XPZP = vl.VoxelLoc.Y + 0; break; case 3: cr.Height.XNZN = vl.VoxelLoc.Y + 0; cr.Height.XPZN = vl.VoxelLoc.Y + 0; cr.Height.XNZP = vl.VoxelLoc.Y + 1; cr.Height.XPZP = vl.VoxelLoc.Y + 1; break; } if (vl.VoxelLoc.Y > 0) { vl.VoxelLoc.Y--; } break; } } // Get Wall Information cr.Walls = 0x00; if (x == 0) { cr.Walls |= CollisionGrid.Direction.XN; } else { Point hi = vgr.HeightIndex(vw, x, z, 0); Point hin = vgr.HeightIndex(vw, x - 1, z, 1); if (hin != hi) { cr.Walls |= CollisionGrid.Direction.XN; } } if (x == w - 1) { cr.Walls |= CollisionGrid.Direction.XP; } else { Point hi = vgr.HeightIndex(vw, x, z, 1); Point hin = vgr.HeightIndex(vw, x + 1, z, 0); if (hin != hi) { cr.Walls |= CollisionGrid.Direction.XP; } } if (z == 0) { cr.Walls |= CollisionGrid.Direction.ZN; } else { Point hi = vgr.HeightIndex(vw, x, z, 2); Point hin = vgr.HeightIndex(vw, x, z - 1, 3); if (hin != hi) { cr.Walls |= CollisionGrid.Direction.ZN; } } if (z == h - 1) { cr.Walls |= CollisionGrid.Direction.ZP; } else { Point hi = vgr.HeightIndex(vw, x, z, 3); Point hin = vgr.HeightIndex(vw, x, z + 1, 2); if (hin != hi) { cr.Walls |= CollisionGrid.Direction.ZP; } } if ((cr.Walls & CollisionGrid.Direction.XN) != 0 && (cr.Walls & CollisionGrid.Direction.ZN) != 0) { cr.Walls |= CollisionGrid.Direction.XNZN; } if ((cr.Walls & CollisionGrid.Direction.XP) != 0 && (cr.Walls & CollisionGrid.Direction.ZN) != 0) { cr.Walls |= CollisionGrid.Direction.XPZN; } if ((cr.Walls & CollisionGrid.Direction.XN) != 0 && (cr.Walls & CollisionGrid.Direction.ZP) != 0) { cr.Walls |= CollisionGrid.Direction.XNZP; } if ((cr.Walls & CollisionGrid.Direction.XP) != 0 && (cr.Walls & CollisionGrid.Direction.ZP) != 0) { cr.Walls |= CollisionGrid.Direction.XPZP; } return(cr); }
public static void ParseVoxels(VoxWorld vw, string file) { // Set Voxel Data byte[] data; using (var s = File.OpenRead(file)) { // Read How Much Data To Allocate var br = new BinaryReader(s); int l = br.ReadInt32(); // Decompress Data data = new byte[l]; var gs = new GZipStream(s, CompressionMode.Decompress); gs.Read(data, 0, data.Length); } // Convert Data int i = 0; int x = BitConverter.ToInt32(data, i); i += 4; int z = BitConverter.ToInt32(data, i); i += 4; Vector3I loc = Vector3I.Zero; Region rN; for (loc.Z = 0; loc.Z < z; loc.Z++) { for (loc.X = 0; loc.X < x; loc.X++) { loc.Y = 0; VoxLocation vl = new VoxLocation(loc); var r = vw.regions[vl.RegionIndex]; if (r == null) { // Check If The Region Needs To Be Loaded r = vw.TryCreateRegion(vl.RegionLoc.X, vl.RegionLoc.Y); int rx = vl.RegionLoc.X; int rz = vl.RegionLoc.Y; if (r == null) { continue; } // Look For Neighbors rN = vw.pager.Obtain(rx - 1, rz); if (rN != null) { r.rNX = rN; rN.rPX = r; } rN = vw.pager.Obtain(rx + 1, rz); if (rN != null) { r.rPX = rN; rN.rNX = r; } rN = vw.pager.Obtain(rx, rz - 1); if (rN != null) { r.rNZ = rN; rN.rPZ = r; } rN = vw.pager.Obtain(rx, rz + 1); if (rN != null) { r.rPZ = rN; rN.rNZ = r; } vw.regions[vl.RegionIndex] = r; } // Read Scenery while (true) { int scen = BitConverter.ToInt32(data, i); i += 4; if (scen == -1) { break; } int ri = BitConverter.ToInt32(data, i); i += 4; int vi = BitConverter.ToInt32(data, i); i += 4; vw.regions[ri].voxels[vi].ID = (ushort)(20 + scen); } int h = BitConverter.ToInt32(data, i); i += 4; int t = BitConverter.ToInt32(data, i); i += 4; switch (t) { case 0: // Terrain int terr = BitConverter.ToInt32(data, i) + 1; i += 4; for (vl.VoxelLoc.Y = 0; vl.VoxelLoc.Y <= h; vl.VoxelLoc.Y++) { r.SetVoxel(vl.VoxelLoc.X, vl.VoxelLoc.Y, vl.VoxelLoc.Z, (ushort)(terr + 10)); } if (h > 0) { r.SetVoxel(vl.VoxelLoc.X, h, vl.VoxelLoc.Z, (ushort)(terr)); } if (h > 1) { r.SetVoxel(vl.VoxelLoc.X, h - 1, vl.VoxelLoc.Z, (ushort)(terr + 5)); } break; case 1: // Ramp int ramp = BitConverter.ToInt32(data, i); i += 4; for (vl.VoxelLoc.Y = 0; vl.VoxelLoc.Y <= h; vl.VoxelLoc.Y++) { r.SetVoxel(vl.VoxelLoc.X, vl.VoxelLoc.Y, vl.VoxelLoc.Z, 11); } if (h > 0) { r.SetVoxel(vl.VoxelLoc.X, h, vl.VoxelLoc.Z, (ushort)(ramp + 16)); } if (h > 1) { r.SetVoxel(vl.VoxelLoc.X, h - 1, vl.VoxelLoc.Z, 6); } break; } r.NotifyFacesChanged(); } } for (int vi = 0; vi < 15; vi++) { var vd = vw.Atlas.Create(); vd.FaceType = new VoxFaceType(); vd.FaceType.SetAllTypes(0x00000001u); vd.FaceType.SetAllMasks(0xfffffffeu); } for (int vi = 0; vi < 4; vi++) { var vd = vw.Atlas.Create(); vd.FaceType = new VoxFaceType(); vd.FaceType.SetAllTypes(0x00000000u); vd.FaceType.Types[Voxel.FACE_PY] = 0xffffffffu; vd.FaceType.SetAllMasks(0xffffffffu); } for (int vi = 0; vi < 5; vi++) { var vd = vw.Atlas.Create(); vd.FaceType = new VoxFaceType(); vd.FaceType.SetAllTypes(0x00000001u); vd.FaceType.SetAllMasks(0xfffffffeu); } for (int vi = 0; vi < 5; vi++) { var vd = vw.Atlas.Create(); vd.FaceType = new VoxFaceType(); vd.FaceType.SetAllTypes(0x00000000u); vd.FaceType.Types[Voxel.FACE_PY] = 0xffffffffu; vd.FaceType.SetAllMasks(0xffffffffu); } }
public override void OnMouseClick(VoxState s, FreeCamera camera, Vector2 mPos, MouseButton button, Viewport vp) { Ray r = camera.GetViewRay(mPos, vp.Width, vp.Height); if(button == MouseButton.Left) { VoxLocation? vl = VRayHelper.GetInner(r, s); if(vl.HasValue) { var loc = vl.Value; if(hasStart) { Vector3I end = new Vector3I( loc.RegionLoc.X * Region.WIDTH + loc.VoxelLoc.X, loc.VoxelLoc.Y, loc.RegionLoc.Y * Region.DEPTH + loc.VoxelLoc.Z ); Vector3I min = new Vector3I(Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), Math.Min(start.Z, end.Z)); Vector3I max = new Vector3I(Math.Max(start.X, end.X), Math.Max(start.Y, end.Y), Math.Max(start.Z, end.Z)); for(int ry = min.Y; ry <= max.Y; ry++) { for(int rz = min.Z; rz <= max.Z; rz++) { for(int rx = min.X; rx <= max.X; rx++) { loc = new VoxLocation(new Vector3I(rx, ry, rz)); s.World.regions[loc.RegionIndex].RemoveVoxel(loc.VoxelLoc.X, loc.VoxelLoc.Y, loc.VoxelLoc.Z); } } } hasStart = false; } else { start = new Vector3I( loc.RegionLoc.X * Region.WIDTH + loc.VoxelLoc.X, loc.VoxelLoc.Y, loc.RegionLoc.Y * Region.DEPTH + loc.VoxelLoc.Z ); hasStart = true; } } } else if(button == MouseButton.Right) { VoxLocation? vl = VRayHelper.GetOuter(r, s); if(vl.HasValue) { var loc = vl.Value; if(hasStart) { Vector3I end = new Vector3I( loc.RegionLoc.X * Region.WIDTH + loc.VoxelLoc.X, loc.VoxelLoc.Y, loc.RegionLoc.Y * Region.DEPTH + loc.VoxelLoc.Z ); Vector3I min = new Vector3I(Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), Math.Min(start.Z, end.Z)); Vector3I max = new Vector3I(Math.Max(start.X, end.X), Math.Max(start.Y, end.Y), Math.Max(start.Z, end.Z)); for(int ry = min.Y; ry <= max.Y; ry++) { for(int rz = min.Z; rz <= max.Z; rz++) { for(int rx = min.X; rx <= max.X; rx++) { loc = new VoxLocation(new Vector3I(rx, ry, rz)); s.World.regions[loc.RegionIndex].AddVoxel(loc.VoxelLoc.X, loc.VoxelLoc.Y, loc.VoxelLoc.Z, CurVoxID); } } } hasStart = false; } else { start = new Vector3I( loc.RegionLoc.X * Region.WIDTH + loc.VoxelLoc.X, loc.VoxelLoc.Y, loc.RegionLoc.Y * Region.DEPTH + loc.VoxelLoc.Z ); hasStart = true; } } } }
private void WriteWorld(string file, int w, int h) { List <byte> data = new List <byte>(w * h * 4 + 8); data.AddRange(BitConverter.GetBytes(w)); data.AddRange(BitConverter.GetBytes(h)); Vector3I loc = Vector3I.Zero; for (loc.Z = 0; loc.Z < h; loc.Z++) { for (loc.X = 0; loc.X < w; loc.X++) { loc.Y = Region.HEIGHT - 1; VoxLocation vl = new VoxLocation(loc); Region r = state.World.regions[vl.RegionIndex]; ushort id = 0; int terr = -1, scen = -1, ramp = -1; // Write Scenery for (; vl.VoxelLoc.Y > 0; vl.VoxelLoc.Y--) { id = r.voxels[vl.VoxelIndex].ID; terr = id - MINID_TERRAIN; scen = id - MINID_SCENERY; ramp = id - MINID_RAMP; if (terr >= 0 && terr < COUNT_TERRAIN) { break; } else if (ramp >= 0 && ramp < COUNT_RAMP) { break; } else if (scen >= 0 && ramp < COUNT_SCENERY) { data.AddRange(BitConverter.GetBytes(scen)); data.AddRange(BitConverter.GetBytes(vl.RegionIndex)); data.AddRange(BitConverter.GetBytes(vl.VoxelIndex)); } } data.AddRange(BitConverter.GetBytes(-1)); // Write Surface data.AddRange(BitConverter.GetBytes(vl.VoxelLoc.Y)); if (terr >= 0 && terr < COUNT_TERRAIN) { data.AddRange(BitConverter.GetBytes(0)); data.AddRange(BitConverter.GetBytes(terr)); } else if (ramp >= 0 && ramp < COUNT_RAMP) { data.AddRange(BitConverter.GetBytes(1)); data.AddRange(BitConverter.GetBytes(ramp)); } else { data.AddRange(BitConverter.GetBytes(-1)); } } } using (MemoryStream ms = new MemoryStream()) { var gs = new GZipStream(ms, CompressionMode.Compress, true); gs.Write(data.ToArray(), 0, data.Count); gs.Close(); ms.Position = 0; using (var s = File.Create(file)) { var bw = new BinaryWriter(s); bw.Write(data.Count); bw.Flush(); ms.CopyTo(s); s.Flush(); } } }
public override void LESave(VoxWorld world, int w, int h, DirectoryInfo dir) { // Create File FileInfo fi = new FileInfo(dir.FullName + @"\horde.dat"); BinaryWriter s = new BinaryWriter(fi.Create()); // Search Through Columns Vector3I loc = Vector3I.Zero; for(loc.Z = 0; loc.Z < h; loc.Z++) { for(loc.X = 0; loc.X < w; loc.X++) { loc.Y = 0; VoxLocation vl = new VoxLocation(loc); Region r = world.regions[vl.RegionIndex]; // Search Through The Region int team, type; for(; vl.VoxelLoc.Y < Region.HEIGHT; vl.VoxelLoc.Y++) { ushort id = r.voxels[vl.VoxelIndex].ID; if(id < minID || id > maxID) continue; // Write Team And Type team = id - minID; type = team & 0x01; team >>= 1; s.Write(team); s.Write(type); s.Write(loc.X); s.Write(loc.Z); break; } } } s.Write(-1); // Flush And Close s.Flush(); s.BaseStream.Dispose(); }