示例#1
0
        /// <summary>
        /// GetPartition() takes a connected graph (in the form of a dataset or lightweight graph),
        /// and returns a partitioning of the graph created from applying the resilience measure.
        /// The minimum number of clusters in the partitioning is given by the instance variable _minK.
        /// </summary>
        /// <returns>A partition of the instance graph</returns>
        public Partition GetPartition()
        {
            DistanceMatrix mat = null;

            if (_data.Type == AbstractDataset.DataType.DistanceMatrix)
            {
                mat = (DistanceMatrix)_data;
            }
            else if (_data.Type == AbstractDataset.DataType.PointSet)
            {
                mat = ((PointSet)_data).GetDistanceMatrix();
            }

            //Setup our partition with a single cluster, with all points
            List <Cluster> clusterList = new List <Cluster> {
                new Cluster(0, Enumerable.Range(0, _data.Count).ToList())
            };
            Partition partition = new Partition(clusterList, _data);

            //Dictionary to hold VAT
            var vatMap = new Dictionary <int, Scattering>();

            //Dictionary to hold subset array
            var subsetMap = new Dictionary <int, int[]>();

            while (clusterList.Count < _minK)
            {
                //Calculate the VAT for all values
                foreach (var c in partition.Clusters.Where(c => !vatMap.ContainsKey(c.ClusterId)))
                {
                    //We must calculate a graph for this subset of data
                    List <int> clusterSubset = c.Points.Select(p => p.Id).ToList();

                    //Now calculate Vat
                    LightWeightGraph lwg;
                    if (_data.Type == AbstractDataset.DataType.Graph)
                    {
                        bool[] exclusion = new bool[_data.Count];
                        for (int i = 0; i < _data.Count; i++)
                        {
                            exclusion[i] = true;
                        }
                        foreach (var p in c.Points)
                        {
                            exclusion[p.Id] = false;
                        }
                        lwg = new LightWeightGraph((LightWeightGraph)_data, exclusion);
                    }
                    else //Distance matrix or Pointset
                    {
                        Debug.Assert(mat != null, "mat != null");
                        var subMatrix = mat.GetReducedDataSet(clusterSubset);

                        //Generate our graph
                        lwg = _graphGen.GenerateGraph(subMatrix.Mat);
                    }

                    subsetMap.Add(c.ClusterId, clusterSubset.ToArray());
                    lwg.IsWeighted = _weighted;
                    Scattering v = new Scattering(lwg, _reassignNodes, _alpha, _beta);
                    _vatNodeRemovalOrder = v.NodeRemovalOrder;
                    _vatNumNodesRemoved  = v.NumNodesRemoved;
                    if (_hillClimb)
                    {
                        v.HillClimb();
                    }
                    ////VATClust v = new VATClust(subMatrix.Mat, _weighted, _useKnn, _kNNOffset, _alpha, _beta);
                    vatMap.Add(c.ClusterId, v);
                }

                meta.AppendLine("All calculated Scatterings:");
                //Now find the minimum vat value
                int    minVatCluster = 0;
                double minVatValue   = double.MaxValue;
                foreach (var c in vatMap)
                {
                    meta.Append(String.Format("{0} ", c.Value.MinVat));
                    if (c.Value.MinVat < minVatValue)
                    {
                        minVatCluster = c.Key;
                        minVatValue   = c.Value.MinVat;
                    }
                }
                meta.AppendLine();

                //now merge the partition into the cluster
                var minVAT       = vatMap[minVatCluster];
                var subPartition = minVAT.GetPartition();
                var nodeIndexMap = subsetMap[minVatCluster];

                meta.AppendFormat("Scattering: MinScattering={0}\r\n", minVAT.MinVat);
                meta.AppendFormat("Removed Count:{0} \r\n", minVAT.NumNodesRemoved);
                meta.AppendLine(String.Join(",",
                                            minVAT.NodeRemovalOrder.GetRange(0, minVAT.NumNodesRemoved).Select(c => nodeIndexMap[c])));

                partition.MergeSubPartition(subPartition, nodeIndexMap, minVatCluster);
                vatMap.Remove(minVatCluster);
                subsetMap.Remove(minVatCluster);
            }
            partition.MetaData = meta.ToString();
            return(partition);
        }
