public Window() : base(640, 480, GraphicsMode.Default, "XSharp") { GL.Enable(EnableCap.DepthTest); ISharpShape shape = new Sphere().Subsect(new Vector(0.5, 0.5, 0.5), new Vector(0.5, 0.5, 0.5)); this.Tree = OctoTree.Create(shape, 5); PointCloud.Point[] points = new PointCloud.Point[80000]; for (int t = 0; t < points.Length; t++) { double ang = (double)t / (double)points.Length * Math.PI * 2.0; double elv = (double)Math.Sin(ang * 100.0); double x = (double)Math.Sin(ang); double z = (double)Math.Cos(ang); points[t] = new PointCloud.Point() { Position = new Vector(x, z, elv), A = 255, R = 0, G = 255, B = 0 }; } this.MyPointCloud = new PointCloud(); this.MyPointCloud.Submit(points, 2.0f); }
private OctoTree() { // Self referential for completely full or completely empty this.PPP = this; this.PPN = this; this.PNP = this; this.PNN = this; this.NPP = this; this.NPN = this; this.NNP = this; this.NNN = this; }
static OctoTree() { _Full = new OctoTree(); _Full._Hash = 0xDEADBEEF; _Full._FillLevel = 1.0; _Empty = new OctoTree(); _Empty._Hash = 0x1337BED5; _Empty._FillLevel = 0.0; _Hashes = new Hashtable(); _Hashes.Add(_Full._Hash, _Full); _Hashes.Add(_Empty._Hash, _Empty); _Hashes.Add(_CalcHash(_Full.Children), _Full); _Hashes.Add(_CalcHash(_Empty.Children), _Empty); }
private void _DrawOctoTree(Vector Offset, Vector Scale, OctoTree Tree) { if (Tree == OctoTree.Full) { GL.Color3(Color.FromArgb(192, (int)(Offset.X * 126 + 127), (int)(Offset.Y * 126 + 127), (int)(Offset.Z * 126 + 127))); GL.Vertex3(Offset); } else if (Tree == OctoTree.Empty) { } else { OctoTree[] children = Tree.Children; for (int t = 0; t < 8; t++) { Vector offset = OctoTree.Offset(t); offset.Scale(Scale); _DrawOctoTree(Offset + offset, Scale * 0.5, children[t]); } } }
private OctoTree(OctoTree[] Children) { this.PPP = Children[0]; this.PPN = Children[1]; this.PNP = Children[2]; this.PNN = Children[3]; this.NPP = Children[4]; this.NPN = Children[5]; this.NNP = Children[6]; this.NNN = Children[7]; }
/// <summary> /// Computes the hash for an octotree with the specified children. /// </summary> private static uint _CalcHash(OctoTree[] Children) { uint hash = 0x1234ABCD; for (uint t = 0; t < 8; t++) { hash += Children[t]._Hash; hash += t * 2 + 1; hash = hash << 1; } return hash; }
/// <summary> /// Loads an octrotree from a steam. /// </summary> public static OctoTree Load(Stream Stream) { List<uint> data = new List<uint>(); byte[] buffer = new byte[4]; while (Stream.Read(buffer, 0, 4) == 4) { data.Add(BitConverter.ToUInt32(buffer, 0)); } uint target = 0; List<uint> curgroup = null; LinkedList<uint[]> groups = null; foreach (uint datum in data) { if (groups == null) { groups = new LinkedList<uint[]>(); target = datum; } else { if (curgroup == null) { curgroup = new List<uint>(); curgroup.Add(datum); } else { curgroup.Add(datum); if (curgroup.Count == 8) { groups.AddFirst(curgroup.ToArray()); curgroup = null; } } } } // Try to reach target hash with given information OctoTree targettree; while((targettree = _Hashes[target] as OctoTree) == null) { LinkedListNode<uint[]> grouppointer = groups.First; while(grouppointer != null) { OctoTree[] childrens = new OctoTree[8]; for (int t = 0; t < 8; t++) { if ((childrens[t] = _Hashes[grouppointer.Value[t]] as OctoTree) == null) { childrens = null; break; } } if (childrens != null) { LinkedListNode<uint[]> lgrouppointer = grouppointer; grouppointer = grouppointer.Next; groups.Remove(lgrouppointer); Get(childrens); // get hash for group } if (grouppointer != null) { grouppointer = grouppointer.Next; } } } return targettree; }
/// <summary> /// Gets an octotree with the specified children. /// </summary> public static OctoTree Get(OctoTree[] Children) { uint hash = _CalcHash(Children); object hasheditem = _Hashes[hash]; if (hasheditem == null) { OctoTree newtree = new OctoTree(Children); double filllevel = 0.0; for (int t = 0; t < 8; t++) { filllevel += (Children[t]._FillLevel) / 8.0; } newtree._FillLevel = filllevel; newtree._Hash = hash; _Hashes[hash] = newtree; return newtree; } else { return _Hashes[hash] as OctoTree; } }
/// <summary> /// Creates an octotree representation of a shape with the specified resolution(Tree depth). /// </summary> public static OctoTree Create(ISharpShape Shape, int Resolution) { if (Resolution > 0) { OctoTree[] children = new OctoTree[8]; for (int t = 0; t < 8; t++) { children[t] = Create(Shape.Subsect(Offset(t), new Vector(0.5, 0.5, 0.5)), Resolution - 1); } return Get(children); } else { if (Shape.Occupies(new Vector(0.0, 0.0, 0.0))) { return _Full; } else { return _Empty; } } }