private static Vector3 WorldPosFromVoxelPos(VoxelPos voxelPos) { return(new Vector3 { x = voxelPos.x * VOXEL_WIDTH, y = voxelPos.y * VOXEL_WIDTH, z = voxelPos.z * VOXEL_WIDTH }); }
public SurfaceNetCube[,,] GenerateSurfaceNetCubes(BufferedWorld world, TilePos pos, LevelOfDetail lod) { // var snNets = new SurfaceNetCube[14, 14, 14]; var lodFactor = 16 / lod.Skip; var snNets = new SurfaceNetCube[lodFactor, lodFactor, lodFactor]; var tile = world.GetTileAt(pos); Contracts.Asserts(tile != null); for (var x = tile.StartPos.X; x < tile.EndPos.X; x += lod.Skip) { for (var y = tile.StartPos.Y; y < tile.EndPos.Y; x += lod.Skip) { for (var z = tile.StartPos.Z; z < tile.EndPos.Z; x += lod.Skip) { var sample = new float[8]; var voxelPos = new VoxelPos(x, y, z); for (var i = 0; i < 8; i++) { var offset = SurfaceNetUtil.GetVoxelOffset(i).Multiply(lod.Skip); sample[i] = world.GetVoxelAt(offset.Add(x, y, z)).Density; } var snNet = SurfaceNetUtil.CalculateSurfaceNetCube(sample, world.GetVoxelAt(voxelPos)); snNet.Position = new Vector3(snNet.Position.x + x, snNet.Position.y + y, snNet.Position.z + z); snNets[x / lod.Skip, y / lod.Skip, z / lod.Skip] = snNet; } } } // foreach (var voxelPos in tile) { //// if (voxelPos.X <= 0 || voxelPos.Y <= 0 || voxelPos.Z <= 0) { //// continue; //// } //// //// if (voxelPos.X >= 15 || voxelPos.Y >= 15 || voxelPos.Z >= 15) { //// continue; //// } // // var sample = new float[8]; // // for (var i = 0; i < 8; i++) { // var offset = SurfaceNetUtil.GetVoxelCornerOffset (i); // sample[i] = world.GetVoxelAt (voxelPos.Add ((int) offset.x, (int) offset.y, (int) offset.z)) // .Density; // } // // var snNet = SurfaceNetUtil.CalculateSurfaceNetCube (sample, world.GetVoxelAt (voxelPos)); // snNet.Position = new Vector3 (snNet.Position.x + voxelPos.X, snNet.Position.y + voxelPos.Y, // snNet.Position.z + voxelPos.Z); // snNets[voxelPos.X, voxelPos.Y, voxelPos.Z] = snNet; // } return(snNets); }
public static void SaveLevel(string filepath, Level level) { JsonObject rootObject = new JsonObject(); JsonArray textureArray = new JsonArray(); JsonArray voxelArray = new JsonArray(); List <(VoxelPos, Voxel)> voxelList = level.GetVoxelList(); List <string> textures = new List <string>(); foreach ((VoxelPos, Voxel)pair in voxelList) { VoxelPos pos = pair.Item1; Voxel voxel = pair.Item2; JsonObject voxelObject = new JsonObject(); JsonObject posObject = new JsonObject(); JsonArray faceArray = new JsonArray(); posObject["x"] = pos.x; posObject["y"] = pos.y; posObject["z"] = pos.z; voxelObject["pos"] = posObject; foreach (string face in new string[] { voxel.frontTexture, voxel.backTexture, voxel.leftTexture, voxel.rightTexture, voxel.topTexture, voxel.bottomTexture }) { if (!textures.Contains(face)) { textures.Add(face); } faceArray.Add(new JsonPrimitive(textures.IndexOf(face))); } voxelObject["faces"] = faceArray; voxelArray.Add(voxelObject); } textures.ForEach((texture) => textureArray.Add(new JsonPrimitive(texture))); rootObject.Add("textures", textureArray); rootObject.Add("voxels", voxelArray); Godot.File file = new Godot.File(); file.Open("user://save.json", Godot.File.ModeFlags.Write); file.StoreString(rootObject.ToString()); file.Close(); }
public void AddSingleVoxel(Vector3 worldPos) { VoxelPos newVoxelPos = VoxelPosFromWorldPos(worldPos); Voxel origVoxel; if (_voxelMap.TryGetValue(newVoxelPos, out origVoxel)) { // copy desired settings? for now just ignore } else { Voxel voxel = _voxels[_usedVoxelCount++]; voxel.transform.position = WorldPosFromVoxelPos(newVoxelPos); voxel.transform.parent = _usedVoxelParent.transform; voxel.gameObject.SetActive(true); _voxelMap[newVoxelPos] = voxel; } }
public void GetVertecs(ref VoxelPos p1, ref VoxelPos p2) { p1.X = X0; p1.Y = Y0; p2.X = X1; p2.Y = Y1; }
public static bool EqualIgnoreDir(Edge e0, Edge e1) { VoxelPos v0, v1, v2, v3; v0 = new VoxelPos(); v1 = new VoxelPos(); v2 = new VoxelPos(); v3 = new VoxelPos(); e0.GetVertecs(ref v0, ref v1); e1.GetVertecs(ref v2, ref v3); return (v0 == v2 && v1 == v3) || (v0 == v3 && v1 == v2); }
void __FindAllEdges__(VoxelPos vp, List<Edge> AllEdges, List<VoxelPos> AllVoxel) { int EdgeCount = AllEdges.Count; Edge e0, e1, e2, e3; e0 = new Edge(vp.X, vp.Y, vp.X, vp.Y + 1); e1 = new Edge(vp.X, vp.Y + 1, vp.X + 1, vp.Y + 1); e2 = new Edge(vp.X + 1, vp.Y + 1, vp.X + 1, vp.Y); e3 = new Edge(vp.X + 1, vp.Y, vp.X, vp.Y); if (EdgeCount == 0) { AllEdges.Add(e0); AllEdges.Add(e1); AllEdges.Add(e2); AllEdges.Add(e3); } else { Edge te = null; bool[] be = {false, false, false, false}; for (int i = 0; i < EdgeCount; ++i) { te = AllEdges[i]; if (Edge.EqualIgnoreDir(te, e0)) { AllEdges.RemoveAt(i); EdgeCount--; be[0] = true; } if (Edge.EqualIgnoreDir(te, e1)) { AllEdges.RemoveAt(i); EdgeCount--; be[1] = true; } if (Edge.EqualIgnoreDir(te, e2)) { AllEdges.RemoveAt(i); EdgeCount--; be[2] = true; } if (Edge.EqualIgnoreDir(te, e3)) { AllEdges.RemoveAt(i); EdgeCount--; be[3] = true; } } if (!(be[0] || be[1] || be[2] || be[3])) return; if (!be[0]) AllEdges.Add(e0); if (!be[1]) AllEdges.Add(e1); if (!be[2]) AllEdges.Add(e2); if (!be[3]) AllEdges.Add(e3); } AllVoxel.Remove(vp); int x = vp.X; int y = vp.Y; if (y - 1 >= 0 && AllVoxel.Contains(new VoxelPos(x, y - 1))) __FindAllEdges__(new VoxelPos(x, y - 1), AllEdges, AllVoxel); if (x - 1 >= 0 && AllVoxel.Contains(new VoxelPos(x - 1, y))) __FindAllEdges__(new VoxelPos(x - 1, y), AllEdges, AllVoxel); if (y + 1 < VoxelCount && AllVoxel.Contains(new VoxelPos(x, y + 1))) __FindAllEdges__(new VoxelPos(x, y + 1), AllEdges, AllVoxel); if (x + 1 < VoxelCount && AllVoxel.Contains(new VoxelPos(x + 1, y))) __FindAllEdges__(new VoxelPos(x + 1, y), AllEdges, AllVoxel); }
void __FindAllEdges2Ring__(Edge e, List<Edge> AllEdges, Dictionary<int, int> Degrees, List<VoxelPos> Ring) { VoxelPos v1, v2; v1 = new VoxelPos(); v2 = new VoxelPos(); e.GetVertecs(ref v1, ref v2); int rc = Ring.Count; if (rc == 0) Ring.Add(v1); if (Ring[0] == v2) return; int ldx = e.X1 - e.X0; int ldy = e.Y1 - e.Y0; int ldx0, ldy0; rc = Ring.Count; if (rc > 1) { ldx0 = Ring[rc - 1].X - Ring[rc - 2].X; ldy0 = Ring[rc - 1].Y - Ring[rc - 2].Y; if (ldx0 * ldy + ldx * ldy0 == 0) { Ring.RemoveAt(rc - 1); } } Ring.Add(v2); int ec = AllEdges.Count; VoxelPos sv = new VoxelPos(); ldx = v2.X - v1.X; ldy = v2.Y - v1.Y; int dd = Degrees[v2.X * VoxelCount + v2.Y]; for (int i = 0; i < ec; ++i) { Edge _e = AllEdges[i]; sv.X = _e.X0; sv.Y = _e.Y0; if (sv == v2) { if (dd == 4 && (((_e.X1 - _e.X0 == 0) && (_e.Y1 - _e.Y0) * ldx < 0) || ((_e.Y1 - _e.Y0 == 0) && (_e.X1 - _e.X0) * ldy > 0))) continue; AllEdges.RemoveAt(i); __FindAllEdges2Ring__(_e, AllEdges, Degrees, Ring); break; } } }
public bool IsVoxelLoaded(VoxelPos pos) { return(IsTileLoaded(pos.ToTilePos())); }
public Voxel?GetVoxelAt(VoxelPos pos) { var tilePos = pos.ToTilePos(); return(GetTileAt(tilePos)?.GetVoxelAt(pos)); }