static void TestSchmitzVertexFromHermiteData() { while (true) { HermiteData hermite = new HermiteData(new List <Microsoft.Xna.Framework.Vector3>(), new List <Microsoft.Xna.Framework.Vector3>()); Console.WriteLine("Enter position 1:"); string pos1str = Console.ReadLine(); Console.WriteLine("Enter normal 1:"); string normal1str = Console.ReadLine(); Console.WriteLine("Enter position 2:"); string pos2str = Console.ReadLine(); Console.WriteLine("Enter normal 2:"); string normal2str = Console.ReadLine(); Console.WriteLine("Enter position 3:"); string pos3str = Console.ReadLine(); Console.WriteLine("Enter normal 3:"); string normal3str = Console.ReadLine(); string[] pos1parts = pos1str.Split(','); string[] normal1parts = normal1str.Split(','); string[] pos2parts = pos2str.Split(','); string[] normal2parts = normal2str.Split(','); string[] pos3parts = pos3str.Split(','); string[] normal3parts = normal3str.Split(','); Vector3 pos1 = new Vector3(Single.Parse(pos1parts[0].Trim()), Single.Parse(pos1parts[1].Trim()), Single.Parse(pos1parts[2].Trim())); Vector3 normal1 = new Vector3(Single.Parse(normal1parts[0].Trim()), Single.Parse(normal1parts[1].Trim()), Single.Parse(normal1parts[2].Trim())); Vector3 pos2 = new Vector3(Single.Parse(pos2parts[0].Trim()), Single.Parse(pos2parts[1].Trim()), Single.Parse(pos2parts[2].Trim())); Vector3 normal2 = new Vector3(Single.Parse(normal2parts[0].Trim()), Single.Parse(normal2parts[1].Trim()), Single.Parse(normal2parts[2].Trim())); Vector3 pos3 = new Vector3(Single.Parse(pos3parts[0].Trim()), Single.Parse(pos3parts[1].Trim()), Single.Parse(pos3parts[2].Trim())); Vector3 normal3 = new Vector3(Single.Parse(normal3parts[0].Trim()), Single.Parse(normal3parts[1].Trim()), Single.Parse(normal3parts[2].Trim())); normal1.Normalize(); normal2.Normalize(); normal3.Normalize(); Console.WriteLine("Position 1: {0}", pos1); Console.WriteLine("Normal 1: {0}", normal1); Console.WriteLine("Position 2: {0}", pos2); Console.WriteLine("Normal 2: {0}", normal2); Console.WriteLine("Position 3: {0}", pos3); Console.WriteLine("Normal 3: {0}", normal3); hermite.Add(pos1, normal1); hermite.Add(pos2, normal2); //hermite.Add(pos3, normal3); Stopwatch sw = new Stopwatch(); sw.Start(); Vector3 pos = DualContouring.SchmitzVertexFromHermiteData(hermite, 0.001f, 100); sw.Stop(); Console.WriteLine("Out: {0}", pos); Console.WriteLine("Took {0}ms", sw.ElapsedMilliseconds); } }
private void ProcessBlock(HashSet <Edge> intersectingEdges, List <VertexPositionNormalColorLight> vertices, Dictionary <Vector3I, short> positionToIndex, Chunk c, GridPoint min, Vector3I worldPosition, Vector3I localPosition) { int lX = localPosition.X; int lY = localPosition.Y; int lZ = localPosition.Z; GridPoint XYZ = min; GridPoint XMaxYZ = c.PointAt(lX + 1, lY, lZ); GridPoint XYMaxZ = c.PointAt(lX, lY + 1, lZ); GridPoint XYZMax = c.PointAt(lX, lY, lZ + 1); GridPoint XMaxYMaxZ = c.PointAt(lX + 1, lY + 1, lZ); GridPoint XMaxYZMax = c.PointAt(lX + 1, lY, lZ + 1); GridPoint XYMaxZMax = c.PointAt(lX, lY + 1, lZ + 1); GridPoint XMaxYMaxZMax = c.PointAt(lX + 1, lY + 1, lZ + 1); Tuple <HermiteData, Edge[]> data = CubeInfo(c, localPosition, XYZ, XMaxYZ, XYMaxZ, XYZMax, XMaxYMaxZ, XMaxYZMax, XYMaxZMax, XMaxYMaxZMax); HermiteData hermite = data.Item1; // If there are no intersections, this is an interior point. Therefore, don't build any vertices. if (hermite.IntersectionPoints.Count == 0) { return; } Stopwatch sw = new Stopwatch(); sw.Start(); // investigate possible optimization by using AddRange, since it re-allocates the list only once. List <Edge> edges = new List <Edge>(); for (int i = 0; i < data.Item2.Length; i++) { if (!intersectingEdges.Contains(data.Item2[i])) { edges.Add(data.Item2[i]); } } intersectingEdges.UnionWith(edges); Vector3 minimizingVertex = DualContouring.SchmitzVertexFromHermiteData(hermite, 0.001f, DualContouring.MAX_ITERATIONS); float light = (XYZ.Metadata[0] + XMaxYZ.Metadata[0] + XYMaxZ.Metadata[0] + XYZMax.Metadata[0] + XMaxYMaxZ.Metadata[0] + XMaxYZMax.Metadata[0] + XYMaxZMax.Metadata[0] + XMaxYMaxZMax.Metadata[0]); light /= 8; // average light /= 15; // out of maximum value of 15 vertices.Add(new VertexPositionNormalColorLight(c.Position.ToVector3() + minimizingVertex, Vector3.Zero, Color.Green, light)); positionToIndex.Add(localPosition, (short)(_vertices[c].Count - 1)); //_positionToQEF.Add(localPosition, new CubeInfo(minimizingVertex, data.Item2)); }
private Tuple <HermiteData, Edge[]> CubeInfo(Chunk c, Vector3I min, GridPoint XYZ, GridPoint XMaxYZ, GridPoint XYMaxZ, GridPoint XYZMax, GridPoint XMaxYMaxZ, GridPoint XMaxYZMax, GridPoint XYMaxZMax, GridPoint XMaxYMaxZMax) { HermiteData hermiteData = new HermiteData(new List <Vector3>(), new List <Vector3>()); // get edge table index int cubeIndex = 0; if (XYZ.Density < _minimumSolidDensity) { cubeIndex += 1; } if (XMaxYZ.Density < _minimumSolidDensity) { cubeIndex += 2; } if (XMaxYMaxZ.Density < _minimumSolidDensity) { cubeIndex += 4; } if (XYMaxZ.Density < _minimumSolidDensity) { cubeIndex += 8; } if (XYZMax.Density < _minimumSolidDensity) { cubeIndex += 16; } if (XMaxYZMax.Density < _minimumSolidDensity) { cubeIndex += 32; } if (XMaxYMaxZMax.Density < _minimumSolidDensity) { cubeIndex += 64; } if (XYMaxZMax.Density < _minimumSolidDensity) { cubeIndex += 128; } GridPoint[][][] lookupTable = new GridPoint[][][] { new GridPoint[][] { new GridPoint[] { XYZ, XYZMax, }, new GridPoint[] { XYMaxZ, XYMaxZMax, } }, new GridPoint[][] { new GridPoint[] { XMaxYZ, XMaxYZMax, }, new GridPoint[] { XMaxYMaxZ, XMaxYMaxZMax, } }, }; int edge = _edgeTable[cubeIndex]; List <Edge> xEdges = new List <Edge>(); // loop through all the edges for (int i = 0; i < 12; i++) { // if this edge contains no intersection, skip it if ((edge & (1 << i)) == 0) { continue; } int[] corner1Offset = _intersections[i][0]; int[] corner2Offset = _intersections[i][1]; Vector3I corner1 = min; Vector3I corner2 = min; corner1.X += corner1Offset[0]; corner1.Y += corner1Offset[1]; corner1.Z += corner1Offset[2]; corner2.X += corner2Offset[0]; corner2.Y += corner2Offset[1]; corner2.Z += corner2Offset[2]; GridPoint corner1Point = lookupTable[corner1Offset[0]][corner1Offset[1]][corner1Offset[2]]; GridPoint corner2Point = lookupTable[corner2Offset[0]][corner2Offset[1]][corner2Offset[2]]; Vector3I delta = (corner2 - corner1) * (corner1Point.Density < _minimumSolidDensity ? -1 : 1); // negate if corner1 is less than the isovalue because we assume corner2 at first. Direction dir = GetDirectionFromDelta(delta); xEdges.Add(new Edge(corner1, corner2, dir)); Vector3 intersectionPoint = DualContouring.InterpolateIntersectionPoint(_minimumSolidDensity, corner1.ToVector3(), corner2.ToVector3(), corner1Point.Density, corner2Point.Density); Vector3I minCorner = Vector3I.Min(corner1, corner2); GridPoint minPoint = (minCorner == corner1) ? corner1Point : corner2Point; Vector3 naturalNormal = _densityGradientFunction.df(intersectionPoint.X, intersectionPoint.Y, intersectionPoint.Z); Vector3F8 compressedNaturalNormal = new Vector3F8(naturalNormal); Vector3 normal = compressedNaturalNormal.ToVector3(); //normal = naturalNormal; switch (dir) { case Direction.XIncreasing: case Direction.XDecreasing: normal = minPoint.XPositiveNormal; if (normal == Vector3.Zero) { GridPoint withNormal = new GridPoint(minPoint); withNormal.XPositiveNormal = naturalNormal; c.SetPoint(minCorner.X, minCorner.Y, minCorner.Z, withNormal, true); } break; case Direction.YIncreasing: case Direction.YDecreasing: normal = minPoint.YPositiveNormal; if (normal == Vector3.Zero) { GridPoint withNormal = new GridPoint(minPoint); withNormal.YPositiveNormal = naturalNormal; c.SetPoint(minCorner.X, minCorner.Y, minCorner.Z, withNormal, true); } break; case Direction.ZIncreasing: case Direction.ZDecreasing: normal = minPoint.ZPositiveNormal; if (normal == Vector3.Zero) { GridPoint withNormal = new GridPoint(minPoint); withNormal.ZPositiveNormal = naturalNormal; c.SetPoint(minCorner.X, minCorner.Y, minCorner.Z, withNormal, true); } break; } if (normal == Vector3.Zero) { normal = naturalNormal; } normal.Normalize(); hermiteData.Add(intersectionPoint, normal); } Tuple <HermiteData, Edge[]> ret = new Tuple <HermiteData, Edge[]>(hermiteData, xEdges.ToArray()); return(ret); }