// converts a volume into bricks, subdivides the bricks and culls subdivided volumes falling outside the original volume private void ConvertVolume(Volume volume, SubdivisionDel subdivider, List <Brick> outSortedBricks) { Profiler.BeginSample("ConvertVolume"); m_TmpBricks[0].Clear(); Transform(volume, out Volume vol); // rasterize bricks according to the coarsest grid Rasterize(vol, m_TmpBricks[0]); int subDivCount = 0; // iterative subdivision while (m_TmpBricks[0].Count > 0 && subDivCount < m_MaxSubdivision) { m_TmpBricks[1].Clear(); m_TmpFlags.Clear(); m_TmpFlags.Capacity = Mathf.Max(m_TmpFlags.Capacity, m_TmpBricks[0].Count); Profiler.BeginSample("Subdivider"); subdivider(m_Transform, m_TmpBricks[0], m_TmpFlags); Profiler.EndSample(); Debug.Assert(m_TmpBricks[0].Count == m_TmpFlags.Count); for (int i = 0; i < m_TmpFlags.Count; i++) { if (!m_TmpFlags[i].discard) { outSortedBricks.Add(m_TmpBricks[0][i]); } if (m_TmpFlags[i].subdivide) { m_TmpBricks[1].Add(m_TmpBricks[0][i]); } } m_TmpBricks[0].Clear(); if (m_TmpBricks[1].Count > 0) { //Debug.Log("Calling SubdivideBricks with " + m_TmpBricks[1].Count + " bricks."); SubdivideBricks(m_TmpBricks[1], m_TmpBricks[0]); // Cull out of bounds bricks Profiler.BeginSample("Cull bricks"); for (int i = m_TmpBricks[0].Count - 1; i >= 0; i--) { if (!ProbeVolumePositioning.OBBIntersect(ref m_Transform, m_TmpBricks[0][i], ref volume)) { m_TmpBricks[0].RemoveAt(i); } } Profiler.EndSample(); } subDivCount++; } Profiler.EndSample(); }
internal void CreateBricks(List <Volume> volumes, SubdivisionDel subdivider, List <Brick> outSortedBricks, out int positionArraySize) { Profiler.BeginSample("CreateBricks"); // generate bricks for all areas covered by the passed in volumes, potentially subdividing them based on the subdivider's decisions foreach (var v in volumes) { ConvertVolume(v, subdivider, outSortedBricks); } Profiler.BeginSample("sort"); // sort from larger to smaller bricks outSortedBricks.Sort((Brick lhs, Brick rhs) => { if (lhs.size != rhs.size) { return(lhs.size > rhs.size ? -1 : 1); } if (lhs.position.z != rhs.position.z) { return(lhs.position.z < rhs.position.z ? -1 : 1); } if (lhs.position.y != rhs.position.y) { return(lhs.position.y < rhs.position.y ? -1 : 1); } if (lhs.position.x != rhs.position.x) { return(lhs.position.x < rhs.position.x ? -1 : 1); } return(0); }); Profiler.EndSample(); // communicate the required array size for storing positions to the caller positionArraySize = outSortedBricks.Count * ProbeBrickPool.kBrickProbeCountTotal; Profiler.EndSample(); }