Exemple #1
0
        public OctreeNode(OctreeNodeType _type)
        {
            Type     = _type;
            min      = Vec3.Zero;
            size     = 0;
            drawInfo = new OctreeDrawInfo();

            children = new OctreeNode[8];
            for (var i = 0; i < 8; i++)
            {
                children[i] = null;
            }
        }
Exemple #2
0
        static OctreeNode SimplifyOctree(OctreeNode node, double threshold)
        {
            if (node == null)
            {
                return(null);
            }

            if (node.Type != OctreeNodeType.Node_Internal)
            {
                // can't simplify!
                return(node);
            }

            var qef   = new QefSolver();
            var signs = new int[8] {
                -1, -1, -1, -1, -1, -1, -1, -1
            };
            var midsign       = -1;
            var edgeCount     = 0;
            var isCollapsible = true;

            for (var i = 0; i < 8; i++)
            {
                node.children[i] = SimplifyOctree(node.children[i], threshold);

                if (node.children[i] != null)
                {
                    var child = node.children[i];

                    if (child.Type == OctreeNodeType.Node_Internal)
                    {
                        isCollapsible = false;
                    }
                    else
                    {
                        qef.add(child.drawInfo.qef);

                        midsign  = (child.drawInfo.corners >> (7 - i)) & 1;
                        signs[i] = (child.drawInfo.corners >> i) & 1;

                        edgeCount++;
                    }
                }
            }

            if (!isCollapsible)
            {
                // at least one child is an internal node, can't collapse
                return(node);
            }

            Vec3 qefPosition;

            qef.solve(out qefPosition, QEF_ERROR, QEF_SWEEPS, QEF_ERROR);
            var error = qef.getError();

            // convert to glm vec3 for ease of use
            var position = new Vec3(qefPosition.X, qefPosition.Y, qefPosition.Z);

            // at this point the masspoint will actually be a sum, so divide to make it the average
            if (error > threshold)
            {
                // this collapse breaches the threshold
                return(node);
            }

            if (position.X < node.min.X || position.X > (node.min.X + node.size) ||
                position.Y < node.min.Y || position.Y > (node.min.Y + node.size) ||
                position.Z < node.min.Z || position.Z > (node.min.Z + node.size))
            {
                position = qef.getMassPoint();
            }

            // change the node from an internal node to a 'psuedo leaf' node
            var drawInfo = new OctreeDrawInfo();

            drawInfo.corners = 0;
            drawInfo.index   = -1;

            for (var i = 0; i < 8; i++)
            {
                if (signs[i] == -1)
                {
                    // Undetermined, use centre sign instead
                    drawInfo.corners |= (midsign << i);
                }
                else
                {
                    drawInfo.corners |= (signs[i] << i);
                }
            }

            drawInfo.averageNormal = Vec3.Zero;
            for (var i = 0; i < 8; i++)
            {
                if (node.children[i] != null)
                {
                    var child = node.children[i];
                    if (child.Type == OctreeNodeType.Node_Psuedo ||
                        child.Type == OctreeNodeType.Node_Leaf)
                    {
                        drawInfo.averageNormal += child.drawInfo.averageNormal;
                    }
                }
            }

            drawInfo.averageNormal = drawInfo.averageNormal.Normalized;
            drawInfo.position      = position;
            drawInfo.qef           = qef.getData();

            for (var i = 0; i < 8; i++)
            {
                DestroyOctree(node.children[i]);
                node.children[i] = null;
            }

            node.Type     = OctreeNodeType.Node_Psuedo;
            node.drawInfo = drawInfo;

            return(node);
        }