private static void RecDrawOctree(Octree tree, IOctreeNode iOctreeNode, Vector3 LowerLocalCorner, int current_recursion) { if (iOctreeNode == null) { return; } double boxWidth = Math.Pow(2, -current_recursion); if (iOctreeNode is OctreeEndNode) { OctreeEndNode oen = ((OctreeEndNode)iOctreeNode); SurfaceTangentPoint stp = new SurfaceTangentPoint(); stp.SurfaceNormal = oen.SurfaceNormal; stp.Location = tree.OctreeToWorld(LowerLocalCorner); RenderPoint(stp); } if (iOctreeNode is OctreeParent) { double b = boxWidth / 2; OctreeParent parent = (OctreeParent)iOctreeNode; RecDrawOctree(tree, parent.xyz, LowerLocalCorner + new Vector3(0, 0, 0), current_recursion + 1); RecDrawOctree(tree, parent.xyZ, LowerLocalCorner + new Vector3(0, 0, b), current_recursion + 1); RecDrawOctree(tree, parent.xYz, LowerLocalCorner + new Vector3(0, b, 0), current_recursion + 1); RecDrawOctree(tree, parent.xYZ, LowerLocalCorner + new Vector3(0, b, b), current_recursion + 1); RecDrawOctree(tree, parent.Xyz, LowerLocalCorner + new Vector3(b, 0, 0), current_recursion + 1); RecDrawOctree(tree, parent.XyZ, LowerLocalCorner + new Vector3(b, 0, b), current_recursion + 1); RecDrawOctree(tree, parent.XYz, LowerLocalCorner + new Vector3(b, b, 0), current_recursion + 1); RecDrawOctree(tree, parent.XYZ, LowerLocalCorner + new Vector3(b, b, b), current_recursion + 1); } }
private IOctreeNode BuildOctreeFromFileRecursion(byte[] file, int offset) { const byte ID_LEAF = 0x42; const byte ID_BRANCH = 0x43; if (file[offset] == ID_LEAF) { OctreeEndNode leaf = new OctreeEndNode(); leaf.SurfaceNormal = new Vector3(0, -1, 0); return(leaf); } else if (file[offset] == ID_BRANCH) { OctreeParent branch = new OctreeParent(); if (getIntAt(file, offset + 1 + 4 * 0) > 0) { branch.xyz = BuildOctreeFromFileRecursion(file, getIntAt(file, offset + 1 + 4 * 0)); } if (getIntAt(file, offset + 1 + 4 * 1) > 0) { branch.xyZ = BuildOctreeFromFileRecursion(file, getIntAt(file, offset + 1 + 4 * 1)); } if (getIntAt(file, offset + 1 + 4 * 2) > 0) { branch.xYz = BuildOctreeFromFileRecursion(file, getIntAt(file, offset + 1 + 4 * 2)); } if (getIntAt(file, offset + 1 + 4 * 3) > 0) { branch.xYZ = BuildOctreeFromFileRecursion(file, getIntAt(file, offset + 1 + 4 * 3)); } if (getIntAt(file, offset + 1 + 4 * 4) > 0) { branch.Xyz = BuildOctreeFromFileRecursion(file, getIntAt(file, offset + 1 + 4 * 4)); } if (getIntAt(file, offset + 1 + 4 * 5) > 0) { branch.XyZ = BuildOctreeFromFileRecursion(file, getIntAt(file, offset + 1 + 4 * 5)); } if (getIntAt(file, offset + 1 + 4 * 6) > 0) { branch.XYz = BuildOctreeFromFileRecursion(file, getIntAt(file, offset + 1 + 4 * 6)); } if (getIntAt(file, offset + 1 + 4 * 7) > 0) { branch.XYZ = BuildOctreeFromFileRecursion(file, getIntAt(file, offset + 1 + 4 * 7)); } return(branch); } else { throw new Exception("Broken file"); } }
int WriteToFileRec(List <byte> data, IOctreeNode self_node) { int thisNodeOffset = data.Count; if (self_node is OctreeParent) { OctreeParent op = (OctreeParent)self_node; byte[] block = new byte[8 * 4 + 1]; block[0] = ID_BRANCH; data.AddRange(block); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 0, WriteToFileRec(data, op.xyz)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 1, WriteToFileRec(data, op.xyZ)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 2, WriteToFileRec(data, op.xYz)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 3, WriteToFileRec(data, op.xYZ)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 4, WriteToFileRec(data, op.Xyz)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 5, WriteToFileRec(data, op.XyZ)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 6, WriteToFileRec(data, op.XYz)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 7, WriteToFileRec(data, op.XYZ)); } else if (self_node is OctreeEndNode) { OctreeEndNode oen = (OctreeEndNode)self_node; byte[] block = new byte[7]; block[0] = ID_LEAF; block[1] = 111; // red block[2] = 112; // green block[3] = 113; // blue block[4] = (byte)(oen.SurfaceNormal.X * 126 + 126); block[5] = (byte)(oen.SurfaceNormal.Y * 126 + 126); block[6] = (byte)(oen.SurfaceNormal.Z * 126 + 126); data.AddRange(block); } else if (self_node == null) { return(0); } return(thisNodeOffset); }
private IOctreeNode BuildOctree(List <SurfaceTangentPoint> points, Vector3 LowerLocalCorner, int current_recursion, int max_recursion) { double boxWidth = Math.Pow(2, -current_recursion); List <SurfaceTangentPoint> local_points = new List <SurfaceTangentPoint>(points.Count); foreach (var p in points) { var x = p; if (PointInBox(p.Location, LowerLocalCorner, LowerLocalCorner + new Vector3(boxWidth, boxWidth, boxWidth))) { local_points.Add(x); } } if (local_points.Count == 0) { bytes++; return(null); } if (current_recursion >= max_recursion) { OctreeEndNode node = new OctreeEndNode(); node.SurfaceNormal = local_points[0].SurfaceNormal; bytes += 7; return(node); } bytes += 8 * 4; double b = boxWidth / 2; OctreeParent parent = new OctreeParent(); parent.xyz = BuildOctree(local_points, LowerLocalCorner + new Vector3(0, 0, 0), current_recursion + 1, max_recursion); parent.xyZ = BuildOctree(local_points, LowerLocalCorner + new Vector3(0, 0, b), current_recursion + 1, max_recursion); parent.xYz = BuildOctree(local_points, LowerLocalCorner + new Vector3(0, b, 0), current_recursion + 1, max_recursion); parent.xYZ = BuildOctree(local_points, LowerLocalCorner + new Vector3(0, b, b), current_recursion + 1, max_recursion); parent.Xyz = BuildOctree(local_points, LowerLocalCorner + new Vector3(b, 0, 0), current_recursion + 1, max_recursion); parent.XyZ = BuildOctree(local_points, LowerLocalCorner + new Vector3(b, 0, b), current_recursion + 1, max_recursion); parent.XYz = BuildOctree(local_points, LowerLocalCorner + new Vector3(b, b, 0), current_recursion + 1, max_recursion); parent.XYZ = BuildOctree(local_points, LowerLocalCorner + new Vector3(b, b, b), current_recursion + 1, max_recursion); return(parent); }