示例#2
0
    public override void Inject(Scattering scattering, ComputeShader compute, Matrix4x4 viewProj)
    {
        if (HasShadow)
        {
            if (GetShadowMapResolution() != m_shadowMap.width)
            {
                DestroyImmediate(m_shadowMap);
                CreateShadowTex();
            }
        }

        //TODO: This doesn't really need to run every frame
        UpdateCommandBuffer();

        //Setup basic params
        Vector4 posRange = transform.position;

        posRange.w = 1.0f / (m_light.range * m_light.range);
        compute.SetVector("_LightPosRange", posRange);

        Vector4 lightStrength = m_light.color * m_light.intensity * FogScatterIntensity;

        lightStrength *= 10;
        compute.SetVector("_LightColor", lightStrength);

        //Per light type things
        switch (LightType)
        {
        case LightType.Directional:
            int dirKernel;

            if (HasShadow)
            {
                if (QualitySettings.shadowCascades > 1)
                {
                    dirKernel = scattering.LightDirKernel.GetKernel(ScatterKernel.EShadowMode.Cascaded);
                }
                else
                {
                    dirKernel = scattering.LightDirKernel.GetKernel(ScatterKernel.EShadowMode.Shadowed);
                }
            }
            else
            {
                dirKernel = scattering.LightDirKernel.GetKernel(ScatterKernel.EShadowMode.None);
            }

            compute.SetVector("_LightPosRange", m_light.transform.forward);

            if (HasShadow)
            {
                compute.SetBuffer(dirKernel, "_MatrixBuf", MatrixBuffer);
                compute.SetTexture(dirKernel, "_ShadowMapTexture", m_shadowMap);
            }
            else
            {
                compute.SetTexture(dirKernel, "_ShadowMapTexture", Texture2D.whiteTexture);
            }

            scattering.SetLightAccum(dirKernel, false);

            Profiler.BeginSample("Dir Light pass");
            var tex = scattering.GetDensityTex();
            compute.DispatchScaled(dirKernel, tex.width, tex.height, tex.volumeDepth);
            Profiler.EndSample();
            break;

        case LightType.Point:
            scattering.SetLightAccum(scattering.LightPointKernel, false);
            scattering.InjectObject(viewProj, scattering.LightPointKernel, this);
            break;

        case LightType.Spot:
            int spotKernel =
                scattering.LightSpotKernel.GetKernel(HasShadow ? ScatterKernel.EShadowMode.Shadowed : ScatterKernel.EShadowMode.None);

            if (HasShadow)
            {
                Matrix4x4 v = transform.worldToLocalMatrix;
                Matrix4x4 p =
                    GL.GetGPUProjectionMatrix(Matrix4x4.Perspective(m_light.spotAngle, 1.0f,
                                                                    m_light.shadowNearPlane,
                                                                    m_light.range), true);

                //For some reason z is flipped :(
                p *= Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f));

                compute.SetMatrix("_SpotShadowMatrix", p * v);
                compute.SetTexture(spotKernel, "_SpotShadow", m_shadowMap);
            }

            var   lightProjMatrix = Matrix4x4.identity;
            float d = Mathf.Deg2Rad * m_light.spotAngle * 0.5f;
            d = Mathf.Cos(d) / Mathf.Sin(d);
            lightProjMatrix[3, 2] = 2f / d;
            lightProjMatrix[3, 3] = SpotBaseSize;
            var mat = lightProjMatrix * transform.worldToLocalMatrix;
            compute.SetMatrix("_SpotMatrix", mat);
            if (m_light.cookie != null)
            {
                compute.SetTexture(spotKernel, "_SpotCookie", m_light.cookie);
            }
            else
            {
                compute.SetTexture(spotKernel, "_SpotCookie", scattering.SpotCookie);
            }

            scattering.SetLightAccum(spotKernel, false);
            scattering.InjectObject(viewProj, spotKernel, this);
            break;
        }
    }
示例#3
0
 public abstract void Inject(Scattering scat, ComputeShader comp, Matrix4x4 viewProj);