コード例 #1
0
            public void LodInternal(LOD[] lods, int lodLevel)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;
                    if (thisCell.currentLod != lodLevel)
                    {
                        for (int i = 0; i < lods.Length; i++)
                        {
                            bool active = (i == lodLevel);
                            for (int j = 0; j < thisCell.mrList[i].Count; j++)
                            {
                                thisCell.mrList[i][j].enabled = active;
                            }
                        }

                        thisCell.currentLod = lodLevel;
                    }
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            cells[i].LodInternal(lods, lodLevel);
                        }
                    }
                }
            } //===============================================================================================================================
コード例 #2
0
            void AddMeshRendererInternal(MeshRenderer mr, Vector3 position, int lodLevel, int lodLevels)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;
                    if (thisCell.mrList == null)
                    {
                        thisCell.mrList = new List <MeshRenderer> [lodLevels];
                    }
                    List <MeshRenderer>[] mrList = thisCell.mrList;

                    if (mrList[lodLevel] == null)
                    {
                        mrList[lodLevel] = new List <MeshRenderer>();
                    }
                    mrList[lodLevel].Add(mr);
                    thisCell.currentLod = -1;
                }
                else
                {
                    bool maxCellCreated;
                    int  index = AddCell <Cell, MaxCell>(ref cells, position, out maxCellCreated);
                    cells[index].box = new AABB3(cells[index].bounds.min, cells[index].bounds.max);
                    cells[index].AddMeshRendererInternal(mr, position, lodLevel, lodLevels);
                }
            }
コード例 #3
0
            public void CombineMeshes(MeshCombiner meshCombiner, int lodLevel)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;
                    LOD     lod      = thisCell.lods[lodLevel];

                    if (lod == null)
                    {
                        return;
                    }

                    for (int i = 0; i < lod.sortedMeshes.Count; ++i)
                    {
                        meshCombiner.CombineMeshes(lod.sortedMeshes[i], bounds.center);
                    }
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            cells[i].CombineMeshes(meshCombiner, lodLevel);
                        }
                    }
                }
            }
コード例 #4
0
            int AddCell(Vector3 position)
            {
                Vector3 localPos = position - bounds.min;

                int x = (int)(localPos.x / bounds.extents.x);
                int y = (int)(localPos.y / bounds.extents.y);
                int z = (int)(localPos.z / bounds.extents.z);

                int index = x + (y * 4) + (z * 2);

                if (cells == null)
                {
                    cells = new Cell[8]; cellsUsed = new bool[8];
                }

                // Reporter.Log("index "+index+" position "+localPos+" x: "+x+" y: "+y+" z: "+z+" extents "+bounds.extents);

                if (!cellsUsed[index])
                {
                    Bounds subBounds = new Bounds(new Vector3(bounds.min.x + (bounds.extents.x * (x + 0.5f)), bounds.min.y + (bounds.extents.y * (y + 0.5f)), bounds.min.z + (bounds.extents.z * (z + 0.5f))), bounds.extents);

                    if (level == maxLevels - 1)
                    {
                        cells[index] = new MaxCell(this, index, subBounds);
                    }
                    else
                    {
                        cells[index] = new Cell(this, index, subBounds);
                    }

                    cellsUsed[index] = true;
                    ++cellCount;
                }
                return(index);
            }
コード例 #5
0
            public void Draw(MeshCombiner meshCombiner, bool onlyMaxLevel, bool drawLevel0)
            {
                if (!onlyMaxLevel || level == maxLevels || (drawLevel0 && level == 0))
                {
                    Gizmos.DrawWireCube(bounds.center, bounds.size);

                    if (level == maxLevels)
                    {
                        if (meshCombiner.drawMeshBounds)
                        {
                            MaxCell thisCell = (MaxCell)this;

                            LODParent[] lodParents = thisCell.lodParents;

                            for (int i = 0; i < lodParents.Length; i++)
                            {
                                if (lodParents[i] == null)
                                {
                                    continue;
                                }

                                LODLevel[] lods = lodParents[i].lodLevels;

                                Gizmos.color = meshCombiner.activeOriginal ? Color.blue : Color.green;
                                for (int j = 0; j < lods.Length; j++)
                                {
                                    for (int k = 0; k < lods[j].cachedGOs.Count; k++)
                                    {
                                        if (lods[j].cachedGOs.items[k].mr == null)
                                        {
                                            continue;
                                        }
                                        Bounds meshBounds = lods[j].cachedGOs.items[k].mr.bounds;
                                        Gizmos.DrawWireCube(meshBounds.center, meshBounds.size);
                                    }
                                }
                                Gizmos.color = Color.white;
                            }
                            return;
                        }
                    }
                }

                if (cells == null || cellsUsed == null)
                {
                    return;
                }

                for (int i = 0; i < 8; i++)
                {
                    if (cellsUsed[i])
                    {
                        cells[i].Draw(meshCombiner, onlyMaxLevel, drawLevel0);
                    }
                }
            }
