Exemple #1
0
        /* Threaded is a very simple way to multithread the node generation
         * Be careful though, as the number of tasks generated is 8^threaded
         * Anything more than 1 generally is slower than 1
         * To be safe, either keep it at 0 or 1
         */
        public bool ConstructNodes(List<VertexPositionColorNormal> vertices, int grid_size, int threaded = 0)
        {
            if (size == 1)
            {
                return ConstructLeaf(vertices, grid_size);
            }

            int child_size = size / 2;
            bool has_children = false;

            Task[] threads = new Task[8];
            bool[] return_values = new bool[8];

            for (int i = 0; i < 8; i++)
            {
                Vector3 offset = new Vector3(i / 4, i % 4 / 2, i % 2);
                OctreeNode child = new OctreeNode();
                child.size = child_size;
                child.position = position + offset * (float)child_size;
                child.type = OctreeNodeType.Internal;

                int index = i;
                if (threaded > 0 && size > 2)
                {
                    threads[index] = Task.Factory.StartNew(
                        () =>
                        {
                            return_values[index] = child.ConstructNodes(vertices, grid_size, threaded - 1);
                            if (return_values[index])
                                children[index] = child;
                            else
                                children[index] = null;
                        }, TaskCreationOptions.AttachedToParent);
                    //threads[index].Start();
                }
                else
                {
                    if (child.ConstructNodes(vertices, grid_size, 0))
                        has_children = true;
                    else
                        child = null;
                    children[i] = child;
                }
            }

            if (threaded > 0 && size > 2)
            {
                for (int i = 0; i < 8; i++)
                {
                    threads[i].Wait();
                    if (return_values[i])
                        has_children = true;
                }
            }

            if (!has_children)
                return false;

            return true;
        }
Exemple #2
0
        public void ProcessCell(List<int> indexes)
        {
            if (type == OctreeNodeType.Internal)
            {
                for (int i = 0; i < 8; i++)
                {
                    if (children[i] != null)
                        children[i].ProcessCell(indexes);
                }

                for (int i = 0; i < 12; i++)
                {
                    OctreeNode[] face_nodes = new OctreeNode[2];

                    int c1 = cellProcFaceMask[i, 0];
                    int c2 = cellProcFaceMask[i, 1];

                    face_nodes[0] = children[c1];
                    face_nodes[1] = children[c2];

                    ProcessFace(face_nodes, cellProcFaceMask[i, 2], indexes);
                }

                for (int i = 0; i < 6; i++)
                {
                    OctreeNode[] edge_nodes =
                    {
                        children[cellProcEdgeMask[i, 0]],
                        children[cellProcEdgeMask[i, 1]],
                        children[cellProcEdgeMask[i, 2]],
                        children[cellProcEdgeMask[i, 3]]
                    };

                    ProcessEdge(edge_nodes, cellProcEdgeMask[i, 4], indexes);
                }
            }
        }
Exemple #3
0
        public static void ProcessIndexes(OctreeNode[] nodes, int direction, List<int> indexes)
        {
            int min_size = 10000000;
            int min_index = 0;
            int[] indices = { -1, -1, -1, -1 };
            bool flip = false;
            bool sign_changed = false;

            for (int i = 0; i < 4; i++)
            {
                int edge = processEdgeMask[direction, i];
                int c1 = edgevmap[edge, 0];
                int c2 = edgevmap[edge, 1];

                int m1 = (nodes[i].draw_info.corners >> c1) & 1;
                int m2 = (nodes[i].draw_info.corners >> c2) & 1;

                if (nodes[i].size < min_size)
                {
                    min_size = nodes[i].size;
                    min_index = i;
                    flip = m1 == 1;
                    sign_changed = ((m1 == 0 && m2 != 0) || (m1 != 0 && m2 == 0));
                }

                indices[i] = nodes[i].draw_info.index;

                //sign_changed = true;
            }

            if (sign_changed)
            {
                if (!flip)
                {
                    if (indices[0] != indices[1] && indices[1] != indices[3])
                    {
                        indexes.Add(indices[0]);
                        indexes.Add(indices[1]);
                        indexes.Add(indices[3]);
                    }

                    if (indices[0] != indices[2] && indices[2] != indices[3])
                    {
                        indexes.Add(indices[0]);
                        indexes.Add(indices[3]);
                        indexes.Add(indices[2]);
                    }
                }
                else
                {
                    if (indices[0] != indices[1] && indices[1] != indices[3])
                    {
                        indexes.Add(indices[0]);
                        indexes.Add(indices[3]);
                        indexes.Add(indices[1]);
                    }

                    if (indices[0] != indices[2] && indices[2] != indices[3])
                    {
                        indexes.Add(indices[0]);
                        indexes.Add(indices[2]);
                        indexes.Add(indices[3]);
                    }
                }
            }
        }
