public bool TryLoadCached() { var sz = this.mVolumeSource.VolumeSize; var path = VolumeBufferFile.CacheFilePath(this.gameObject.name, sz); if (VolumeBufferFile.CacheFileExists(path)) { Debug.Log("Loading from cache '" + path + "'"); this.mColorBuffer = VolumeBufferFile.ReadVolFromFile(sz, path); return(this.mColorBuffer != null); } return(false); }
private IEnumerable <bool> UpdateAura() { Debug.Log("UPDATING AURA."); var m2w = this.transform.localToWorldMatrix; bool debugMe = true; var proj = SpanAPI.spanProjFromCubicDomainAndRange( mColorBuffer.Size.Select(k => SpanAPI.span(0, k - 1)), Cubic <SpanF> .CreateSame(SpanAPI.span(-0.5, 0.5)) ); var invProj = SpanAPI.spanProjFromCubicDomainAndRange( Cubic <SpanF> .CreateSame(SpanAPI.span(-0.5, 0.5)), mColorBuffer.Size.Select(k => SpanAPI.span(0, k - 1)) ); var invProjForMath = SpanAPI.spanProjFromCubicDomainAndRange( Cubic <SpanF> .CreateSame(SpanAPI.span(-0.5, 0.5)), Cubic <SpanF> .CreateSame(SpanAPI.span(-1.0, 1.0)) ); VolumeBuffer <float> distances = null; bool needsDistances = false; bool needsSurface = true; var sz = this.mColorBuffer.Size; var path = VolumeBufferFile.CacheFilePath(this.gameObject.name + "_sdf", sz); var pathOpacity = VolumeBufferFile.CacheFilePath(this.gameObject.name + "_opacity", sz); if ((!this.RefreshDistances) && VolumeBufferFile.CacheFileExists(path)) { distances = VolumeBufferFile.ReadFloatVolFromFile(sz, path); } if ((!this.RefreshDistances) && VolumeBufferFile.CacheFileExists(pathOpacity)) { distances = VolumeBufferFile.ReadFloatVolFromFile(sz, pathOpacity); needsDistances = true; needsSurface = false; } if (distances == null) { distances = new VolumeBuffer <float>(sz); distances.ClearAll(-1.0f); needsDistances = true; } if (needsDistances) { if (needsSurface) { Debug.Log("AURA SURFACES..."); // First see which points are touching: Color defaultVal = Color.clear; for (int i = 0; i < this.mColorBuffer.Length; i++) { var ndx = this.mColorBuffer.UnprojectIndex(i); var mpos = SpanAPI.spanProjCubicInt(proj, ndx); Color curColor = defaultVal; float curDistance = -1.0f; if (this.mColorBuffer.IsEdge(ndx)) { // it's an edge, ignore it } else { var center = mpos.Select(k => (k.From + k.To) * 0.5f).AsVector(); var radius = mpos.Select(k => Mathf.Abs((float)((k.From - k.To) * 0.5f))).Aggregate((a, b) => ((a + b) * 0.5f)); var wcenter = m2w.MultiplyPoint(center); var wradius = m2w.MultiplyVector(Vector3.one * radius).magnitude; if (Physics.CheckSphere(wcenter, wradius)) { //Debug.Log ("Touched something"); curColor = Color.white; curColor.a = 0.2f; curDistance = 0.0f; } } this.mColorBuffer.Write(ndx, curColor); distances.Write(ndx, curDistance); if (((i % 100)) == 99) { this.UpdateTextureFromBuffer(); yield return(false); } } VolumeBufferFile.SaveFloatVolToFile(distances, pathOpacity); } // Now calculate the actual distances: Debug.Log("AURA DISTANCES..."); if (false) { // if this works: VolumeBufferUtil.ConvertOpacityToDistanceBuffer(distances); } else { // this works but is super slow: float maxDist = CubicIntDist(Cubic <int> .CreateSame(0), distances.Size); for (int i = 0; i < this.mColorBuffer.Length; i++) { var ndx = this.mColorBuffer.UnprojectIndex(i); var centerDist = distances.Read(ndx); if (centerDist < 0.0f) { // needs recalc, slowest possible way O(n^6): float closestDistance = -1.0f; for (int j = 0; j < distances.Array.Length; j++) { if (distances.Array[j] == 0.0f) { float dist = CubicIntDist(distances.UnprojectIndex(j), ndx) / maxDist; if ((closestDistance < 0.0f) || (dist < closestDistance)) { closestDistance = dist; } } } distances.Write(ndx, closestDistance); Color testColor = Color.white; testColor.a = closestDistance; this.mColorBuffer.Write(ndx, testColor); if (((i % 100)) == 99) { this.UpdateTextureFromBuffer(); yield return(false); } } } } // Write out the results: VolumeBufferFile.SaveFloatVolToFile(distances, path); } ChakraAuraSettings auraSettings = this.GetComponent <ChakraAuraSettings>(); if (auraSettings.UseChakraAuraDistance) { Debug.Log("AURA-TO-CHAKRA DISTANCES..."); // modify distances based on chakra locality: var allChakras = this.gameObject .GetComponentInParent <ChakraControl>() .AllPoints .Where(k => ((!k.IsAura) && (!k.IsMultiChakras))) .Where(k => (!k.ChakraOneWay)) .Select(k => Matrix4x4.TRS(k.transform.position, k.transform.rotation, Vector3.one).inverse) .ToArray(); Debug.Log("Chakra Count = " + allChakras.Length); for (int li = 0; li < distances.Array.Length; li++) { var ndx = this.mColorBuffer.UnprojectIndex(li); var mpos = SpanAPI.spanProjCubicInt(proj, ndx).Select(k => (k.From + k.To) * 0.5f).AsVector(); var wpos = m2w.MultiplyPoint(mpos); var dist = distances.Array[li]; var origdist = dist; foreach (var c in allChakras) { var lpos = c.MultiplyPoint(wpos); var ldist = Mathf.Sqrt((lpos.x * lpos.x) + (lpos.z * lpos.z)) / (Mathf.Abs(lpos.y) * 1.5f); ldist = 0.5f - (ldist * ldist); if (ldist > dist) { dist = ldist; //(origdist - ldist); } } //if (origdist == dist) dist = 0.0f; // HACK REMOVE distances.Array[li] = dist; if (((li % 100)) == 99) { float pct = ((float)li) / ((float)distances.Array.Length); Debug.Log("Updating aura-chakra distance (" + (pct * 100.0f) + "%)"); yield return(false); } } } // Calculate the colors from the distances: float[] idealDistances = auraSettings.AuraDistances; // { 0.0165f, 0.05f, 0.1f }; Color[] idealColors = auraSettings.AuraColors; // { Color.red, Color.green, new Color(0.0f, 1.0f, 1.0f, 1.0f) }; //float IdealDistance = 0.0165f; //float AuraWidth = 0.0125f; Debug.Log("AURA COLORS..."); float previousDist = 0.0f; for (int i = 0; i < this.mColorBuffer.Length; i++) { var ndx = this.mColorBuffer.UnprojectIndex(i); var dist = distances.Read(ndx); dist = dist * dist; // 1.0f / (dist * dist); Color resColor = Color.clear; for (int layerNdx = idealDistances.Length - 1; layerNdx >= 0; layerNdx--) { var edgeDist = idealDistances[layerNdx] * auraSettings.WholeScaleDistances; if (dist < edgeDist) { var edgeColor = idealColors[layerNdx]; var nextDist = 0.0f; // ((layerNdx > 0) ? (idealDistances[layerNdx - 1] * auraSettings.WholeScaleDistances) : 0.0f); float strength = Mathf.Clamp01(1.0f - (Mathf.Abs(dist - edgeDist) / (edgeDist - nextDist))); Color curColor = edgeColor; curColor.a = curColor.a * strength; resColor = curColor;// Colors_BlendOver(auraSettings, resColor, curColor); } previousDist = edgeDist; } this.mColorBuffer.Write(ndx, resColor); if (((i % 100)) == 99) { Debug.Log("cur = " + dist); this.UpdateTextureFromBuffer(); yield return(false); } while (auraSettings.IsPauseCalculation) { yield return(false); } } this.mColorBuffer.ClearEdges(Color.clear); //return; this.UpdateTextureFromBuffer(); this.TrySaveToCache(); Debug.Log("AURA UPDATED!"); }