コード例 #6
0
            void AddObjectInternal(MeshCombiner meshCombiner, CachedGameObject cachedGO, Vector3 position, int lodParentIndex, int lodLevel, bool isChangeMode)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;

                    if (thisCell.lodParents == null)
                    {
                        thisCell.lodParents = new LODParent[10];
                    }
                    if (thisCell.lodParents[lodParentIndex] == null)
                    {
                        thisCell.lodParents[lodParentIndex] = new LODParent(lodParentIndex + 1);
                    }

                    LODParent lodParent = thisCell.lodParents[lodParentIndex];
                    LODLevel  lod       = lodParent.lodLevels[lodLevel];

                    lod.cachedGOs.Add(cachedGO);
                    if (isChangeMode)
                    {
                        if (SortObject(meshCombiner, lod, cachedGO))
                        {
                            if (!thisCell.hasChanged)
                            {
                                thisCell.hasChanged = true;
                                if (meshCombiner.changedCells == null)
                                {
                                    meshCombiner.changedCells = new List <MaxCell>();
                                }
                                meshCombiner.changedCells.Add(thisCell);
                            }
                            if (!lodParent.hasChanged)
                            {
                                lodParent.hasChanged = true;
                                thisCell.changedLodParents.Add(lodParent);
                            }
                        }
                    }

                    lod.objectCount++;

                    lod.vertCount += cachedGO.mesh.vertexCount;
                    return;
                }
                else
                {
                    bool maxCellCreated;
                    int  index = AddCell <Cell, MaxCell>(ref cells, position, out maxCellCreated);
                    if (maxCellCreated)
                    {
                        MaxCell.maxCellCount++;
                    }
                    cells[index].AddObjectInternal(meshCombiner, cachedGO, position, lodParentIndex, lodLevel, isChangeMode);
                }
            }
コード例 #7
0
            void AddObjectInternal(Transform t, Vector3 position, bool addToSingle, int lodLevel)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;

                    if (thisCell.lods == null)
                    {
                        thisCell.lods = new LOD[lodCount];
                    }
                    if (thisCell.lods[lodLevel] == null)
                    {
                        thisCell.lods[lodLevel] = new LOD();
                    }

                    LOD lod = thisCell.lods[lodLevel];

                    if (lod.transforms == null)
                    {
                        lod.transforms = new List <Transform>();
                    }

                    if (addToSingle)
                    {
                        lod.singleTransforms.Add(t);
                    }
                    else
                    {
                        lod.transforms.Add(t);
                    }

                    lod.objectCount++;

                    MeshFilter mf = t.GetComponent <MeshFilter>();
                    Mesh       m  = mf.sharedMesh;
                    lod.vertCount += m.vertexCount;
                    return;
                }
                else
                {
                    bool maxCellCreated;
                    int  index = AddCell <Cell, MaxCell>(ref cells, position, out maxCellCreated);
                    if (maxCellCreated)
                    {
                        MaxCell.maxCellCount++;
                    }
                    cells[index].AddObjectInternal(t, position, addToSingle, lodLevel);
                }
            }
コード例 #8
0
            public void SortObjects(MeshCombiner meshCombiner)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;

                    LODParent[] lodParents = thisCell.lodParents;

                    for (int i = 0; i < lodParents.Length; i++)
                    {
                        LODParent lodParent = lodParents[i];
                        if (lodParent == null)
                        {
                            continue;
                        }

                        for (int j = 0; j < lodParent.lodLevels.Length; j++)
                        {
                            LODLevel lod = lodParent.lodLevels[j];

                            if (lod == null || lod.cachedGOs.Count == 0)
                            {
                                return;
                            }

                            for (int k = 0; k < lod.cachedGOs.Count; ++k)
                            {
                                CachedGameObject cachedGO = lod.cachedGOs.items[k];

                                if (!SortObject(meshCombiner, lod, cachedGO))
                                {
                                    lod.cachedGOs.RemoveAt(k--);
                                }
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            cells[i].SortObjects(meshCombiner);
                        }
                    }
                }
            }
