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;
 }
Beispiel #4
0
        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);
                        }
                    }
                }
            }
        }
Beispiel #12
0
 public int Hash(Region r)
 {
     return Hash(r.loc.X, r.loc.Y);
 }
Beispiel #13
0
        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;
        }
Beispiel #14
0
 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;
 }