Example #1
0
        public ClusterFit(ColourSet colours, SquishFlags flags)
            : base(colours, flags)
        {
            // set the iteration count
            m_iterationCount = ((m_flags & SquishFlags.ColourIterativeClusterFit) != 0) ? kMaxIterations : 1;

            // initialise the best error
            m_besterror = new Vec4(float.MaxValue);

            // initialise the metric
            bool perceptual = ((m_flags & SquishFlags.ColourMetricPerceptual) != 0);
            if (perceptual)
                m_metric = new Vec4(0.2126f, 0.7152f, 0.0722f, 0.0f);
            else
                m_metric = new Vec4(1.0f);

            // cache some values
            int count = m_colours.GetCount();
            Vec3[] values = m_colours.GetPoints();

            // get the covariance matrix
            Sym3x3 covariance = Sym3x3.ComputeWeightedCovariance(count, values, m_colours.GetWeights());
            // compute the principle component
            m_principle = Sym3x3.ComputePrincipleComponent(covariance);
        }
Example #2
0
        public RangeFit(ColourSet colours, SquishFlags flags)
            : base(colours, flags)
        {
            // initialise the metric
            bool perceptual = ((m_flags & SquishFlags.ColourMetricPerceptual) != 0);
            if (perceptual)
                m_metric = new Vec3(0.2126f, 0.7152f, 0.0722f);
            else
                m_metric = new Vec3(1.0f);

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

            // cache some values
            int count = m_colours.GetCount();
            Vec3[] values = m_colours.GetPoints();
            float[] weights = m_colours.GetWeights();

            // 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 = new Vec3(0.0f);
            Vec3 end = new Vec3(0.0f);

            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]
            Vec3 one = new Vec3(1.0f);
            Vec3 zero = new Vec3(0.0f);
            start = Vec3.Min(one, Vec3.Max(zero, start));
            end = Vec3.Min(one, Vec3.Max(zero, end));

            // clamp to the grid and save
            Vec3 grid = new Vec3(31.0f, 63.0f, 31.0f);
            Vec3 gridrcp = new Vec3(1.0f / 31.0f, 1.0f / 63.0f, 1.0f / 31.0f);
            Vec3 half = new Vec3(0.5f);
            m_start = Vec3.Truncate(grid * start + half) * gridrcp;
            m_end = Vec3.Truncate(grid * end + half) * gridrcp;
        }
Example #3
0
        public SingleColourFit(ColourSet colours, SquishFlags flags)
            : base(colours, flags)
        {
            Vec3[] values = m_colours.GetPoints();
            m_colour[0] = (byte)CMath.FloatToInt(255.0f * values[0].X(), 255);
            m_colour[1] = (byte)CMath.FloatToInt(255.0f * values[0].Y(), 255);
            m_colour[2] = (byte)CMath.FloatToInt(255.0f * values[0].Z(), 255);

            // initialise the best error
            m_besterror = int.MaxValue;
        }
Example #4
0
        /// <summary>
        /// Compresses a 4x4 block of pixels.
        /// </summary>
        /// <param name="rgba">The rgba values of the 16 source pixels.</param>
        /// <param name="mask">The valid pixel mask.</param>
        /// <param name="block">Storage for the compressed DXT block.</param>
        /// <param name="flags">Compression flags.</param>
        public static unsafe void CompressMasked(byte* rgba, int mask, byte* block, SquishFlags flags)
        {
            // fix any bad flags
            flags = FixFlags(flags);

            if ((flags & (SquishFlags.BC1 | SquishFlags.BC2 | SquishFlags.BC3 | SquishFlags.BC4 | SquishFlags.BC5)) != 0)
            {
                CompressMaskedBC(rgba, mask, block, flags);
                return;
            }

            // get the block locations
            byte* colourBlock = block;
            byte* alphaBock = block;
            if ((flags & (SquishFlags.Dxt3 | SquishFlags.Dxt5)) != 0)
                colourBlock = block + 8;

            // create the minimal point set
            ColourSet colours = new ColourSet(rgba, mask, flags);

            // check the compression type and compress colour
            if (colours.GetCount() == 1)
            {
                // always do a single colour fit
                SingleColourFit fit = new SingleColourFit(colours, flags);
                fit.Compress(colourBlock);
            }
            else if ((flags & SquishFlags.ColourRangeFit) != 0 || colours.GetCount() == 0)
            {
                // do a range fit
                RangeFit fit = new RangeFit(colours, flags);
                fit.Compress(colourBlock);
            }
            else
            {
                // default to a cluster fit (could be iterative or not)
                ClusterFit fit = new ClusterFit(colours, flags);
                fit.Compress(colourBlock);
            }

            // compress alpha separately if necessary
            if ((flags & SquishFlags.Dxt3) != 0)
                AlphaBlock.CompressAlphaDxt3(rgba, mask, alphaBock);
            else if ((flags & SquishFlags.Dxt5) != 0)
                AlphaBlock.CompressAlphaDxt5(rgba, mask, alphaBock);
        }
Example #5
0
 public ColourFit(ColourSet colours, SquishFlags flags)
 {
     m_colours = colours;
     m_flags = flags;
 }