Exemplo n.º 1
0
            public static List <MeshData> GetSmallestPossibleMeshData(SpaceTreeNode root, Vector3 v3Min, Vector3 v3Max)
            {
                if (root.ContainsCompletely(v3Min, v3Max) == false)
                {
                    return(root.listMeshDatasSpace);
                }

                SpaceTreeNode nodeCurrent = root;

                while (true)
                {
                    if (nodeCurrent.nodeOneSide != null)
                    {
                        if (nodeCurrent.nodeOneSide.ContainsCompletely(v3Min, v3Max))
                        {
                            nodeCurrent = nodeCurrent.nodeOneSide;
                            continue;
                        }
                    }

                    if (nodeCurrent.nodeOtherSide != null)
                    {
                        if (nodeCurrent.nodeOtherSide.ContainsCompletely(v3Min, v3Max))
                        {
                            nodeCurrent = nodeCurrent.nodeOtherSide;
                            continue;
                        }
                    }

                    break;
                }

                return(nodeCurrent.listMeshDatasSpace);
            }
Exemplo n.º 2
0
            public static List<MeshData> GetSmallestPossibleMeshData(SpaceTreeNode root, Vector3 v3Min, Vector3 v3Max)
            {
                if(root.ContainsCompletely(v3Min, v3Max) == false)
                {
                    return root.listMeshDatasSpace;
                }

                SpaceTreeNode nodeCurrent = root;

                while(true)
                {
                    if(nodeCurrent.nodeOneSide != null)
                    {
                        if(nodeCurrent.nodeOneSide.ContainsCompletely(v3Min, v3Max))
                        {
                            nodeCurrent = nodeCurrent.nodeOneSide;
                            continue;
                        }
                    }

                    if(nodeCurrent.nodeOtherSide != null)
                    {
                        if(nodeCurrent.nodeOtherSide.ContainsCompletely(v3Min, v3Max))
                        {
                            nodeCurrent = nodeCurrent.nodeOtherSide;
                            continue;
                        }
                    }

                    break;
                }

                return nodeCurrent.listMeshDatasSpace;
            }
