示例#1
0
void ClusterFit::SetColourSet( ColourSet const* colours, int flags )
{
	ColourFit::SetColourSet( colours, flags );

	// initialise the best error
#if SQUISH_USE_SIMD
	m_besterror = VEC4_CONST( FLT_MAX );
	Vec3 metric = m_metric.GetVec3();
#else
	m_besterror = FLT_MAX;
	Vec3 metric = m_metric;
#endif

	// cache some values
	int const count = m_colours->GetCount();
	Vec3 const* values = m_colours->GetPoints();
	
	// get the covariance matrix
	Sym3x3 covariance = ComputeWeightedCovariance( count, values, m_colours->GetWeights(), metric );
	
	// compute the principle component
	Vec3 principle = ComputePrincipleComponent( covariance );

	// build the list of values
	float dps[16];
	for( int i = 0; i < count; ++i )
	{
		dps[i] = Dot( values[i], principle );
		m_order[i] = i;
	}
	
	// stable sort
	for( int i = 0; i < count; ++i )
	{
		for( int j = i; j > 0 && dps[j] < dps[j - 1]; --j )
		{
			std::swap( dps[j], dps[j - 1] );
			std::swap( m_order[j], m_order[j - 1] );
		}
	}

	// weight all the points
#if SQUISH_USE_SIMD
	Vec4 const* unweighted = m_colours->GetPointsSimd();
	Vec4 const* weights = m_colours->GetWeightsSimd();
	m_xxsum = VEC4_CONST( 0.0f );
#else
	Vec3 const* unweighted = m_colours->GetPoints();
	float const* weights = m_colours->GetWeights();
	m_xxsum = Vec3( 0.0f );
#endif
	for( int i = 0; i < count; ++i )
	{
		int p = m_order[i];
		m_unweighted[i] = unweighted[p];
		m_weights[i] = weights[p];
		m_weighted[i] = weights[p]*unweighted[p];
		m_xxsum += m_weighted[i]*m_weighted[i];
	}
}
示例#2
0
RangeFit::RangeFit( ColourSet const* colours, int flags, float* metric )
  : ColourFit( colours, flags )
{
    // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f)
    if( metric )
        m_metric = Vec3( metric[0], metric[1], metric[2] );
    else
        m_metric = Vec3( 1.0f );

    // initialise the best error
    m_besterror = FLT_MAX;

    // cache some values
    int const count = m_colours->GetCount();
    Vec3 const* values = m_colours->GetPoints();
    float const* weights = m_colours->GetWeights();

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

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

    // get the min and max range as the codebook endpoints
    Vec3 start( 0.0f );
    Vec3 end( 0.0f );
    if( count > 0 )
    {
        float min, max;

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

    // clamp to the grid and save
    Vec3 const grid( 31.0f, 63.0f, 31.0f );
    Vec3 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f );
    Vec3 const half( 0.5f );
    m_start = Truncate( grid*start + half )*gridrcp;
    m_end = Truncate( grid*end + half )*gridrcp;
}