コード例 #9
0
            public void SortObjects(int lodLevel)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;
                    LOD     lod      = thisCell.lods[lodLevel];

                    if (lod == null)
                    {
                        return;
                    }

                    lod.sortedMeshes = new List <SingleMeshes>();

                    for (int i = 0; i < lod.singleTransforms.Count; ++i)
                    {
                        Transform    t    = lod.singleTransforms[i];
                        MeshFilter   mf   = t.GetComponent <MeshFilter>();
                        MeshRenderer mr   = t.GetComponent <MeshRenderer>();
                        Material     mat  = mr.sharedMaterial;
                        Mesh         mesh = mf.sharedMesh;

                        int index = lod.GetSortMeshIndex(mat);
                        if (index != -1)
                        {
                            lod.sortedMeshes[index].meshes.Add(new MeshInfo(t, mesh));
                        }
                        else
                        {
                            lod.sortedMeshes.Add(new SingleMeshes(t, mat, mesh));
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            cells[i].SortObjects(lodLevel);
                        }
                    }
                }
            }
コード例 #10
0
            public void UncombineMeshes(MeshCombiner meshCombiner, int lodLevel)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;
                    LOD     lod      = thisCell.lods[lodLevel];
                    // Debug.Log("Multi Count " + lod.transforms.Count);
                    // Debug.Log("Single Count " + lod.singleTransforms.Count);
                    if (lod == null)
                    {
                        Debug.Log("-------------");
                        for (int i = 0; i < 3; i++)
                        {
                            LOD lod0 = thisCell.lods[i];
                            if (lod0 == null)
                            {
                                Debug.Log(i);
                            }
                        }
                        Debug.Log("-------------");
                        return;
                    }

                    meshCombiner.UncombineMeshes(lod.transforms, lodLevel);
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            if (cells[i] == null)
                            {
                                Debug.Log(i);
                            }
                            cells[i].UncombineMeshes(meshCombiner, lodLevel);
                        }
                    }
                }
            }
コード例 #11
0
            public void SetObjectsActive(bool active, int lodLevel)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;
                    LOD     lod      = thisCell.lods[lodLevel];

                    for (int i = 0; i < lod.sortedMeshes.Count; ++i)
                    {
                    }
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            cells[i].SetObjectsActive(active, lodLevel);
                        }
                    }
                }
            }
コード例 #12
0
            public void DrawGizmosInternal()
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;
                    if (thisCell.currentLod == 0)
                    {
                        Gizmos.color = Color.red;
                    }
                    else if (thisCell.currentLod == 1)
                    {
                        Gizmos.color = Color.green;
                    }
                    else if (thisCell.currentLod == 2)
                    {
                        Gizmos.color = Color.yellow;
                    }
                    else if (thisCell.currentLod == 3)
                    {
                        Gizmos.color = Color.blue;
                    }

                    Gizmos.DrawWireCube(bounds.center, bounds.size - new Vector3(0.25f, 0.25f, 0.25f));

                    Gizmos.color = Color.white;
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            cells[i].DrawGizmosInternal();
                        }
                    }
                }
            }
コード例 #13
0
            public void CombineMeshes(MeshCombiner meshCombiner, int lodParentIndex)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;

                    LODParent lodParent = thisCell.lodParents[lodParentIndex];
                    if (lodParent == null)
                    {
                        return;
                    }

                    CombineMode combineMode = meshCombiner.combineMode;

                    if (combineMode != CombineMode.DynamicObjects)
                    {
                        lodParent.cellGO         = new GameObject(meshCombiner.combineMode == CombineMode.StaticObjects ? "Cell " + bounds.center : "Combined Objects");
                        lodParent.cellT          = lodParent.cellGO.transform;
                        lodParent.cellT.position = bounds.center;
                        lodParent.cellT.parent   = meshCombiner.lodParentHolders[lodParentIndex].t;
                    }

                    if (lodParentIndex > 0)
                    {
                        lodParent.lodGroup = lodParent.cellGO.AddComponent <LODGroup>();
                        lodParent.lodGroup.localReferencePoint = lodParent.cellT.position = bounds.center;
                    }

                    LODLevel[] lods = lodParent.lodLevels;
                    for (int i = 0; i < lods.Length; i++)
                    {
                        LODLevel lod = lodParent.lodLevels[i];
                        if (lod == null || lod.meshObjectsHoldersLookup == null)
                        {
                            return;
                        }

                        GameObject lodGO;
                        Transform  lodT = null;

                        if (lodParentIndex > 0)
                        {
                            lodGO       = new GameObject("LOD" + i);
                            lodT        = lodGO.transform;
                            lodT.parent = lodParent.cellT;
                        }

                        foreach (MeshObjectsHolder sortedMeshes in lod.meshObjectsHoldersLookup.Values)
                        {
                            sortedMeshes.lodParent = lodParent;
                            sortedMeshes.lodLevel  = i;
                            Vector3 position = (combineMode == CombineMode.DynamicObjects ? sortedMeshes.meshObjects.items[0].cachedGO.rootT.position : bounds.center);
                            MeshCombineJobManager.instance.AddJob(meshCombiner, sortedMeshes, lodParentIndex > 0 ? lodT : lodParent.cellT, position);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            cells[i].CombineMeshes(meshCombiner, lodParentIndex);
                        }
                    }
                }
            }