Exemple #4
0
        public static void ProcessFace(OctreeNode[] nodes, int direction, List<int> indexes)
        {
            if (nodes[0] == null || nodes[1] == null)
                return;

            if (nodes[0].type == OctreeNodeType.Internal || nodes[1].type == OctreeNodeType.Internal)
            {
                for (int i = 0; i < 4; i++)
                {
                    OctreeNode[] face_nodes = new OctreeNode[2];

                    for (int j = 0; j < 2; j++)
                    {
                        if (nodes[j].type != OctreeNodeType.Internal)
                            face_nodes[j] = nodes[j];
                        else
                            face_nodes[j] = nodes[j].children[faceProcFaceMask[direction, i, j]];
                    }

                    ProcessFace(face_nodes, faceProcFaceMask[direction, i, 2], indexes);
                }

                int[,] orders =
                {
                    { 0, 0, 1, 1 },
                    { 0, 1, 0, 1 },
                };

                for (int i = 0; i < 4; i++)
                {
                    OctreeNode[] edge_nodes = new OctreeNode[4];

                    for (int j = 0; j < 4; j++)
                    {
                        if (nodes[orders[faceProcEdgeMask[direction, i, 0], j]].type == OctreeNodeType.Leaf || nodes[orders[faceProcEdgeMask[direction, i, 0], j]].type == OctreeNodeType.Pseudo)
                            edge_nodes[j] = nodes[orders[faceProcEdgeMask[direction, i, 0], j]];
                        else
                            edge_nodes[j] = nodes[orders[faceProcEdgeMask[direction, i, 0], j]].children[faceProcEdgeMask[direction, i, 1 + j]];
                    }

                    ProcessEdge(edge_nodes, faceProcEdgeMask[direction, i, 5], indexes);
                }
            }
        }
Exemple #5
0
        public static void ProcessEdge(OctreeNode[] nodes, int direction, List<int> indexes)
        {
            if (nodes[0] == null || nodes[1] == null || nodes[2] == null || nodes[3] == null)
                return;

            if (nodes[0].type != OctreeNodeType.Internal && nodes[1].type != OctreeNodeType.Internal && nodes[2].type != OctreeNodeType.Internal && nodes[3].type != OctreeNodeType.Internal)
            {
                ProcessIndexes(nodes, direction, indexes);
            }
            else
            {
                for (int i = 0; i < 2; i++)
                {
                    OctreeNode[] edge_nodes = new OctreeNode[4];

                    for (int j = 0; j < 4; j++)
                    {
                        if (nodes[j].type == OctreeNodeType.Leaf || nodes[j].type == OctreeNodeType.Pseudo)
                            edge_nodes[j] = nodes[j];
                        else
                            edge_nodes[j] = nodes[j].children[edgeProcEdgeMask[direction, i, j]];
                    }

                    ProcessEdge(edge_nodes, edgeProcEdgeMask[direction, i, 4], indexes);
                }
            }
        }
