public static List<MeshedFace> Mesh(Region region) { var res = new List<MeshedFace>(); MeshY(region, res); MeshX(region, res); MeshZ(region, res); return res; }
public void Remove(Region r) { int h = Hash(r); var rl = rLists[h]; if(rl != null) { rl.Remove(r); if(rl.Count < 1) rLists[h] = null; } }
public bool TryAdd(Region r) { int h = Hash(r); List<Region> rl; bool b = true; if(rLists[h] == null) { rl = new List<Region>(INITIAL_CAPACITY); rLists[h] = rl; } rl = rLists[h]; for(int i = 0; i < rl.Count; i++) { if(rl[i].loc == r.loc) b = false; } if(b) rl.Add(r); return b; }
public Region(VoxWorld w) { World = w; loc = Point.Zero; // Create Empty Region voxels = new Voxel[VOXEL_COUNT]; for(int i = 0; i < VOXEL_COUNT; i++) voxels[i] = Voxel.Empty; // Non-calculated Boundaries rBS = new RegionBoundaryState[4]; for(int i = 0; i < 4; i++) rBS[i] = new RegionBoundaryState(); // No Neighbors rNX = rPX = rNZ = rPZ = null; }
public RegionLoader(Region r) { region = r; }
public RegionTesselator(Region r, VoxelRenderer vg) { region = r; renderer = vg; }
void OnRegionRemoval(VoxWorld w, Region r) { lock(activeRegions) { activeRegions.Remove(r); } }
void OnRegionAddition(VoxWorld w, Region r) { lock(activeRegions) { activeRegions.Add(r); } }
private static ushort VoxelID(Region region, int x, int y, int z) { return region.voxels[Region.ToIndex(x, y, z)].ID; }
private static void MeshX(Region region, List<MeshedFace> res) { // Find Neighbor Regions Region rNeg = region.rNX; Region rPos = region.rPX; // Loop Through All Planes Vector3I pos = Vector3I.Zero; for(pos.X = 0; pos.X <= Region.WIDTH; pos.X++) { int[] mask = new int[Region.HEIGHT * Region.DEPTH]; int mi = 0; // Create Mask int nID, pID; for(pos.Y = 0; pos.Y < Region.HEIGHT; pos.Y++) { for(pos.Z = 0; pos.Z < Region.DEPTH; pos.Z++) { // Get Negative Voxel if(pos.X > 0) nID = VoxelID(region, pos.X - 1, pos.Y, pos.Z); else if(rNeg != null) nID = VoxelID(rNeg, Region.WIDTH - 1, pos.Y, pos.Z); else nID = 0; // VoxelID(region, pos.X, pos.Y, pos.Z); // Get Positive Voxel if(pos.X < Region.WIDTH) pID = VoxelID(region, pos.X, pos.Y, pos.Z); else if(rPos != null) pID = VoxelID(rPos, 0, pos.Y, pos.Z); else pID = 0; // VoxelID(region, pos.X - 1, pos.Y, pos.Z); ; // Create Mask VoxData nVD = region.World.Atlas[(ushort)nID]; VoxData pVD = region.World.Atlas[(ushort)pID]; if(nID == pID || (!nVD.FaceType.CanShowFace(pVD.FaceType, Voxel.FACE_PX) && !pVD.FaceType.CanShowFace(nVD.FaceType, Voxel.FACE_NX))) mask[mi] = 0; else if(nID != 0) mask[mi] = nID; else mask[mi] = -pID; mi++; } } // Generate Rectangles mi = 0; for(pos.Y = 0; pos.Y < Region.HEIGHT; pos.Y++) { for(pos.Z = 0; pos.Z < Region.DEPTH; pos.Z++, mi++) { int id = mask[mi]; if(id != 0) { int su = pos.Z; int w = 1; pos.Z++; mi++; while(pos.Z < Region.DEPTH && mask[mi] == id) { w++; pos.Z++; mi++; } pos.Z--; mi--; MeshedFace mf; if(id < 0) { mf = new MeshedFace( new Vector3I(pos.X, pos.Y + 1, su), new Vector3I(0, 0, 1), new Vector3I(0, -1, 0), new Point(w, 1), -id, Voxel.FACE_NX ); } else { mf = new MeshedFace( new Vector3I(pos.X, pos.Y + 1, pos.Z + 1), new Vector3I(0, 0, -1), new Vector3I(0, -1, 0), new Point(w, 1), id, Voxel.FACE_PX ); } res.Add(mf); } } } } }
private static void MeshY(Region region, List<MeshedFace> res) { // Loop Through All Planes Vector3I pos = Vector3I.Zero; for(pos.Y = 0; pos.Y <= Region.HEIGHT; pos.Y++) { int[] mask = new int[Region.WIDTH * Region.DEPTH]; int mi = 0; // Create Mask int nID, pID; for(pos.Z = 0; pos.Z < Region.DEPTH; pos.Z++) { for(pos.X = 0; pos.X < Region.WIDTH; pos.X++) { // Get Negative Voxel if(pos.Y > 0) nID = VoxelID(region, pos.X, pos.Y - 1, pos.Z); else nID = VoxelID(region, pos.X, pos.Y, pos.Z); // Get Positive Voxel if(pos.Y < Region.HEIGHT) pID = VoxelID(region, pos.X, pos.Y, pos.Z); else pID = VoxelID(region, pos.X, pos.Y - 1, pos.Z); // Create Mask VoxData nVD = region.World.Atlas[(ushort)nID]; VoxData pVD = region.World.Atlas[(ushort)pID]; if(nID == pID || (!nVD.FaceType.CanShowFace(pVD.FaceType, Voxel.FACE_PY) && !pVD.FaceType.CanShowFace(nVD.FaceType, Voxel.FACE_NY))) mask[mi] = 0; else if(nID != 0) mask[mi] = nID; else mask[mi] = -pID; mi++; } } // Generate Rectangles mi = 0; for(int v = 0; v < Region.DEPTH; v++) { for(int u = 0; u < Region.WIDTH; u++, mi++) { int id = mask[mi]; if(id != 0) { int su = u; int w = 1; u++; mi++; while(u < Region.WIDTH && mask[mi] == id) { w++; u++; mi++; } u--; mi--; MeshedFace mf; if(id < 0) { mf = new MeshedFace( new Vector3I(su, pos.Y, v + 1), new Vector3I(1, 0, 0), new Vector3I(0, 0, -1), new Point(w, 1), -id, Voxel.FACE_NY ); } else { mf = new MeshedFace( new Vector3I(su, pos.Y, v), new Vector3I(1, 0, 0), new Vector3I(0, 0, 1), new Point(w, 1), id, Voxel.FACE_PY ); } res.Add(mf); } } } } }
public int Hash(Region r) { return Hash(r.loc.X, r.loc.Y); }
public bool PlaceRegion(Region region) { int x, z; if(!IsInArray(region.loc.X, region.loc.Y, out x, out z)) { // TODO: Send To Unloader return false; } int i = ToIndex(x, z); // Check Old Region if(regions[i] != null) { regions[i] = null; if(OnRegionDeletion != null) OnRegionDeletion(this, regions[i]); } // Add To Array regions[i] = region; if(OnRegionAddition != null) OnRegionAddition(this, region); return true; }
public Region TryCreateRegion(int x, int z) { Region r = new Region(this); r.loc = new Point(x, z); if(pager.TryAdd(r)) return r; else return null; }