コード例 #14
0
            public void AutoLodInternal(LOD[] lods, float lodCulledDistance)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;
                    if (lodCulledDistance != -1)
                    {
                        float squareDistance = (bounds.center - lods[0].sphere.center).sqrMagnitude;
                        if (squareDistance > lodCulledDistance * lodCulledDistance)
                        {
                            if (thisCell.currentLod != -1)
                            {
                                for (int i = 0; i < lods.Length; i++)
                                {
                                    for (int j = 0; j < thisCell.mrList[i].Count; j++)
                                    {
                                        thisCell.mrList[i][j].enabled = false;
                                    }
                                }
                                thisCell.currentLod = -1;
                            }
                            return;
                        }
                    }

                    for (int lodIndex = 0; lodIndex < lods.Length; lodIndex++)
                    {
                        bool intersect;
                        if (lodIndex < lods.Length - 1)
                        {
                            intersect = Mathw.IntersectAABB3Sphere3(box, lods[lodIndex].sphere);
                        }
                        else
                        {
                            intersect = true;
                        }

                        if (intersect)
                        {
                            if (thisCell.currentLod != lodIndex)
                            {
                                for (int i = 0; i < lods.Length; i++)
                                {
                                    bool active = (i == lodIndex);
                                    for (int j = 0; j < thisCell.mrList[i].Count; j++)
                                    {
                                        thisCell.mrList[i][j].enabled = active;
                                    }
                                }
                                thisCell.currentLod = lodIndex;
                            }
                            break;
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            cells[i].AutoLodInternal(lods, lodCulledDistance);
                        }
                    }
                }
            }
コード例 #15
0
            public void CombineMeshes(MeshCombiner meshCombiner, int lodParentIndex)
            {
                if (level == maxLevels)
                {
                    MaxCell thisCell = (MaxCell)this;

                    LODParent lodParent = thisCell.lodParents[lodParentIndex];
                    if (lodParent == null)
                    {
                        return;
                    }

                    lodParent.cellGO         = new GameObject(meshCombiner.useCells ? "Cell " + bounds.center : "Combined Objects");
                    lodParent.cellT          = lodParent.cellGO.transform;
                    lodParent.cellT.position = bounds.center;
                    lodParent.cellT.parent   = meshCombiner.lodParentHolders[lodParentIndex].t;

                    if (lodParentIndex > 0)
                    {
                        lodParent.lodGroup = lodParent.cellGO.AddComponent <LODGroup>();
                        lodParent.lodGroup.localReferencePoint = lodParent.cellT.position = bounds.center;
                    }

                    LODLevel[] lods = lodParent.lodLevels;
                    for (int i = 0; i < lods.Length; i++)
                    {
                        LODLevel lod = lodParent.lodLevels[i];
                        if (lod == null || lod.meshObjectsHolders == null)
                        {
                            return;
                        }

                        GameObject lodGO;
                        Transform  lodT = null;

                        if (lodParentIndex > 0)
                        {
                            lodGO       = new GameObject("LOD" + i);
                            lodT        = lodGO.transform;
                            lodT.parent = lodParent.cellT;
                        }

                        for (int k = 0; k < lod.meshObjectsHolders.Count; ++k)
                        {
                            MeshObjectsHolder sortedMeshes = lod.meshObjectsHolders[k];
                            sortedMeshes.lodParent = lodParent;
                            sortedMeshes.lodLevel  = i;
                            MeshCombineJobManager.instance.AddJob(meshCombiner, sortedMeshes, lodParentIndex > 0 ? lodT : lodParent.cellT, bounds.center);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cellsUsed[i])
                        {
                            cells[i].CombineMeshes(meshCombiner, lodParentIndex);
                        }
                    }
                }
            }