Пример #1
0
        public ClusterFit(ColourSet colours, SquishFlags flags)
            : base(colours, flags)
        {
            // set the iteration count
            m_iterationCount = ((m_flags & SquishFlags.kColourIterativeClusterFit) != 0) ? kMaxIterations : 1;

            // initialise the best error
            m_besterror = Vector4.one * float.MaxValue;

            // initialise the metric
            bool perceptual = ((m_flags & SquishFlags.kColourMetricPerceptual) != 0);

            if (perceptual)
            {
                m_metric = new Vector4(0.2126f, 0.7152f, 0.0722f, 0.0f);
            }
            else
            {
                m_metric = Vector4.one;
            }

            // cache some values
            int count = m_colours.GetCount();

            Vector3[] values = m_colours.GetPoints();

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

            // compute the principle component
            m_principle = math.ComputePrincipleComponent(covariance);
        }
Пример #2
0
        public RangeFit( ColourSet  colours, SquishFlags flags )
            : base(colours, flags)
        {
            // initialise the metric
            bool perceptual = ( ( m_flags & SquishFlags.kColourMetricPerceptual ) != 0 );
            if( perceptual )
            m_metric = new Vector3( 0.2126f, 0.7152f, 0.0722f );
            else
            m_metric = Vector3.one;

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

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

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

            // compute the principle component
            Vector3 principle = math.ComputePrincipleComponent( covariance );

            // get the min and max range as the codebook endpoints
            Vector3 start = Vector3.zero;
            Vector3 end = Vector3.zero;
            if( count > 0 )
            {
            float min, max;

            // compute the range
            start = end = values[0];
            min = max = Vector3.Dot( values[0], principle );
            for( int i = 1; i < count; ++i )
            {
            float val = Vector3.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 = Vector3.Min( Vector3.one,Vector3.Max( Vector3.zero, start ) );
            end = Vector3.Min( Vector3.one, Vector3.Max( Vector3.zero, end ) );

            // clamp to the grid and save

            Vector3  half = Vector3.one*( 0.5f );
            m_start = Vector3.Scale(math.Truncate( Vector3.Scale(grid,start) + half ),gridrcp);
            m_end = Vector3.Scale(math.Truncate( Vector3.Scale(grid,end) + half ),gridrcp);
        }
        static unsafe void CompressMasked(byte[] rgba, int mask, byte *pBlock, SquishFlags flags)
        {
            // fix any bad flags
            flags = FixFlags(flags);


            // get the block locations
            byte *colourBlock = pBlock;
            byte *alphaBock   = pBlock;

            if ((flags & (SquishFlags.kDxt3 | SquishFlags.kDxt5)) != 0)
            {
                colourBlock = pBlock + 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.kColourRangeFit) != 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.kDxt3) != 0)
            {
                alpha.CompressAlphaDxt3(rgba, mask, alphaBock);
            }
            else if ((flags & SquishFlags.kDxt5) != 0)
            {
                alpha.CompressAlphaDxt5(rgba, mask, alphaBock);
            }
        }
Пример #4
0
 public ColourFit(ColourSet colours, SquishFlags flags)
 {
     m_colours = colours;
     m_flags   = flags;
 }
        public SingleColourFit( ColourSet colours, SquishFlags flags )
            : base(colours, flags)
        {
            // grab the single colour
            Vector3[] values = m_colours.GetPoints();
            m_colour[0] = ( byte )FloatToInt( 255.0f*values[0].x, 255 );
            m_colour[1] = ( byte )FloatToInt( 255.0f*values[0].y, 255 );
            m_colour[2] = ( byte )FloatToInt( 255.0f*values[0].z, 255 );

            // initialise the best error
            m_besterror = int.MaxValue;
        }
Пример #6
0
        public RangeFit(ColourSet colours, SquishFlags flags)
            : base(colours, flags)
        {
            // initialise the metric
            bool perceptual = ((m_flags & SquishFlags.kColourMetricPerceptual) != 0);

            if (perceptual)
            {
                m_metric = new Vector3(0.2126f, 0.7152f, 0.0722f);
            }
            else
            {
                m_metric = Vector3.one;
            }

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

            // cache some values
            int count = m_colours.GetCount();

            Vector3[] values  = m_colours.GetPoints();
            float[]   weights = m_colours.GetWeights();

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

            // compute the principle component
            Vector3 principle = math.ComputePrincipleComponent(covariance);

            // get the min and max range as the codebook endpoints
            Vector3 start = Vector3.zero;
            Vector3 end   = Vector3.zero;

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

                // compute the range
                start = end = values[0];
                min   = max = Vector3.Dot(values[0], principle);
                for (int i = 1; i < count; ++i)
                {
                    float val = Vector3.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 = Vector3.Min(Vector3.one, Vector3.Max(Vector3.zero, start));
            end   = Vector3.Min(Vector3.one, Vector3.Max(Vector3.zero, end));

            // clamp to the grid and save

            Vector3 half = Vector3.one * (0.5f);

            m_start = Vector3.Scale(math.Truncate(Vector3.Scale(grid, start) + half), gridrcp);
            m_end   = Vector3.Scale(math.Truncate(Vector3.Scale(grid, end) + half), gridrcp);
        }
Пример #7
0
        static unsafe void CompressMasked(byte[] rgba, int mask, byte* pBlock, SquishFlags flags)
        {
            // fix any bad flags
            flags = FixFlags(flags);

            // get the block locations
            byte* colourBlock = pBlock;
            byte* alphaBock = pBlock;
            if ((flags & (SquishFlags.kDxt3 | SquishFlags.kDxt5)) != 0)
                colourBlock = pBlock + 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.kColourRangeFit) != 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.kDxt3) != 0)
            {
                alpha.CompressAlphaDxt3(rgba, mask, alphaBock);
            }
            else if ((flags & SquishFlags.kDxt5) != 0)
            {
                alpha.CompressAlphaDxt5(rgba, mask, alphaBock);
            }
        }
Пример #8
0
 public ColourFit(ColourSet colours, SquishFlags flags)
 {
     m_colours = colours;
     m_flags = flags;
 }