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); }
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); } }
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; }
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); } }