Exemplo n.º 3
0
            public static SpaceTreeNode BuildSpaceTree(MeshData meshDataIn, int nSubdivisionLevels, FracturedObject fracturedComponent, ProgressDelegate progress = null)
            {
                if (nSubdivisionLevels < 1)
                {
                    return(null);
                }

                SplitOptions splitOptions = new SplitOptions();

                splitOptions.bForceNoIslandGeneration     = true;
                splitOptions.bForceNoChunkConnectionInfo  = true;
                splitOptions.bForceNoIslandConnectionInfo = true;
                splitOptions.bForceNoCap       = false;
                splitOptions.bVerticesAreLocal = true;

                SpaceTreeNode nodeRoot = new SpaceTreeNode();

                nodeRoot.listMeshDatasSpace = new List <MeshData>();
                nodeRoot.listMeshDatasSpace.Add(meshDataIn);
                nodeRoot.nLevel   = 0;
                nodeRoot.nSplitsX = 0;
                nodeRoot.nSplitsY = 0;
                nodeRoot.nSplitsZ = 0;
                nodeRoot.v3Min    = meshDataIn.v3Min;
                nodeRoot.v3Max    = meshDataIn.v3Max;

                Queue <SpaceTreeNode> queueNodes = new Queue <SpaceTreeNode>();

                queueNodes.Enqueue(nodeRoot);

                int nTotalSubdivisions   = 0;
                int nCurrentSubdivisions = 0;
                int nSplitsX             = 0;
                int nSplitsY             = 0;
                int nSplitsZ             = 0;

                for (int i = 0; i < nSubdivisionLevels; i++)
                {
                    nTotalSubdivisions += Mathf.RoundToInt(Mathf.Pow(2, i));
                }

                while (queueNodes.Count > 0)
                {
                    SpaceTreeNode nodeCurrent = queueNodes.Dequeue();

                    List <MeshData> listMeshDataPos;
                    List <MeshData> listMeshDataNeg;

                    if (nodeCurrent.nLevel < nSubdivisionLevels)
                    {
                        if (progress != null)
                        {
                            progress("Fracturing", string.Format("Pre computing space volume (split {0}/{1}, Depth {2})", nCurrentSubdivisions + 1, nTotalSubdivisions, nodeCurrent.nLevel + 1), Mathf.Clamp01((float)nCurrentSubdivisions / (float)nTotalSubdivisions));
                        }

                        if (Fracturer.IsFracturingCancelled())
                        {
                            return(null);
                        }

                        Vector3 v3Normal = Vector3.up;
                        Vector3 v3Right  = Vector3.right;
                        Vector3 v3Pos    = (nodeCurrent.v3Min + nodeCurrent.v3Max) * 0.5f;

                        float fSizeX = nodeCurrent.v3Max.x - nodeCurrent.v3Min.x;
                        float fSizeY = nodeCurrent.v3Max.y - nodeCurrent.v3Min.y;
                        float fSizeZ = nodeCurrent.v3Max.z - nodeCurrent.v3Min.z;

                        Vector3 v3MinNeg = nodeCurrent.v3Min;
                        Vector3 v3MaxNeg = nodeCurrent.v3Max;
                        Vector3 v3MinPos = nodeCurrent.v3Min;
                        Vector3 v3MaxPos = nodeCurrent.v3Max;

                        if (fSizeX >= fSizeY && fSizeX >= fSizeZ)
                        {
                            v3Normal = Vector3.right;
                            v3Right  = Vector3.forward;

                            v3MaxNeg.x = v3Pos.x;
                            v3MinPos.x = v3Pos.x;

                            nSplitsX++;
                        }
                        else if (fSizeY >= fSizeX && fSizeY >= fSizeZ)
                        {
                            v3Normal = Vector3.up;
                            v3Right  = Vector3.right;

                            v3MaxNeg.y = v3Pos.y;
                            v3MinPos.y = v3Pos.y;

                            nSplitsY++;
                        }
                        else
                        {
                            v3Normal = Vector3.forward;
                            v3Right  = Vector3.right;

                            v3MaxNeg.z = v3Pos.z;
                            v3MinPos.z = v3Pos.z;

                            nSplitsZ++;
                        }

                        foreach (MeshData meshData in nodeCurrent.listMeshDatasSpace)
                        {
                            if (SplitMeshUsingPlane(meshData, fracturedComponent, splitOptions, v3Normal, v3Right, v3Pos, out listMeshDataPos, out listMeshDataNeg, progress) == true)
                            {
                                nodeCurrent.nodeOneSide = new SpaceTreeNode();
                                nodeCurrent.nodeOneSide.listMeshDatasSpace = listMeshDataNeg;
                                nodeCurrent.nodeOneSide.v3Min    = v3MinNeg;
                                nodeCurrent.nodeOneSide.v3Max    = v3MaxNeg;
                                nodeCurrent.nodeOneSide.nLevel   = nodeCurrent.nLevel + 1;
                                nodeCurrent.nodeOneSide.nSplitsX = nSplitsX;
                                nodeCurrent.nodeOneSide.nSplitsY = nSplitsY;
                                nodeCurrent.nodeOneSide.nSplitsZ = nSplitsZ;

                                queueNodes.Enqueue(nodeCurrent.nodeOneSide);

                                nodeCurrent.nodeOtherSide = new SpaceTreeNode();
                                nodeCurrent.nodeOtherSide.listMeshDatasSpace = listMeshDataPos;
                                nodeCurrent.nodeOtherSide.v3Min    = v3MinPos;
                                nodeCurrent.nodeOtherSide.v3Max    = v3MaxPos;
                                nodeCurrent.nodeOtherSide.nLevel   = nodeCurrent.nLevel + 1;
                                nodeCurrent.nodeOtherSide.nSplitsX = nSplitsX;
                                nodeCurrent.nodeOtherSide.nSplitsY = nSplitsY;
                                nodeCurrent.nodeOtherSide.nSplitsZ = nSplitsZ;

                                queueNodes.Enqueue(nodeCurrent.nodeOtherSide);
                            }
                        }

                        nCurrentSubdivisions++;
                    }
                }

                return(nodeRoot);
            }
