public override void Bake() { if (bakedRenderers == null) { bakedRenderers = new List <Renderer>(); } bakedRenderers.Clear(); AVolumeSettings settings = new AVolumeSettings(bounds, dimensions); //first check if any objects are parented to this object //if anything is found, try to use renderers from those instead of volume overlap if (!GetChildRenderersAndEncapsulate(ref settings, ref bakedRenderers, transform)) { //otherwise try to get renderers intersecting the volume //get mesh renderers within volume if (!GetMeshRenderersIntersectingVolume(settings, transform, ref bakedRenderers)) { //TODO display error? return; } } SDFVolume sdfVolume = AVolume <SDFVolume> .CreateVolume(transform, settings); // sdfVolume.Bake( raySamples, bakedRenderers, BakeComplete ); Debug.Log($"settings: {settings.BoundsLocal} {settings.Dimensions} {settings.CellCount} "); sdfVolume.Dispose(); }
public static T CreateVolume(Transform transform, AVolumeSettings settings) { T v = new T(); v.Initialize(transform, settings); return(v); }
public static void AddBoundsBorder(ref AVolumeSettings settings) { Vector3 extraBound = Vector3.Max(settings.BoundsLocal.size * 0.2f, settings.VoxelSize * 4f); settings.BoundsLocal.Expand(extraBound); //divide current by dimensions-2 so that it gets a voxel size without the borders //Vector3 extraBorderVoxelSize = new Vector3( // settings.BoundsLocal.size.x / Mathf.Max(1,settings.Dimensions.x - 2), // settings.BoundsLocal.size.y / Mathf.Max(1,settings.Dimensions.y - 2), // settings.BoundsLocal.size.z / Mathf.Max(1,settings.Dimensions.z - 2)); // Just testing if we can minimise the extraBorder bounds to not lose a voxel - but not sure it does any good. //if ( !settings.StandardBorder ) //{ // float offset = 0.5f; // extraBorderVoxelSize = new Vector3( offset, offset, offset ) * 0.5f; //} //then add extra voxel size so that bordering voxels are outside original bounds //Bounds newBounds = new Bounds(settings.BoundsLocal.center, settings.BoundsLocal.size + extraBorderVoxelSize * 2f); //Debug.Log( $"AddBoundsBorder Bounds: {newBounds.center} Size: {newBounds.size} Dimensions: {settings.Dimensions} StandardBorder: {settings.StandardBorder}"); //settings = new AVolumeSettings(newBounds, settings.Dimensions, settings.StandardBorder); }
public override void Bake() { if (bakedRenderers == null) { bakedRenderers = new List <Renderer>(); } bakedRenderers.Clear(); AVolumeSettings settings = new AVolumeSettings(bounds, dimensions, useStandardBorder); //first check if any objects are parented to this object //if anything is found, try to use renderers from those instead of volume overlap if (!SDFBaker.GetMeshRenderersInChildren(ref settings, ref bakedRenderers, transform, fitToVertices)) { //otherwise try to get renderers intersecting the volume //get mesh renderers within volume if (!SDFBaker.GetMeshRenderersIntersectingVolume(settings, transform, ref bakedRenderers)) { //TODO display error? return; } } SDFVolume sdfVolume = AVolume <SDFVolume> .CreateVolume(transform, settings); sdfVolume.Bake(raySamples, bakedRenderers, BakeComplete); sdfVolume.Dispose(); }
/// <summary> /// changes bound size automatically /// </summary> public virtual void Encapsulate() { List <Renderer> tempRenderers = new List <Renderer>(); AVolumeSettings settings = new AVolumeSettings(bounds, dimensions); GetChildRenderersAndEncapsulate(ref settings, ref tempRenderers, transform); bounds = settings.BoundsLocal; }
/// <summary> /// changes bound size automatically /// </summary> public virtual void Encapsulate() { List <Renderer> tempRenderers = new List <Renderer>(); AVolumeSettings settings = new AVolumeSettings(bounds, dimensions); GetMeshRenderersInChildren(ref settings, ref tempRenderers, transform, fitToVertices); bounds = settings.BoundsLocal; }
protected virtual void Initialize(Transform transform, AVolumeSettings settings) { _transform = transform; _settings = settings; //always add a bounds border when initializing AVolume AVolumeSettings.AddBoundsBorder(ref settings); }
public virtual void EditorCreateAVolume() { EditorDestroyAVolume(); AVolumeSettings settings = new AVolumeSettings { Bounds = bounds, Dimensions = dimensions }; //create new aVolume = AVolume <T> .CreateVolume(transform, settings); }
public static void AddBoundsBorder(ref AVolumeSettings settings) { //divide current by dimensions-2 so that it gets a voxel size without the borders Vector3 extraBorderVoxelSize = new Vector3( settings.BoundsLocal.size.x / Mathf.Max(1, settings.Dimensions.x - 2), settings.BoundsLocal.size.y / Mathf.Max(1, settings.Dimensions.y - 2), settings.BoundsLocal.size.z / Mathf.Max(1, settings.Dimensions.z - 2)); //then add extra voxel size so that bordering voxels are outside original bounds Bounds newBounds = new Bounds(settings.BoundsLocal.center, settings.BoundsLocal.size + extraBorderVoxelSize * 2f); settings = new AVolumeSettings(newBounds, settings.Dimensions); }
public static bool GetMeshRenderersIntersectingVolume(AVolumeSettings settings, Transform transform, ref List <Renderer> renderers) { if (renderers == null) { return(false); } Renderer[] mrs = FindObjectsOfType <Renderer>(); if (mrs == null || mrs.Length == 0) { return(false); } //shift bounds local to world space position Bounds ws = settings.BoundsLocal; ws.center += transform.position; foreach (var r in mrs) { if (!(r is MeshRenderer) && !(r is SkinnedMeshRenderer)) { continue; } //skip inactive renderers if (!r.gameObject.activeSelf) { continue; } if (!r.enabled) { continue; } if (!ws.Intersects(r.bounds)) { continue; } renderers.Add(r); } if (renderers.Count == 0) { return(false); } return(true); }
/// <summary> /// Gets all Renderers parented to the VolumeBaker & Encapsulates them with the bounds (unless manual bounds is enabled) /// </summary> /// <param name="settings"></param> /// <param name="renderers"></param> /// <param name="target"></param> /// <returns></returns> public bool GetChildRenderersAndEncapsulate(ref AVolumeSettings settings, ref List <Renderer> renderers, Transform target) { if (renderers == null) { return(false); } //get renderers in children Renderer[] mrs = target.GetComponentsInChildren <Renderer>(); if (mrs == null || mrs.Length == 0) { return(false); } Bounds newBounds = useManualBounds ? bounds : new Bounds(target.position, Vector3.zero); bool first = true; foreach (var r in mrs) { if (!(r is MeshRenderer) && !(r is SkinnedMeshRenderer)) { continue; } //skip inactive renderers if (!r.gameObject.activeSelf) { continue; } if (!r.enabled) { continue; } if (!useManualBounds) //do not change bounds if manual bounds specified { if (!fitToVertices) { newBounds.Encapsulate(r.bounds); } else { //iterate all vertices and encapsulate Mesh mesh = null; if (r is MeshRenderer) { MeshFilter mf = r.GetComponent <MeshFilter>(); if (mf != null && mf.sharedMesh != null) { mesh = mf.sharedMesh; } } else { mesh = (r as SkinnedMeshRenderer).sharedMesh; } if (mesh != null) { Bounds b = EncapsulateVertices(mesh, r.transform.localToWorldMatrix); if (first) { newBounds = b; } else { newBounds.Encapsulate(b); } first = false; } } } renderers.Add(r); } if (renderers.Count == 0) { return(false); } Debug.Log($"GetMeshRenderersInChildren newBounds: {newBounds.center} Size: {newBounds.size} Dimensions: {settings.Dimensions}"); //assign new bounds //remove the world offset if (!useManualBounds) { newBounds = new Bounds(newBounds.center - target.position, newBounds.size); } settings = new AVolumeSettings(newBounds, settings.Dimensions) { UsePadding = !useManualBounds //no padding with manual bounds, sorry! }; AVolumeSettings.AddBoundsBorder(ref settings); return(true); }
public static bool GetMeshRenderersInChildren(ref AVolumeSettings settings, ref List <Renderer> renderers, Transform target, bool fitToVertices) { if (renderers == null) { return(false); } //get renderers in children Renderer[] mrs = target.GetComponentsInChildren <Renderer>(); if (mrs == null || mrs.Length == 0) { return(false); } Bounds newBounds = new Bounds(target.position, Vector3.zero); bool first = true; foreach (var r in mrs) { if (!(r is MeshRenderer) && !(r is SkinnedMeshRenderer)) { continue; } //skip inactive renderers if (!r.gameObject.activeSelf) { continue; } if (!r.enabled) { continue; } if (!fitToVertices) { newBounds.Encapsulate(r.bounds); } else { //iterate all vertices and encapsulate Mesh mesh = null; if (r is MeshRenderer) { MeshFilter mf = r.GetComponent <MeshFilter>(); if (mf != null && mf.sharedMesh != null) { mesh = mf.sharedMesh; } } else { mesh = (r as SkinnedMeshRenderer).sharedMesh; } if (mesh != null) { Bounds b = EncapsulateVertices(mesh, r.transform.localToWorldMatrix); if (first) { newBounds = b; } else { newBounds.Encapsulate(b); } first = false; } } renderers.Add(r); } if (renderers.Count == 0) { return(false); } //assign new bounds //remove the world offset newBounds = new Bounds(newBounds.center - target.position, newBounds.size); settings = new AVolumeSettings(newBounds, settings.Dimensions); AVolumeSettings.AddBoundsBorder(ref settings); return(true); }