public static HermiteDataGrid LoadFromFile(FileInfo fi) { var ret = new HermiteDataGrid(); ret.Load(fi); return(ret); }
/// <summary> /// /// </summary> /// <param name="gridWorldSize">Size of the grid in world space</param> /// <param name="resolution">Aka the subdivision of the grid</param> /// <param name="world">Worldmatrix of the object</param> /// <param name="obj"></param> /// <returns></returns> public static HermiteDataGrid FromIntersectableGeometry(float gridWorldSize, int resolution, Matrix world, IIntersectableObject obj) { var numCubes = new Point3(resolution, resolution, resolution); var grid = new HermiteDataGrid(); var gridToWorld = Matrix.Scaling(1f / resolution, 1f / resolution, 1f / resolution) * Matrix.Scaling(new Vector3(gridWorldSize)); var gridToGeometry = gridToWorld * Matrix.Invert(world); var geometryToGrid = Matrix.Invert(gridToGeometry); // Fill vertices grid.cells = new Array3D <Vertex>(numCubes + new Point3(1, 1, 1)); grid.ForEachGridPoint(cube => { grid.cells[cube] = new Vertex() { Sign = obj.IsInside(Vector3.TransformCoordinate(cube.ToVector3(), gridToGeometry)), EdgeData = new Vector4[3] }; }); // Find changing edges and calculate edge info grid.ForEachGridPoint(cube => { var sign = grid.GetSign(cube); for (int i = 0; i < grid.dirs.Length; i++) { Point3 start = cube; Point3 end = cube + grid.dirs[i]; if (sign == grid.GetSign(end)) { continue; } //sign difference Vector3 startT = Vector3.TransformCoordinate(start, gridToGeometry); Vector3 endT = Vector3.TransformCoordinate(end, gridToGeometry); var vector4 = obj.GetIntersection(startT, endT); var intersectionPoint = Vector3.TransformCoordinate(Vector3.Lerp(startT, endT, vector4.W), geometryToGrid); var realLerp = Vector3.Distance(start, intersectionPoint); // /1 Debug.Assert(Math.Abs(Vector3.Distance(start, end) - 1) < 0.001); // Algo check vector4 = new Vector4(Vector3.Normalize(Vector3.TransformNormal(vector4.TakeXYZ(), geometryToGrid)), realLerp); grid.cells[cube].EdgeData[i] = vector4; } }); return(grid); }
public static AbstractHermiteGrid Empty(Point3 dimensions) { var ret = new HermiteDataGrid(); Point3 storageSize = dimensions + new Point3(1, 1, 1); ret.cells = new Array3D <Vertex>(storageSize); for (int x = 0; x < storageSize.X; x++) { for (int y = 0; y < storageSize.Y; y++) { for (int z = 0; z < storageSize.Z; z++) { var p = new Point3(x, y, z); ret.cells[p] = new Vertex() { Sign = false, EdgeData = new Vector4[3] }; } } } return(ret); }
/// <summary> /// Returns a hermite grid of size+1 with a sphere of 'size' voxels centered in the middle /// </summary> public HermiteDataGrid CreateSphere(int size) { return(HermiteDataGrid.FromIntersectableGeometry(size + 1, size + 1, Matrix.Scaling(new Vector3(0.5f * size)) * Matrix.Translation(new Vector3(0.5f + size / 2f)), new IntersectableSphere())); }
public static HermiteDataGrid CopyGrid(AbstractHermiteGrid grid) { var ret = new HermiteDataGrid(); Point3 storageSize = grid.Dimensions + new Point3(1, 1, 1); ret.cells = new Array3D <Vertex>(storageSize); for (int x = 0; x < storageSize.X; x++) { for (int y = 0; y < storageSize.Y; y++) { for (int z = 0; z < storageSize.Z; z++) { var p = new Point3(x, y, z); ret.cells[p] = new Vertex() { Sign = grid.GetSign(p), Material = grid.GetMaterial(p) /*EdgeData = ret.dirs.Select(dir => * { * var edgeId = grid.GetEdgeId(p, p + dir); * return grid.HasEdgeData(p, edgeId) ? grid.getEdgeData(p, edgeId) : new Vector4(); * }).ToArray()*/ }; } } } //ret.ForEachGridPoint(p => // { // ret.cells[p] = new Vertex() // { // Sign = grid.GetSign(p), // /*EdgeData = ret.dirs.Select(dir => // { // var edgeId = grid.GetEdgeId(p, p + dir); // return grid.HasEdgeData(p, edgeId) ? grid.getEdgeData(p, edgeId) : new Vector4(); // }).ToArray()*/ // }; // }); var dirs = ret.dirs; var dirEdges = dirs.Select(i => ret.GetEdgeId(new Point3(), i)).ToArray(); ret.ForEachGridPoint(p => { var gridPointP = ret.cells.GetFast(p.X, p.Y, p.Z); gridPointP.EdgeData = new Vector4[3]; for (int i = 0; i < 3; i++) { var dir = dirs[i]; var edgeId = dirEdges[i]; Point3 endPoint = p + dir; // Optimization: direclty read from already constructed data if (!ret.cells.InArray(endPoint)) { continue; } if (gridPointP.Sign == ret.cells.GetFast(endPoint.X, endPoint.Y, endPoint.Z).Sign) { continue; } if (!grid.HasEdgeData(p, edgeId)) { // This can normally not happen, since we check if there is a sign difference by looking at the already evaluated density points. // If this would be true there is some problem with the manual determining of the existence of an edge. //throw new InvalidOperationException(); continue; } gridPointP.EdgeData[i] = grid.getEdgeData(p, edgeId); } /*val.EdgeData = ret.dirs.Select( dir => * { * * } ).ToArray();*/ ret.cells[p] = gridPointP; }); return(ret); }
public HermiteDataGrid createCubeGrid() { return(HermiteDataGrid.FromIntersectableGeometry(gridWorldSize, subdivision, Matrix.Scaling(new Vector3(4)) * Matrix.Translation(5, 5, 5), new IntersectableCube())); }