static protected int RenderersToVolumes(ref Renderer[] renderers, ref Volume cellVolume, ref List <Volume> volumes, ref Dictionary <Scene, int> sceneRefs) { int num = 0; foreach (Renderer r in renderers) { var flags = GameObjectUtility.GetStaticEditorFlags(r.gameObject) & StaticEditorFlags.ContributeGI; bool contributeGI = (flags & StaticEditorFlags.ContributeGI) != 0; if (!r.enabled || !r.gameObject.activeSelf || !contributeGI) { continue; } Volume v = ToVolume(r.bounds); if (ProbeVolumePositioning.OBBIntersect(ref cellVolume, ref v)) { volumes.Add(v); TrackSceneRefs(r.gameObject.scene, ref sceneRefs); num++; } } return(num); }
// 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]); // iterative subdivision while (m_TmpBricks[0].Count > 0) { 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(); } } Profiler.EndSample(); }
internal static bool ShouldKeepBrick(List <Volume> volumes, Volume brick) { foreach (Volume v in volumes) { Volume vol = v; if (ProbeVolumePositioning.OBBIntersect(ref vol, ref brick)) { return(true); } } return(false); }
static protected void CullVolumes(ref List <Volume> cullees, ref List <Volume> cullers, ref List <Volume> result) { foreach (Volume v in cullers) { Volume lv = v; foreach (Volume c in cullees) { if (result.Contains(c)) { continue; } Volume lc = c; if (ProbeVolumePositioning.OBBIntersect(ref lv, ref lc)) { result.Add(c); } } } }
static protected int ProbeVolumesToVolumes(ref ProbeVolume[] probeVolumes, ref Volume cellVolume, ref List <Volume> volumes, ref Dictionary <Scene, int> sceneRefs) { int num = 0; foreach (ProbeVolume pv in probeVolumes) { if (!pv.enabled || !pv.gameObject.activeSelf) { continue; } Volume indicatorVolume = new Volume(Matrix4x4.TRS(pv.transform.position, pv.transform.rotation, pv.GetExtents())); if (ProbeVolumePositioning.OBBIntersect(ref cellVolume, ref indicatorVolume)) { volumes.Add(indicatorVolume); TrackSceneRefs(pv.gameObject.scene, ref sceneRefs); num++; } } return(num); }
public static void SubdivisionAlgorithm(Volume cellVolume, List <Volume> probeVolumes, List <Volume> influenceVolumes, RefTrans refTrans, List <Brick> inBricks, List <Flags> outFlags) { Flags f = new Flags(); for (int i = 0; i < inBricks.Count; i++) { Volume brickVolume = ProbeVolumePositioning.CalculateBrickVolume(ref refTrans, inBricks[i]); // Keep bricks that overlap at least one probe volume, and at least one influencer (mesh) if (ShouldKeepBrick(probeVolumes, brickVolume) && ShouldKeepBrick(influenceVolumes, brickVolume)) { f.subdivide = true; // Transform into refvol space brickVolume.Transform(refTrans.refSpaceToWS.inverse); Volume cellVolumeTrans = new Volume(cellVolume); cellVolumeTrans.Transform(refTrans.refSpaceToWS.inverse); // Discard parent brick if it extends outside of the cell, to prevent duplicates var brickVolumeMax = brickVolume.corner + brickVolume.X + brickVolume.Y + brickVolume.Z; var cellVolumeMax = cellVolumeTrans.corner + cellVolumeTrans.X + cellVolumeTrans.Y + cellVolumeTrans.Z; f.discard = brickVolumeMax.x > cellVolumeMax.x || brickVolumeMax.y > cellVolumeMax.y || brickVolumeMax.z > cellVolumeMax.z || brickVolume.corner.x < cellVolumeTrans.corner.x || brickVolume.corner.y < cellVolumeTrans.corner.y || brickVolume.corner.z < cellVolumeTrans.corner.z; } else { f.discard = true; f.subdivide = false; } outFlags.Add(f); } }