Example #1
0
        public void GenerateAt(int x, int y, int z)
        {
            int corners = 0;
            for (int i = 0; i < 8; i++)
            {
                if (map[x + i / 4, y + i % 4 / 2, z + i % 2] < 0)
                    corners |= 1 << i;
            }

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

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

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

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

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

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

            QEF3D qef = new QEF3D();
            Vector3 average_normal = new Vector3();
            for (int i = 0; i < 12; i++)
            {
                int c1 = edges[i, 0];
                int c2 = edges[i, 1];

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

                float d1 = map[x + c1 / 4, y + c1 % 4 / 2, z + c1 % 2];
                float d2 = map[x + c2 / 4, y + c2 % 4 / 2, z + 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);
                Vector3 normal = Sampler.GetNormal(intersection + new Vector3(x, y, z));//GetNormal(x, y);
                average_normal += normal;

                qef.Add(intersection, normal);
            }

            Vector3 p = qef.Solve2(0, 16, 0);

            Vector3 n = average_normal / (float)qef.Intersections.Count;
            VertexPositionColorNormal[] v2 = new VertexPositionColorNormal[1];
            Vector3 c_v = n * 0.5f + Vector3.One * 0.5f;
            c_v.Normalize();
            Color clr = new Color(c_v);
            v2[0] = new VertexPositionColorNormal(new Vector3((p.X + x), (p.Y + y), (p.Z + z)), clr, n);
            VertexBuffer.SetData<VertexPositionColorNormal>(VertexCount * VertexPositionColorNormal.VertexDeclaration.VertexStride, v2, 0, 1, VertexPositionColorNormal.VertexDeclaration.VertexStride);
            vertex_indexes[x, y, z] = VertexCount;
            VertexCount++;
            /*vs[0] = new VertexPositionColor(new Vector3((x + 0) , (y + 0) , 0), Color.Black);
            vs[1] = new VertexPositionColor(new Vector3((x + 1) , (y + 0) , 0), Color.Black);
            vs[2] = new VertexPositionColor(new Vector3((x + 1) , (y + 0) , 0), Color.Black);
            vs[3] = new VertexPositionColor(new Vector3((x + 1) , (y + 1) , 0), Color.Black);
            vs[4] = new VertexPositionColor(new Vector3((x + 1) , (y + 1) , 0), Color.Black);
            vs[5] = new VertexPositionColor(new Vector3((x + 0) , (y + 1) , 0), Color.Black);
            vs[6] = new VertexPositionColor(new Vector3((x + 0) , (y + 1) , 0), Color.Black);
            vs[7] = new VertexPositionColor(new Vector3((x + 0) , (y + 0) , 0), Color.Black);

            vs[8] = new VertexPositionColor(new Vector3((p.X + x) , (p.Y + y) , 0), Color.Black);
            vs[9] = new VertexPositionColor(new Vector3((p.X + x + .1f) , (p.Y + y + .1f) , 0), Color.Black);
            index = 10;

            VertexBuffer.SetData<VertexPositionColor>(VertexCount * VertexPositionColor.VertexDeclaration.VertexStride, vs, 0, index, VertexPositionColor.VertexDeclaration.VertexStride);
            VertexCount += index;*/
        }
Example #2
0
        public void GenerateAt(int x, int y, int z)
        {
            int corners = 0;

            for (int i = 0; i < 8; i++)
            {
                if (map[x + i / 4, y + i % 4 / 2, z + i % 2] < 0)
                {
                    corners |= 1 << i;
                }
            }

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

            VertexPositionColor[] vs = new VertexPositionColor[24];
            Color c = Color.LightSteelBlue;

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

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

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

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

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

            QEF3D   qef            = new QEF3D();
            Vector3 average_normal = new Vector3();

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

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

                float d1 = map[x + c1 / 4, y + c1 % 4 / 2, z + c1 % 2];
                float d2 = map[x + c2 / 4, y + c2 % 4 / 2, z + 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);
                Vector3 normal       = Sampler.GetNormal(intersection + new Vector3(x, y, z));          //GetNormal(x, y);
                average_normal += normal;

                qef.Add(intersection, normal);
            }

            Vector3 p = qef.Solve2(0, 16, 0);

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

            VertexPositionColorNormal[] v2 = new VertexPositionColorNormal[1];
            Vector3 c_v = n * 0.5f + Vector3.One * 0.5f;

            c_v.Normalize();
            Color clr = new Color(c_v);

            v2[0] = new VertexPositionColorNormal(new Vector3((p.X + x), (p.Y + y), (p.Z + z)), clr, n);
            VertexBuffer.SetData <VertexPositionColorNormal>(VertexCount * VertexPositionColorNormal.VertexDeclaration.VertexStride, v2, 0, 1, VertexPositionColorNormal.VertexDeclaration.VertexStride);
            vertex_indexes[x, y, z] = VertexCount;
            VertexCount++;

            /*vs[0] = new VertexPositionColor(new Vector3((x + 0) , (y + 0) , 0), Color.Black);
             * vs[1] = new VertexPositionColor(new Vector3((x + 1) , (y + 0) , 0), Color.Black);
             * vs[2] = new VertexPositionColor(new Vector3((x + 1) , (y + 0) , 0), Color.Black);
             * vs[3] = new VertexPositionColor(new Vector3((x + 1) , (y + 1) , 0), Color.Black);
             * vs[4] = new VertexPositionColor(new Vector3((x + 1) , (y + 1) , 0), Color.Black);
             * vs[5] = new VertexPositionColor(new Vector3((x + 0) , (y + 1) , 0), Color.Black);
             * vs[6] = new VertexPositionColor(new Vector3((x + 0) , (y + 1) , 0), Color.Black);
             * vs[7] = new VertexPositionColor(new Vector3((x + 0) , (y + 0) , 0), Color.Black);
             *
             * vs[8] = new VertexPositionColor(new Vector3((p.X + x) , (p.Y + y) , 0), Color.Black);
             * vs[9] = new VertexPositionColor(new Vector3((p.X + x + .1f) , (p.Y + y + .1f) , 0), Color.Black);
             * index = 10;
             *
             * VertexBuffer.SetData<VertexPositionColor>(VertexCount * VertexPositionColor.VertexDeclaration.VertexStride, vs, 0, index, VertexPositionColor.VertexDeclaration.VertexStride);
             * VertexCount += index;*/
        }
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
        /* 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 #5
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();
            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);

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

            if (!is_collapsible)
                return;

            Vector3 pos = qef.Solve2(0, 0, 0);
            float error = qef.Error;

            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;

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

            type = OctreeNodeType.Pseudo;
            this.draw_info = draw_info;
        }