Esempio n. 1
0
        public static Sym3x3 ComputeWeightedCovariance(int n, Vec3[] points, float[] weights, Vec3 metric)
        {
            // compute the centroid
            float total    = 0.0f;
            var   centroid = Vec3.Zero;

            for (int i = 0; i < n; ++i)
            {
                total    += weights[i];
                centroid += weights[i] * points[i];
            }
            centroid /= total;

            // accumulate the covariance matrix
            var covariance = new Sym3x3(0.0f);

            for (int i = 0; i < n; ++i)
            {
                var a = (points[i] - centroid) * metric;
                var b = weights[i] * a;

                covariance[0] += a.X * b.X;
                covariance[1] += a.X * b.Y;
                covariance[2] += a.X * b.Z;
                covariance[3] += a.Y * b.Y;
                covariance[4] += a.Y * b.Z;
                covariance[5] += a.Z * b.Z;
            }

            // return it
            return(covariance);
        }
Esempio n. 2
0
        public RangeFit(ColourSet colours, CompressionOptions flags) : base(colours)
        {
            // initialise the metric
            bool perceptual = ((flags & CompressionOptions.ColourMetricPerceptual) != 0);

            m_metric = perceptual ? new Vec3(0.2126f, 0.7152f, 0.0722f) : Vec3.One;

            // initialise the best error
            m_besterror = float.MaxValue;

            // cache some values
            var count   = m_colours.Count;
            var values  = m_colours.Points;
            var weights = m_colours.Weights;

            // get the covariance matrix
            Sym3x3 covariance = Sym3x3.ComputeWeightedCovariance(count, values, weights);

            // compute the principle component
            Vec3 principle = Sym3x3.ComputePrincipleComponent(covariance);

            // get the min and max range as the codebook endpoints
            Vec3 start = Vec3.Zero;
            Vec3 end   = Vec3.Zero;

            if (count > 0)
            {
                float min, max;

                // compute the range
                start = end = values[0];
                min   = max = Vec3.Dot(values[0], principle);
                for (int i = 1; i < count; ++i)
                {
                    float val = Vec3.Dot(values[i], principle);
                    if (val < min)
                    {
                        start = values[i];
                        min   = val;
                    }
                    else if (val > max)
                    {
                        end = values[i];
                        max = val;
                    }
                }
            }

            // clamp the output to [0, 1]
            start = start.Clamp(Vec3.Zero, Vec3.One);
            end   = end.Clamp(Vec3.Zero, Vec3.One);

            // clamp to the grid and save
            m_start = (GRID * start + HALF).Truncate() * GRIDRCP;
            m_end   = (GRID * end + HALF).Truncate() * GRIDRCP;
        }
Esempio n. 3
0
        public ClusterFitAlt(ColourSet colours, CompressionOptions flags) : base(colours)
        {
            // initialise the metric
            bool perceptual = ((flags & CompressionOptions.ColourMetricPerceptual) != 0);

            m_metric    = perceptual ? new Vec4(0.2126f, 0.7152f, 0.0722f, 1) : Vec4.One;
            m_metricSqr = m_metric * m_metric;

            // get the covariance matrix
            var covariance = Sym3x3.ComputeWeightedCovariance(m_colours.Count, m_colours.Points, m_colours.Weights, m_metric.GetVec3());

            // compute the principle component
            m_principle = Sym3x3.ComputePrincipleComponent(covariance);
        }
Esempio n. 4
0
        public ClusterFit(ColourSet colours, CompressionOptions flags) : base(colours)
        {
            // set the iteration count
            m_iterationCount = (flags & CompressionOptions.ColourIterativeClusterFit) != 0 ? MAXITERATIONS : 1;

            // initialise the metric
            bool perceptual = ((flags & CompressionOptions.ColourMetricPerceptual) != 0);

            m_metric = perceptual ? PERCEPTUAL : Vec4.One;

            // get the covariance matrix
            var covariance = Sym3x3.ComputeWeightedCovariance(m_colours.Count, m_colours.Points, m_colours.Weights);

            // compute the principle component
            m_principle = Sym3x3.ComputePrincipleComponent(covariance);
        }
        public ClusterFit(ColourSet colours, CompressionOptions flags) : base(colours)
        {
            // set the iteration count
            m_iterationCount = (flags & CompressionOptions.ColourIterativeClusterFit) != 0 ? MAXITERATIONS : 1;

            // initialise the metric
            bool perceptual = ((flags & CompressionOptions.ColourMetricPerceptual) != 0);

            m_metric = perceptual ? new Vec4(0.2126f, 0.7152f, 0.0722f, 0.0f) : Vec4.One;

            // cache some values
            var count  = m_colours.Count;
            var values = m_colours.Points;

            // get the covariance matrix
            Sym3x3 covariance = Sym3x3.ComputeWeightedCovariance(count, values, m_colours.Weights);

            // compute the principle component
            m_principle = Sym3x3.ComputePrincipleComponent(covariance);
        }
Esempio n. 6
0
        public static Vec3 ComputePrincipleComponent(Sym3x3 matrix)
        {
            Vec4 row0 = new Vec4(matrix[0], matrix[1], matrix[2], 0.0f);
            Vec4 row1 = new Vec4(matrix[1], matrix[3], matrix[4], 0.0f);
            Vec4 row2 = new Vec4(matrix[2], matrix[4], matrix[5], 0.0f);
            Vec4 v    = new Vec4(1.0f);

            for (int i = 0; i < 8; ++i)
            {
                // matrix multiply
                Vec4 w = row0 * v.SplatX();
                w = row1.MultiplyAdd(v.SplatY(), w);
                w = row2.MultiplyAdd(v.SplatZ(), w);

                // get max component from xyz in all channels
                Vec4 a = Vec4.Max(w.SplatX(), Vec4.Max(w.SplatY(), w.SplatZ()));

                // divide through and advance
                v = w * a.Reciprocal();
            }

            return(v.GetVec3());
        }