예제 #1
0
    public void TrySaveToCache()
    {
        var sz   = this.mVolumeSource.VolumeSize;
        var path = VolumeBufferFile.CacheFilePath(this.gameObject.name, sz);

        Debug.Log("Saving to cache '" + path + "'");
        if (this.mColorBuffer != null)
        {
            VolumeBufferFile.SaveColorVolToFile(this.mColorBuffer, path);
        }
    }
예제 #2
0
    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);
    }
예제 #3
0
    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!");
    }