Example #1
0
        public static void ClusterIndexes(OctreeNode[] nodes, int direction, ref int max_surface_index, List<Vertex> collected_vertices)
        {
            if (nodes[0] == null && nodes[1] == null && nodes[2] == null && nodes[3] == null)
                return;

            Vertex[] vertices = new Vertex[4];
            int v_count = 0;
            int node_count = 0;

            for (int i = 0; i < 4; i++)
            {
                if (nodes[i] == null)
                    continue;
                if (nodes[i].size > 1)
                {
                }
                node_count++;
                if (nodes[i].vertices.Length > 1)
                {
                }

                int edge = Utilities.TProcessEdgeMask[direction, i];
                int c1 = Utilities.TEdgePairs[edge, 0];
                int c2 = Utilities.TEdgePairs[edge, 1];

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

                //if (!((m1 == 0 && m2 != 0) || (m1 != 0 && m2 == 0)))
                //	continue;

                //find the vertex index
                int index = 0;
                bool skip = false;
                for (int k = 0; k < 16; k++)
                {
                    int e = Utilities.TransformedEdgesTable[nodes[i].corners, k];
                    if (e == -1)
                    {
                        index++;
                        continue;
                    }
                    if (e == -2)
                    {
                        if (!((m1 == 0 && m2 != 0) || (m1 != 0 && m2 == 0)))
                            skip = true;
                        break;
                    }
                    if (e == edge)
                        break;
                }

                if (!skip && index < nodes[i].vertices.Length)
                {
                    if (nodes[i].index == 30733)
                    {
                    }
                    if (nodes[i].index == 12)
                    {
                    }
                    vertices[i] = nodes[i].vertices[index];
                    while (vertices[i].parent != null)
                        vertices[i] = vertices[i].parent;
                    if (i > v_count)
                    {
                    }
                    v_count++;
                }
            }

            if (v_count == 0)
                return;
            if (node_count != v_count)
            {
            }

            if (!(vertices[0] != vertices[1] && vertices[1] != vertices[2] && vertices[2] != vertices[3]))
            {
                //return;
            }

            int surface_index = -1;

            for (int i = 0; i < 4; i++)
            {
                Vertex v = vertices[i];
                if (v == null)
                    continue;
                //while (v != null)
                //{
                if (v.surface_index != -1)
                {
                    if (surface_index != -1 && surface_index != v.surface_index)
                    {
                        AssignSurface(collected_vertices, v.surface_index, surface_index);
                    }
                    else if (surface_index == -1)
                        surface_index = v.surface_index;
                    //break;
                }

                //break;
                //v = v.parent;
                //}
            }

            if (surface_index == -1)
                surface_index = max_surface_index++;

            for (int i = 0; i < 4; i++)
            {
                Vertex v = vertices[i];
                if (v == null)
                    continue;
                //while (v.parent != null)
                //	v = v.parent;
                //while (v != null)
                //{
                if (v.surface_index == -1)
                {
                    collected_vertices.Add(v);
                }
                v.surface_index = surface_index;
                //v = v.parent;
                //}
            }
        }
