Example #1
0
        public void Simplify(float threshold, bool randomize = false)
        {
            if (type != OctreeNodeType.Internal)
            {
                return;
            }

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

            //QEF3D qef = new QEF3D();
            QEFProper.QEFSolver qef = new QEFProper.QEFSolver();
            Random rnd = new Random();

            float t = threshold;

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

                if (randomize)
                {
                    t = (float)rnd.NextDouble() * (float)rnd.NextDouble() * 20.0f;
                }
                children[i].Simplify(t);
                OctreeNode child = children[i];

                if (child.type == OctreeNodeType.Internal)
                {
                    is_collapsible = false;
                }
                else
                {
                    //qef.Add(child.draw_info.position, child.draw_info.averageNormal);
                    //if (child.draw_info.qef != null)
                    qef.Add(ref child.draw_info.qef.data);

                    mid_sign = (child.draw_info.corners >> (7 - i)) & 1;
                    signs[i] = (child.draw_info.corners >> i) & 1;
                }
            }

            if (size == 16)
            {
            }

            if (!is_collapsible)
            {
                return;
            }

            //Vector3 pos = qef.Solve2(0, 0, 0);
            Vector3 pos   = qef.Solve(1e-6f, 4, 1e-6f);
            float   error = qef.GetError();

            if (error > threshold)
            {
                return;
            }

            OctreeDrawInfo draw_info = new OctreeDrawInfo();

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

            Vector3 normal = new Vector3();

            for (int i = 0; i < 8; i++)
            {
                if (children[i] != null)
                {
                    OctreeNode child = children[i];
                    if (child.type == OctreeNodeType.Pseudo || child.type == OctreeNodeType.Leaf)
                    {
                        normal += child.draw_info.averageNormal;
                    }
                }
            }

            normal.Normalize();
            draw_info.averageNormal = normal;
            draw_info.position      = pos;
            draw_info.qef           = qef;

            for (int i = 0; i < 8; i++)
            {
                children[i] = null;
            }

            type           = OctreeNodeType.Pseudo;
            this.draw_info = draw_info;
        }
Example #2
0
        /* The following code is more or less a copy/paste cleanup of the C++ implementation
         * It's not clean, or efficient, but it works and is fairly straightforward
         */
        public bool ConstructLeaf(List <VertexPositionColorNormal> vertices, int grid_size)
        {
            if (size != 1)
            {
                return(false);
            }
            int corners = 0;

            float[, ,] samples = new float[2, 2, 2];
            for (int i = 0; i < 8; i++)
            {
                if ((samples[i / 4, i % 4 / 2, i % 2] = Sampler.Sample(position + new Vector3(i / 4, i % 4 / 2, i % 2))) < 0)
                {
                    corners |= 1 << i;
                }
            }

            if (corners == 0 || corners == 255)
            {
                return(false);
            }

            //type = OctreeNodeType.Leaf;
            //return true;

            QEF3D qef = new QEF3D();

            QEFProper.QEFSolver qefp           = new QEFProper.QEFSolver();
            Vector3             average_normal = Vector3.Zero;

            for (int i = 0; i < 12; i++)
            {
                int c1 = edgevmap[i, 0];
                int c2 = edgevmap[i, 1];

                int m1 = (corners >> c1) & 1;
                int m2 = (corners >> c2) & 1;
                if (m1 == m2)
                {
                    continue;
                }

                float d1 = samples[c1 / 4, c1 % 4 / 2, c1 % 2];
                float d2 = samples[c2 / 4, c2 % 4 / 2, c2 % 2];

                Vector3 p1 = new Vector3((float)((c1 / 4)), (float)((c1 % 4 / 2)), (float)((c1 % 2)));
                Vector3 p2 = new Vector3((float)((c2 / 4)), (float)((c2 % 4 / 2)), (float)((c2 % 2)));

                Vector3 intersection = Sampler.GetIntersection(p1, p2, d1, d2) + position;
                Vector3 normal       = Sampler.GetNormal(intersection);          //GetNormal(x, y);
                average_normal += normal;

                qef.Add(intersection, normal);
                qefp.Add(intersection, normal);
            }

            Vector3 n = average_normal / (float)qef.Intersections.Count;

            n.Normalize();
            draw_info = new OctreeDrawInfo();
            //draw_info.position = position + qef.Solve2(0, 0, 0);
            draw_info.position      = qefp.Solve(1e-6f, 4, 1e-6f);
            draw_info.corners       = corners;
            draw_info.averageNormal = n;
            draw_info.qef           = qefp;
            //vertices.Add(new VertexPositionColorNormal(position + draw_info.position, Color.LightGreen, n));

            type = OctreeNodeType.Leaf;
            return(true);
        }