Exemple #6
0
        public void ConstructTreeGrid(OctreeNode node)
        {
            if (node == null)
                return;
            VertexPositionColor[] vs = new VertexPositionColor[24];
            int x = (int)node.position.X;
            int y = (int)node.position.Y;
            int z = (int)node.position.Z;
            Color c = Color.LightSteelBlue;
            Color v = Color.Red;

            float size = node.size;

            vs[0] = new VertexPositionColor(new Vector3(x + 0 * size, y + 0 * size, z + 0 * size), c);
            vs[1] = new VertexPositionColor(new Vector3(x + 1 * size, y + 0 * size, z + 0 * size), c);
            vs[2] = new VertexPositionColor(new Vector3(x + 1 * size, y + 0 * size, z + 0 * size), c);
            vs[3] = new VertexPositionColor(new Vector3(x + 1 * size, y + 1 * size, z + 0 * size), c);
            vs[4] = new VertexPositionColor(new Vector3(x + 1 * size, y + 1 * size, z + 0 * size), c);
            vs[5] = new VertexPositionColor(new Vector3(x + 0 * size, y + 1 * size, z + 0 * size), c);
            vs[6] = new VertexPositionColor(new Vector3(x + 0 * size, y + 1 * size, z + 0 * size), c);
            vs[7] = new VertexPositionColor(new Vector3(x + 0 * size, y + 0 * size, z + 0 * size), c);

            vs[8] = new VertexPositionColor(new Vector3(x + 0 * size, y + 0 * size, z + 1 * size), c);
            vs[9] = new VertexPositionColor(new Vector3(x + 1 * size, y + 0 * size, z + 1 * size), c);
            vs[10] = new VertexPositionColor(new Vector3(x + 1 * size, y + 0 * size, z + 1 * size), c);
            vs[11] = new VertexPositionColor(new Vector3(x + 1 * size, y + 1 * size, z + 1 * size), c);
            vs[12] = new VertexPositionColor(new Vector3(x + 1 * size, y + 1 * size, z + 1 * size), c);
            vs[13] = new VertexPositionColor(new Vector3(x + 0 * size, y + 1 * size, z + 1 * size), c);
            vs[14] = new VertexPositionColor(new Vector3(x + 0 * size, y + 1 * size, z + 1 * size), c);
            vs[15] = new VertexPositionColor(new Vector3(x + 0 * size, y + 0 * size, z + 1 * size), c);

            vs[16] = new VertexPositionColor(new Vector3(x + 0 * size, y + 0 * size, z + 0 * size), c);
            vs[17] = new VertexPositionColor(new Vector3(x + 0 * size, y + 0 * size, z + 1 * size), c);
            vs[18] = new VertexPositionColor(new Vector3(x + 0 * size, y + 1 * size, z + 0 * size), c);
            vs[19] = new VertexPositionColor(new Vector3(x + 0 * size, y + 1 * size, z + 1 * size), c);

            vs[20] = new VertexPositionColor(new Vector3(x + 1 * size, y + 0 * size, z + 0 * size), c);
            vs[21] = new VertexPositionColor(new Vector3(x + 1 * size, y + 0 * size, z + 1 * size), c);
            vs[22] = new VertexPositionColor(new Vector3(x + 1 * size, y + 1 * size, z + 0 * size), c);
            vs[23] = new VertexPositionColor(new Vector3(x + 1 * size, y + 1 * size, z + 1 * size), c);

            OutlineBuffer.SetData<VertexPositionColor>(OutlineLocation * VertexPositionColor.VertexDeclaration.VertexStride, vs, 0, 24, VertexPositionColor.VertexDeclaration.VertexStride);
            OutlineLocation += 24;

            /*if (node.type != OctreeNodeType.Leaf || node.draw_info.index == -1 || true)
            {
                OutlineBuffer.SetData<VertexPositionColor>(outline_location * VertexPositionColor.VertexDeclaration.VertexStride, vs, 0, 8, VertexPositionColor.VertexDeclaration.VertexStride);
                outline_location += 8;
            }
            else
            {
                x += (int)(node.draw_info.position.X * (float)this.size);
                y += (int)(node.draw_info.position.Y * (float)this.size);
                float r = 2;
                vs[8] = new VertexPositionColor(new Vector3(x - r, y - r, 0), v);
                vs[9] = new VertexPositionColor(new Vector3(x + r, y - r, 0), v);
                vs[10] = new VertexPositionColor(new Vector3(x + r, y - r, 0), v);
                vs[11] = new VertexPositionColor(new Vector3(x + r, y + r, 0), v);
                vs[12] = new VertexPositionColor(new Vector3(x + r, y + r, 0), v);
                vs[13] = new VertexPositionColor(new Vector3(x - r, y + r, 0), v);
                vs[14] = new VertexPositionColor(new Vector3(x - r, y + r, 0), v);
                vs[15] = new VertexPositionColor(new Vector3(x - r, y - r, 0), v);
                OutlineBuffer.SetData<VertexPositionColor>(outline_location * VertexPositionColor.VertexDeclaration.VertexStride, vs, 0, 16, VertexPositionColor.VertexDeclaration.VertexStride);
                outline_location += 16;
            }*/

            if (node.type != OctreeNodeType.Leaf)
            {
                for (int i = 0; i < 8; i++)
                {
                    ConstructTreeGrid(node.children[i]);
                }
            }
        }
Exemple #7
0
        public override long Contour(float threshold)
        {
            Stopwatch watch = new Stopwatch();

            Vertices.Clear();
            tree = new OctreeNode();

            watch.Start();
            tree.Build(Vector3.Zero, Resolution, threshold, Vertices, Size);

            tree.GenerateVertexBuffer(Vertices);
            if (Vertices.Count > 0)
                VertexBuffer.SetData<VertexPositionColorNormal>(Vertices.ToArray());
            VertexCount = Vertices.Count;
            //ConstructTreeGrid(tree);
            CalculateIndexes();
            watch.Stop();

            return watch.ElapsedMilliseconds;
        }