コード例 #1
0
        public static void GenerateVertexIndices(OctreeNode node, List <Vector3> vertices, List <Vector3> normals)
        {
            if (node == null)
            {
                return;
            }
            if (node.type != DCC.OctreeNodeType.Node_Leaf)
            {
                for (int i = 0; i < node.children.Length; i++)
                {
                    GenerateVertexIndices(node.children[i], vertices, normals);
                }
            }
            else
            {
                OctreeDrawInfo d = node.drawInfo;
                //Debug.Log("Generating vertix indices... d: ");
                //Debug.Log(d);
                if (d == null)
                {
                    return;
                }

                d.index = vertices.Count;
                vertices.Add(d.position);
                normals.Add(d.averageNormal);
            }
        }
コード例 #2
0
ファイル: Octree.cs プロジェクト: epitaque/LODDualContouring
        public OctreeNode(DCC.OctreeNodeType _type)
        {
            type     = _type;
            min      = Vector3.zero;
            size     = 0;
            drawInfo = null;

            for (int i = 0; i < 8; i++)
            {
                children[i] = null;
            }
        }
コード例 #3
0
ファイル: Octree.cs プロジェクト: epitaque/LODDualContouring
        public OctreeNode()
        {
            type     = DCC.OctreeNodeType.Node_Internal;
            min      = Vector3.zero;
            size     = 0;
            drawInfo = null;

            children = new OctreeNode[8];
            for (int i = 0; i < 8; i++)
            {
                children[i] = null;
            }
        }
コード例 #4
0
        public static OctreeNode SimplifyOctree(OctreeNode node, float threshold)
        {
            if (node == null)
            {
                return(null);
            }
            if (node.type != DCC.OctreeNodeType.Node_Internal)
            {
                return(node);
            }

            QEF.QEFSolver qef           = new QEF.QEFSolver();
            int[]         signs         = { -1, -1, -1, -1, -1, -1, -1, -1 };
            int           midsign       = -1;
            int           edgeCount     = 0;
            bool          isCollapsible = true;

            for (int i = 0; i < 8; i++)
            {
                node.children[i] = SimplifyOctree(node.children[i], threshold);
                if (node.children[i] != null)
                {
                    OctreeNode child = node.children[i];
                    if (child.type == DCC.OctreeNodeType.Node_Internal)
                    {
                        isCollapsible = false;
                    }
                    else
                    {
                        qef.Add(ref child.drawInfo.qef.data);

                        if (qef.data.numPoints == 0)
                        {
                            Debug.Log("warning: zero points in qef");
                            Debug.Log("child number of points: " + child.drawInfo.qef.data.numPoints);
                        }

                        //Debug.LogError("Qef points: " + qef.data.numPoints);

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

                        edgeCount++;
                    }
                }
                else
                {
                    //Debug.LogError("Null child! type: " + node.type);
                }
            }

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

            float QEF_ERROR  = 0.1f;
            int   QEF_SWEEPS = 4;
            float PINV_TOL   = 0.1f;

            if (qef.data.numPoints == 0)
            {
                for (int i = 0; i < 8; i++)
                {
                    //DestroyOctree(node->children[i]);
                    node.children[i] = null;
                }

                node.type = DCC.OctreeNodeType.Node_Psuedo;

                OctreeDrawInfo drawInfo2 = new OctreeDrawInfo();

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

                drawInfo2.averageNormal = Vector3.zero;


                node.drawInfo = drawInfo2;

                return(node);
            }

            Vector3 position = qef.Solve(QEF_ERROR, QEF_SWEEPS, PINV_TOL);
            //if(qef.data.num)
            float error = qef.GetError();

            // 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))
            {
                Vector3 mp = qef.MassPoint;
                position = new Vector3(mp.x, mp.y, mp.z);
            }

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

            for (int 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 = Vector3.zero;
            for (int i = 0; i < 8; i++)
            {
                if (node.children[i] != null)
                {
                    OctreeNode child = node.children[i];
                    if (child.type == DCC.OctreeNodeType.Node_Psuedo ||
                        child.type == DCC.OctreeNodeType.Node_Leaf)
                    {
                        drawInfo.averageNormal += child.drawInfo.averageNormal;
                    }
                }
            }

            drawInfo.averageNormal = Vector3.Normalize(drawInfo.averageNormal);
            drawInfo.position      = position;

            QEF.QEFSolver qef2 = new QEF.QEFSolver();

            qef2.data = qef.data;

            drawInfo.qef = qef2;

            for (int i = 0; i < 8; i++)
            {
                //DestroyOctree(node->children[i]);
                node.children[i] = null;
            }

            node.type     = DCC.OctreeNodeType.Node_Psuedo;
            node.drawInfo = drawInfo;

            return(node);
        }