Example #2
0
        /*
         * Cell stage
         */
        public void ClusterCell(float error)
        {
            if (type != NodeType.Internal)
                return;

            /*
             * First cluster all the children nodes
             */

            int[] signs = { -1, -1, -1, -1, -1, -1, -1, -1 };
            int mid_sign = -1;

            bool is_collapsible = true;
            for (int i = 0; i < 8; i++)
            {
                if (children[i] == null)
                    continue;

                children[i].ClusterCell(error);
                if (children[i].type == NodeType.Internal) //Can't cluster if the child has children
                    is_collapsible = false;
                else
                {
                    mid_sign = (children[i].corners >> (7 - i)) & 1;
                    signs[i] = (children[i].corners >> i) & 1;
                }
            }

            corners = 0;
            for (int i = 0; i < 8; i++)
            {
                if (signs[i] == -1)
                    corners |= (byte)(mid_sign << i);
                else
                    corners |= (byte)(signs[i] << i);
            }

            //if (!is_collapsible)
            //	return;

            int surface_index = 0;
            List<Vertex> collected_vertices = new List<Vertex>();
            List<Vertex> new_vertices = new List<Vertex>();

            if (index == 31681)
            {
            }
            if (index == 61440)
            {
            }
            if (index == 7715)
            {
            }

            if ((int)position.X == 12 && (int)position.Y == 18 && (int)position.Z == 26)
            {
            }

            /*
             * Find all the surfaces inside the children that cross the 6 Euclidean edges and the vertices that connect to them
             */
            for (int i = 0; i < 12; i++)
            {
                OctreeNode[] face_nodes = new OctreeNode[2];

                int c1 = Utilities.TEdgePairs[i, 0];
                int c2 = Utilities.TEdgePairs[i, 1];

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

                ClusterFace(face_nodes, Utilities.TEdgePairs[i, 2], ref surface_index, collected_vertices);
            }

            for (int i = 0; i < 6; i++)
            {
                OctreeNode[] edge_nodes =
                    {
                        children[Utilities.TCellProcEdgeMask[i, 0]],
                        children[Utilities.TCellProcEdgeMask[i, 1]],
                        children[Utilities.TCellProcEdgeMask[i, 2]],
                        children[Utilities.TCellProcEdgeMask[i, 3]]
                    };
                if (size == 4 && i == 1)
                {
                }
                ClusterEdge(edge_nodes, Utilities.TCellProcEdgeMask[i, 4], ref surface_index, collected_vertices);
            }

            if (size == 16 && position.X == 0 && position.Y == 16 && position.Z == 16)
            {
            }
            if (index == 61440)
            {
            }

            int highest_index = surface_index;

            if (highest_index == -1)
                highest_index = 0;
            /*
             * Gather the stray vertices
             */
            foreach (OctreeNode n in children)
            {
                if (n == null)
                    continue;
                foreach (Vertex v in n.vertices)
                {
                    if (v == null)
                        continue;
                    if (v.surface_index == -1)
                    {
                        v.surface_index = highest_index++;
                        collected_vertices.Add(v);
                    }
                }
            }
            //GatherVertices(this, collected_vertices, ref highest_index);

            //if (surface_index == 0 && highest_index > 1)
            //	return;

            if (highest_index == 7)
            {
            }

            int clustered_count = 0;
            if (collected_vertices.Count > 0)
            {

                for (int i = 0; i <= highest_index; i++)
                {
                    QEFProper.QEFSolver qef = new QEFProper.QEFSolver();
                    Vector3 normal = Vector3.Zero;
                    int count = 0;
                    int[] edges = new int[12];
                    int euler = 0;
                    int e = 0;
                    foreach (Vertex v in collected_vertices)
                    {
                        if (v.surface_index == i)
                        {
                            /*if (!v.qef.hasSolution)
                                v.qef.Solve(1e-6f, 4, 1e-6f);
                            if (v.qef.GetError() > error)
                            {
                                count = 0;
                                break;
                            }*/

                            /* Calculate ei(Sv) */
                            for (int k = 0; k < 3; k++)
                            {
                                int edge = Utilities.TExternalEdges[v.in_cell, k];
                                edges[edge] += v.eis[edge];
                            }
                            /* Calculate e(Svk) */
                            for (int k = 0; k < 9; k++)
                            {
                                int edge = Utilities.TInternalEdges[v.in_cell, k];
                                e += v.eis[edge];
                            }

                            euler += v.euler;
                            qef.Add(ref v.qef.data);
                            normal += v.normal;
                            count++;
                        }
                    }

                    /*
                     * One vertex might have an error greater than the threshold, preventing simplification.
                     * When it's just one, we can ignore the error and proceed.
                     */
                    if (count == 0)
                    {
                        continue;
                    }

                    bool face_prop2 = true;
                    for (int f = 0; f < 6 && face_prop2; f++)
                    {
                        int intersections = 0;
                        for (int ei = 0; ei < 4; ei++)
                        {
                            intersections += edges[Utilities.TFaces[f, ei]];
                        }
                        if (!(intersections == 0 || intersections == 2))
                            face_prop2 = false;
                    }

                    Vertex new_vertex = new Vertex();
                    normal /= (float)count;
                    normal.Normalize();
                    new_vertex.normal = normal;
                    new_vertex.qef = qef;
                    new_vertex.eis = edges;
                    new_vertex.euler = euler - e / 4;
                    if (new_vertex.euler != 1)
                    {
                    }
                    new_vertex.in_cell = this.child_index;
                    new_vertex.face_prop2 = face_prop2;
                    if (face_prop2)
                    {
                    }
                    if (new_vertex.euler != 1)
                    {
                    }
                    new_vertices.Add(new_vertex);
                    //new_vertex.index = rnd.Next();

                    qef.Solve(1e-6f, 4, 1e-6f);
                    float err = qef.GetError();
                    new_vertex.collapsible = err <= error/* && new_vertex.euler == 1 && face_prop2*/;
                    new_vertex.error = err;
                    clustered_count++;

                    if (count > 4)
                    {
                    }

                    foreach (Vertex v in collected_vertices)
                    {
                        if (v.surface_index == i)
                        {
                            Vertex p = v;
                            //p.surface_index = -1;
                            /*while (p.parent != null)
                            {
                                p = p.parent;
                                //p.surface_index = -1;
                                if (p == p.parent)
                                {
                                    p.parent = null;
                                    break;
                                }
                            }*/
                            if (p != new_vertex)
                                p.parent = new_vertex;
                            else
                                p.parent = null;
                        }
                    }
                }
            }
            else
            {
                return;
            }

            if (new_vertices.Count >= collected_vertices.Count)
            {
            }

            //if (clustered_count <= 0)
            {
                foreach (Vertex v2 in collected_vertices)
                {
                    v2.surface_index = -1;
                }
            }

            //this.type = NodeType.Collapsed;
            //for (int i = 0; i < 8; i++)
            //	children[i] = null;
            this.vertices = new_vertices.ToArray();
            if (this.vertices.Length > 4)
            {
            }
        }
Example #3
0
 public Vertex()
 {
     parent = null;
     index = -1;
     collapsible = true;
     qef = null;
     normal = Vector3.Zero;
     surface_index = -1;
     eis = null;
 }