Example #3
0
        /* The following code is more or less a copy/paste cleanup of the C++ implementation
         * It's not clean, or efficient, but it works and is fairly straightforward
         */
        public bool ConstructLeaf(List<VertexPositionColorNormal> vertices, int grid_size)
        {
            if (size != 1)
                return false;
            int corners = 0;
            float[, ,] samples = new float[2, 2, 2];
            for (int i = 0; i < 8; i++)
            {
                if ((samples[i / 4, i % 4 / 2, i % 2] = Sampler.Sample(position + new Vector3(i / 4, i % 4 / 2, i % 2))) < 0)
                    corners |= 1 << i;
            }

            if (corners == 0 || corners == 255)
                return false;

            //type = OctreeNodeType.Leaf;
            //return true;

            QEF3D qef = new QEF3D();
            QEFProper.QEFSolver qefp = new QEFProper.QEFSolver();
            Vector3 average_normal = Vector3.Zero;
            for (int i = 0; i < 12; i++)
            {
                int c1 = edgevmap[i, 0];
                int c2 = edgevmap[i, 1];

                int m1 = (corners >> c1) & 1;
                int m2 = (corners >> c2) & 1;
                if (m1 == m2)
                    continue;

                float d1 = samples[c1 / 4, c1 % 4 / 2, c1 % 2];
                float d2 = samples[c2 / 4, c2 % 4 / 2, c2 % 2];

                Vector3 p1 = new Vector3((float)((c1 / 4)), (float)((c1 % 4 / 2)), (float)((c1 % 2)));
                Vector3 p2 = new Vector3((float)((c2 / 4)), (float)((c2 % 4 / 2)), (float)((c2 % 2)));

                Vector3 intersection = Sampler.GetIntersection(p1, p2, d1, d2) + position;
                Vector3 normal = Sampler.GetNormal(intersection);//GetNormal(x, y);
                average_normal += normal;

                qef.Add(intersection, normal);
                qefp.Add(intersection, normal);
            }

            Vector3 n = average_normal / (float)qef.Intersections.Count;
            n.Normalize();
            draw_info = new OctreeDrawInfo();
            //draw_info.position = position + qef.Solve2(0, 0, 0);
            draw_info.position = qefp.Solve(1e-6f, 4, 1e-6f);
            draw_info.corners = corners;
            draw_info.averageNormal = n;
            draw_info.qef = qefp;
            //vertices.Add(new VertexPositionColorNormal(position + draw_info.position, Color.LightGreen, n));

            type = OctreeNodeType.Leaf;
            return true;
        }
Example #4
0
        public void Simplify(float threshold, bool randomize = false)
        {
            if (type != OctreeNodeType.Internal)
                return;

            int[] signs = { -1, -1, -1, -1, -1, -1, -1, -1 };
            int mid_sign = -1;
            bool is_collapsible = true;
            //QEF3D qef = new QEF3D();
            QEFProper.QEFSolver qef = new QEFProper.QEFSolver();
            Random rnd = new Random();

            float t = threshold;
            for (int i = 0; i < 8; i++)
            {
                if (children[i] == null)
                    continue;

                if (randomize)
                    t = (float)rnd.NextDouble() * (float)rnd.NextDouble() * 20.0f;
                children[i].Simplify(t);
                OctreeNode child = children[i];

                if (child.type == OctreeNodeType.Internal)
                    is_collapsible = false;
                else
                {
                    //qef.Add(child.draw_info.position, child.draw_info.averageNormal);
                    //if (child.draw_info.qef != null)
                        qef.Add(ref child.draw_info.qef.data);

                    mid_sign = (child.draw_info.corners >> (7 - i)) & 1;
                    signs[i] = (child.draw_info.corners >> i) & 1;
                }
            }

            if (size == 16)
            {
            }

            if (!is_collapsible)
                return;

            //Vector3 pos = qef.Solve2(0, 0, 0);
            Vector3 pos = qef.Solve(1e-6f, 4, 1e-6f);
            float error = qef.GetError();

            if (error > threshold)
                return;

            OctreeDrawInfo draw_info = new OctreeDrawInfo();

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

            Vector3 normal = new Vector3();
            for (int i = 0; i < 8; i++)
            {
                if (children[i] != null)
                {
                    OctreeNode child = children[i];
                    if (child.type == OctreeNodeType.Pseudo || child.type == OctreeNodeType.Leaf)
                        normal += child.draw_info.averageNormal;
                }
            }

            normal.Normalize();
            draw_info.averageNormal = normal;
            draw_info.position = pos;
            draw_info.qef = qef;

            for (int i = 0; i < 8; i++)
            {
                children[i] = null;
            }

            type = OctreeNodeType.Pseudo;
            this.draw_info = draw_info;
        }
Example #5
0
 public OctreeNode()
 {
     type = OctreeNodeType.None;
     position = Vector3.Zero;
     size = 0;
     children = new OctreeNode[8];
     draw_info = null;
 }