Exemplo n.º 4
0
            public static SpaceTreeNode BuildSpaceTree(MeshData meshDataIn, int nSubdivisionLevels, FracturedObject fracturedComponent, ProgressDelegate progress = null)
            {
                if(nSubdivisionLevels < 1)
                {
                    return null;
                }

                SplitOptions splitOptions = new SplitOptions();

                splitOptions.bForceNoIslandGeneration     = true;
                splitOptions.bForceNoChunkConnectionInfo  = true;            
                splitOptions.bForceNoIslandConnectionInfo = true;
                splitOptions.bForceNoCap                  = false;
                splitOptions.bVerticesAreLocal            = true;

                SpaceTreeNode nodeRoot = new SpaceTreeNode();

                nodeRoot.listMeshDatasSpace = new List<MeshData>();
                nodeRoot.listMeshDatasSpace.Add(meshDataIn);
                nodeRoot.nLevel   = 0;
                nodeRoot.nSplitsX = 0;
                nodeRoot.nSplitsY = 0;
                nodeRoot.nSplitsZ = 0;
                nodeRoot.v3Min    = meshDataIn.v3Min;
                nodeRoot.v3Max    = meshDataIn.v3Max;

                Queue<SpaceTreeNode> queueNodes = new Queue<SpaceTreeNode>();
                queueNodes.Enqueue(nodeRoot);

                int nTotalSubdivisions   = 0;
                int nCurrentSubdivisions = 0;
                int nSplitsX             = 0;
                int nSplitsY             = 0;
                int nSplitsZ             = 0;
                
                for(int i = 0; i < nSubdivisionLevels; i++)
                {
                    nTotalSubdivisions += Mathf.RoundToInt(Mathf.Pow(2, i));
                }

                while(queueNodes.Count > 0)
                {
                    SpaceTreeNode nodeCurrent = queueNodes.Dequeue();

                    List<MeshData> listMeshDataPos;
                    List<MeshData> listMeshDataNeg;

                    if(nodeCurrent.nLevel < nSubdivisionLevels)
                    {
                        if(progress != null)
                        {
                            progress("Fracturing", string.Format("Pre computing space volume (split {0}/{1}, Depth {2})", nCurrentSubdivisions + 1, nTotalSubdivisions, nodeCurrent.nLevel + 1), Mathf.Clamp01((float)nCurrentSubdivisions / (float)nTotalSubdivisions));
                        }

                        if(Fracturer.IsFracturingCancelled())
                        {
                            return null;
                        }

                        Vector3 v3Normal = Vector3.up;
                        Vector3 v3Right  = Vector3.right;
                        Vector3 v3Pos    = (nodeCurrent.v3Min + nodeCurrent.v3Max) * 0.5f;

                        float fSizeX = nodeCurrent.v3Max.x - nodeCurrent.v3Min.x;
                        float fSizeY = nodeCurrent.v3Max.y - nodeCurrent.v3Min.y;
                        float fSizeZ = nodeCurrent.v3Max.z - nodeCurrent.v3Min.z;

                        Vector3 v3MinNeg = nodeCurrent.v3Min;
                        Vector3 v3MaxNeg = nodeCurrent.v3Max;
                        Vector3 v3MinPos = nodeCurrent.v3Min;
                        Vector3 v3MaxPos = nodeCurrent.v3Max;

                        if(fSizeX >= fSizeY && fSizeX >= fSizeZ)
                        {
                            v3Normal = Vector3.right;
                            v3Right  = Vector3.forward;

                            v3MaxNeg.x = v3Pos.x;
                            v3MinPos.x = v3Pos.x;

                            nSplitsX++;
                        }
                        else if(fSizeY >= fSizeX && fSizeY >= fSizeZ)
                        {
                            v3Normal = Vector3.up;
                            v3Right  = Vector3.right;

                            v3MaxNeg.y = v3Pos.y;
                            v3MinPos.y = v3Pos.y;

                            nSplitsY++;
                        }
                        else
                        {
                            v3Normal = Vector3.forward;
                            v3Right  = Vector3.right;

                            v3MaxNeg.z = v3Pos.z;
                            v3MinPos.z = v3Pos.z;

                            nSplitsZ++;
                        }

                        foreach(MeshData meshData in nodeCurrent.listMeshDatasSpace)
                        {
                            if(SplitMeshUsingPlane(meshData, fracturedComponent, splitOptions, v3Normal, v3Right, v3Pos, out listMeshDataPos, out listMeshDataNeg, progress) == true)
                            {
                                nodeCurrent.nodeOneSide = new SpaceTreeNode();
                                nodeCurrent.nodeOneSide.listMeshDatasSpace = listMeshDataNeg;
                                nodeCurrent.nodeOneSide.v3Min    = v3MinNeg;
                                nodeCurrent.nodeOneSide.v3Max    = v3MaxNeg;
                                nodeCurrent.nodeOneSide.nLevel   = nodeCurrent.nLevel + 1;
                                nodeCurrent.nodeOneSide.nSplitsX = nSplitsX;
                                nodeCurrent.nodeOneSide.nSplitsY = nSplitsY;
                                nodeCurrent.nodeOneSide.nSplitsZ = nSplitsZ;

                                queueNodes.Enqueue(nodeCurrent.nodeOneSide);

                                nodeCurrent.nodeOtherSide = new SpaceTreeNode();
                                nodeCurrent.nodeOtherSide.listMeshDatasSpace = listMeshDataPos;
                                nodeCurrent.nodeOtherSide.v3Min    = v3MinPos;
                                nodeCurrent.nodeOtherSide.v3Max    = v3MaxPos;
                                nodeCurrent.nodeOtherSide.nLevel   = nodeCurrent.nLevel + 1;
                                nodeCurrent.nodeOtherSide.nSplitsX = nSplitsX;
                                nodeCurrent.nodeOtherSide.nSplitsY = nSplitsY;
                                nodeCurrent.nodeOtherSide.nSplitsZ = nSplitsZ;

                                queueNodes.Enqueue(nodeCurrent.nodeOtherSide);
                            }
                        }

                        nCurrentSubdivisions++;
                    }
                }

                return nodeRoot;
            }