public Model(VertexModel vmodel)// : this(Utilities.Convert(vmodel)) { Tree = construct(vmodel, 0, Vector3.Zero, vmodel.All()); Octree construct(VertexModel vm, int depth, Vector3 pos, List <int> possible) { float scale = (float)Math.Pow(0.5, depth); float[] verts = new float[8]; Vector3 center = pos + Vector3.One * 0.5f * scale; float centerValue = vm.DistanceAt(center, possible); //possible = vm.GetPossible(center, HalfSqrt3 * scale, possible); possible = vm.GetPossiblePrecomp(center, Math.Abs(centerValue) + HalfSqrt3 * scale, possible); for (int i = 0; i < 8; i++) { verts[i] = vm.DistanceAt(pos + SdfMath.split(i).Vector *scale, possible); } Octree build = new Octree(verts); if (Math.Abs(centerValue) < scale * 2 && depth < MaxDepth) // error(centerValue, build.Vertices, pos) > precision { Octree[] children = new Octree[8]; for (int i = 0; i < 8; i++) { children[i] = construct(vm, depth + 1, pos + SdfMath.split(i).Vector *scale / 2, possible); } build.Children = children; } return(build); } }
public static OctData MakeData(string filename) { OctData data; filename = AutocompleteFile(filename); string basename = Path.ChangeExtension(filename, null); FileFormat format = FormatOf(filename); if (format == FileFormat.ASDF) { Trace.WriteLine("Loading from " + filename); } var raw = OctData.NativeOctData.Generate(filename, format); data = new OctData(raw); OctData.NativeOctData.Free(raw); //else // throw new ArgumentException("Invalid " + Path.GetExtension(filename) + "; can only read .obj or .asdf files."); State.buffer_size = (uint)data.Length; return(data); OctData Sample() { var children = new Octree[8]; for (int i = 0; i < 8; i++) { var vals = new float[8]; for (int j = 0; j < 8; j++) { vals[j] = dist(SdfMath.split(j) + SdfMath.split(i)); } children[i] = new Octree(vals); } var mainvals = new float[8]; for (int i = 0; i < 8; i++) { mainvals[i] = dist(SdfMath.split(i) * 2); } var t = new Octree(children, mainvals); return(new Model(t).Cast()); } float dist(Int3 p) => ((p.Vector - Vector3.One).Length() - 0.6f) * 0.5f; }
public Byte8(float[] d, float scale) { S = FromFloat(d[0]); T = FromFloat(d[1]); U = FromFloat(d[2]); V = FromFloat(d[3]); W = FromFloat(d[4]); X = FromFloat(d[5]); Y = FromFloat(d[6]); Z = FromFloat(d[7]); byte FromFloat(float f) { float normd = f / 4 / scale; return((byte)(SdfMath.Saturate(normd + 0.25f) * 255)); } }
private void Cast(List <OctLean> octs, List <Byte8> values, float scale, Vector3 pos, int parent, int at) { int childstart = -1; if (Children != null) { childstart = octs.Count; for (int i = 0; i < 8; i++) { octs.Add(new OctLean()); values.Add(new Byte8()); } for (int i = 0; i < 8; i++) { Children[i].Cast(octs, values, scale / 2, pos + SdfMath.split(i).Vector *scale / 2, at, childstart + i); } } octs[at] = new OctLean(parent, childstart); values[at] = new Byte8(Vertices, scale); }
public static void MakeGUI(int time) { if (!debugWindow) { return; } double milliPerFrame = Math.Round(1000.0 / time); double area = Program.ScreenSize.X * Program.ScreenSize.Y; string nanoPerPixel = (1000000000.0 * SdfMath.Average(frames) / area).ToString("F2"); ImGui.StyleColorsClassic(); if (ImGui.Begin("Debug window ([space] to hide/show)", ImGuiWindowFlags.AlwaysAutoResize)) { ImGui.Text($"{Program.ScreenSize.X} x {Program.ScreenSize.Y} px"); ImGui.SameLine(); if (Program.ScreenSize != new Vector2(720, 720)) { if (ImGui.Button("Reset")) { Program.window.WindowState = WindowState.Normal; Program.ScreenSize = new Vector2(720, 720); Program.window.WindowState = WindowState.Normal; } if (Program.window.WindowState != WindowState.BorderlessFullScreen) { ImGui.SameLine(); } } if (Program.window.WindowState != WindowState.BorderlessFullScreen) { if (ImGui.Button("Fullscreen [F11]")) { Program.window.WindowState = WindowState.BorderlessFullScreen; } } ImGui.Text($"Y-Rotation {Look.Y.ToString().PadLeft(6)}, X-Rotation {Look.X.ToString()}"); ImGui.SliderFloat("Light X", ref State.light.X, -1, 2); ImGui.SliderFloat("Light Y", ref State.light.Y, -1, 2); ImGui.SliderFloat("Light Z", ref State.light.Z, -1, 2); ImGui.SliderFloat("Light Intensity", ref State.strength, 0, 1f); ImGui.SliderFloat("FOV", ref State.fov, 0.05f, 1.5f); ImGui.SliderFloat("Movement speed", ref mSpeed, 0.05f, 1f); bool submitted = ImGui.InputText("Load File", ref loadPath, 128, ImGuiInputTextFlags.EnterReturnsTrue); string complete = AutocompleteFile(loadPath.Replace('/', '\\')); if (complete != null) { string buttonText = "Load"; if (MustImport(FormatOf(complete))) { ImGui.InputInt("Resolution Level", ref Model.MaxDepth); buttonText = "Import"; } if (submitted || ImGui.Button(buttonText)) { Program.Load(loadPath); } } ImGui.Checkbox("Show Debug Gizmos", ref debugGizmos); if (debugGizmos) { ImGui.PlotLines("", ref frames[0], frames.Length, 0, $"{time} FPS - {nanoPerPixel} nspp", 0, 0.1f, new Vector2(200, 40)); ImGui.DragInt("averaging time", ref desiredFrameCount, 1, 1, 96); if (ImGui.Button("Reload shader")) { Program.ReloadShader(); } if (Program.DebugMode) { console.Render(); } } else { ImGui.Text($"{time} FPS - {milliPerFrame} mspf - {nanoPerPixel} nspp"); } } }