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); } } } } //===============================================================================================================================
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); } }
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); } } } }
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); }
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); } } }
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); } }
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); } }
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); } } } }
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); } } } }
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); } } } }
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); } } } }
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(); } } } }
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); } } } }
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); } } } }
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); } } } }