// TODO: Add subdivision criteria here, // currently just keeps subdividing inside probe volumes internal static bool ShouldKeepBrick(ref RefTrans refTrans, Brick brick) { Renderer[] renderers = Object.FindObjectsOfType <Renderer>(); foreach (Renderer r in renderers) { var flags = GameObjectUtility.GetStaticEditorFlags(r.gameObject) & StaticEditorFlags.ContributeGI; bool contributeGI = (flags & StaticEditorFlags.ContributeGI) != 0; if (!r.enabled || !contributeGI) { continue; } ProbeReferenceVolume.Volume v = new ProbeReferenceVolume.Volume(); v.corner = r.bounds.center - r.bounds.size * 0.5f; v.X = new Vector3(r.bounds.size.x, 0, 0); v.Y = new Vector3(0, r.bounds.size.y, 0); v.Z = new Vector3(0, 0, r.bounds.size.z); if (OBBIntersect(ref refTrans, brick, ref v)) { return(true); } } return(false); }
// TODO: Take refvol translation and rotation into account public static ProbeReferenceVolume.Volume CalculateBrickVolume(ref RefTrans refTrans, Brick brick) { float scaledSize = Mathf.Pow(3, brick.size); Vector3 scaledPos = refTrans.refSpaceToWS.MultiplyPoint(brick.position); ProbeReferenceVolume.Volume bounds; bounds.corner = scaledPos; bounds.X = refTrans.refSpaceToWS.GetColumn(0) * scaledSize; bounds.Y = refTrans.refSpaceToWS.GetColumn(1) * scaledSize; bounds.Z = refTrans.refSpaceToWS.GetColumn(2) * scaledSize; return(bounds); }
// TODO: Take refvol translation and rotation into account public static ProbeReferenceVolume.Volume CalculateBrickVolume(ref RefTrans refTrans, Brick brick) { float scaledSize = Mathf.Pow(3, brick.subdivisionLevel); Vector3 scaledPos = refTrans.refSpaceToWS.MultiplyPoint(brick.position); var bounds = new ProbeReferenceVolume.Volume( scaledPos, refTrans.refSpaceToWS.GetColumn(0) * scaledSize, refTrans.refSpaceToWS.GetColumn(1) * scaledSize, refTrans.refSpaceToWS.GetColumn(2) * scaledSize ); return(bounds); }
public static void SubdivisionAlgorithm(RefTrans refTrans, List <Brick> inBricks, List <Flags> outFlags) { Flags f = new Flags(); for (int i = 0; i < inBricks.Count; i++) { if (ShouldKeepBrick(ref refTrans, inBricks[i])) { f.discard = false; f.subdivide = true; } else { f.discard = true; f.subdivide = false; } outFlags.Add(f); } }
public static bool OBBIntersect(ref RefTrans refTrans, Brick brick, ref ProbeReferenceVolume.Volume volume) { var transformed = CalculateBrickVolume(ref refTrans, brick); return(OBBIntersect(ref transformed, ref volume)); }
public static void SubdivisionAlgorithm(ProbeReferenceVolume.Volume cellVolume, List <ProbeReferenceVolume.Volume> probeVolumes, List <ProbeReferenceVolume.Volume> influenceVolumes, RefTrans refTrans, List <Brick> inBricks, int subdivisionLevel, List <Flags> outFlags) { Flags f = new Flags(); for (int i = 0; i < inBricks.Count; i++) { ProbeReferenceVolume.Volume brickVolume = ProbeVolumePositioning.CalculateBrickVolume(ref refTrans, inBricks[i]); // Find the local max from all overlapping probe volumes: float localMaxSubdiv = 0; float localMinSubdiv = 0; bool overlap = false; foreach (ProbeReferenceVolume.Volume v in probeVolumes) { ProbeReferenceVolume.Volume vol = v; if (ProbeVolumePositioning.OBBIntersect(ref vol, ref brickVolume)) { overlap = true; localMaxSubdiv = Mathf.Max(localMaxSubdiv, vol.maxSubdivisionMultiplier); // Do we use max for min subdiv too? localMinSubdiv = Mathf.Max(localMinSubdiv, vol.minSubdivisionMultiplier); } } bool belowMaxSubdiv = subdivisionLevel <= ProbeReferenceVolume.instance.GetMaxSubdivision(localMaxSubdiv); bool belowMinSubdiv = subdivisionLevel <= ProbeReferenceVolume.instance.GetMaxSubdivision(localMinSubdiv); // Keep bricks that overlap at least one probe volume, and at least one influencer (mesh) if ((belowMinSubdiv && overlap) || (belowMaxSubdiv && ShouldKeepBrick(probeVolumes, brickVolume) && ShouldKeepBrick(influenceVolumes, brickVolume))) { f.subdivide = true; // Transform into refvol space brickVolume.Transform(refTrans.refSpaceToWS.inverse); ProbeReferenceVolume.Volume cellVolumeTrans = new ProbeReferenceVolume.Volume(cellVolume); cellVolumeTrans.Transform(refTrans.refSpaceToWS.inverse); cellVolumeTrans.maxSubdivisionMultiplier = localMaxSubdiv; // 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); } }
public static void SubdivisionAlgorithm(ProbeReferenceVolume.Volume cellVolume, List <ProbeReferenceVolume.Volume> probeVolumes, List <ProbeReferenceVolume.Volume> influenceVolumes, RefTrans refTrans, List <Brick> inBricks, List <Flags> outFlags) { Flags f = new Flags(); for (int i = 0; i < inBricks.Count; i++) { ProbeReferenceVolume.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); ProbeReferenceVolume.Volume cellVolumeTrans = new ProbeReferenceVolume.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); } }