예제 #1
0
void CImagePacker::GetMinimumDimensions( int *pReturnWidth, int *pReturnHeight )
{
	*pReturnWidth = CeilPow2( m_MaxLightmapWidth );
	*pReturnHeight = CeilPow2( m_MinimumHeight );

	int aspect = *pReturnWidth / *pReturnHeight;
	if (aspect > HardwareConfig()->MaxTextureAspectRatio())
	{
		*pReturnHeight = *pReturnWidth / HardwareConfig()->MaxTextureAspectRatio(); 
	}
}
예제 #2
0
static void MXMLBufferAppend(MXMLBuffer * a_buffer, const char* a_string, int a_stringLength = 0)
{
  unsigned int maxLength;
  char * buffer;

  if( !a_stringLength )
  {
    a_stringLength = (unsigned int)strlen(a_string);
  }

  // Grow buffer by power of 2 if required
  unsigned int requiredSize = (unsigned int)(a_buffer->m_bufferSize + a_stringLength);
  if(requiredSize >= a_buffer->m_maxBufferSize)
  {
    if(requiredSize < MXML_BUFFER_INITIAL_SIZE)
    {
      maxLength = MXML_BUFFER_INITIAL_SIZE;
    }
    else
    {
      maxLength = CeilPow2(requiredSize);
    }
    
    buffer = (char*)a_buffer->m_Alloc(maxLength, a_buffer->m_memContext);
    memcpy(buffer, a_buffer->m_buffer, a_buffer->m_bufferSize);
    if( a_buffer->m_buffer )
    {
      a_buffer->m_Free(a_buffer->m_buffer, a_buffer->m_memContext);
    }
    a_buffer->m_buffer = buffer;
    a_buffer->m_maxBufferSize = maxLength;
  }

  // Add characters
  memcpy(a_buffer->m_buffer + a_buffer->m_bufferSize, a_string, a_stringLength);
  a_buffer->m_bufferSize += a_stringLength;
}
예제 #3
0
float CImagePacker::GetEfficiency( void )
{
	return ( float )m_AreaUsed / ( float )( m_MaxLightmapWidth * CeilPow2( m_MinimumHeight ) );
}
예제 #4
0
static double ApproxEarthMoversMetric(
	vector<double>	&dd,
	int				wi,
	int				hi )
{
// find powers of 2 that are big enough

	int	w = CeilPow2( wi ),
		h = CeilPow2( hi );

	vector<double>	d( w*h, 0.0 );

	CopyRaster( &d[0], w, &dd[0], wi, wi, hi );

	UnnormHaarTf2D( d, w, h );

//	PrintVectorAsMat( stdout, d, 8 );

	vector<int>	cdist( w, 1 );
	vector<int>	rdist( h, 1 );
	int			mask;

	mask = w >> 1;  // only works for w = 2^n

	for( int x = 1; x < w; ++x ) {

		for( int tmp = x; !(tmp & mask); tmp <<= 1 )
			cdist[x] <<= 1;
	}

	mask = h >> 1;  // only works for h = 2^n

	for( int y = 1; y < h; ++y ) {

		for( int tmp = y; !(tmp & mask); tmp <<= 1 )
			rdist[y] <<= 1;
	}

// use of 1 as lower bound is right;
// do not care about sums, only differences

	double	approx = 0.0;  // approximate Earth Mover's metric

	for( int x = 1; x < w; ++x ) {

		for( int y = 1; y < h; ++y ) {

			int		dx		= cdist[x];
			int		dy		= rdist[y];
			double	dist	= min( dx, dy );

			if( dist < 0 ) {

				printf(
				"x %d, y %d, dx %d, dy %d, dist %f, d[x+w*y] %f\n",
				x, y, dx, dy, dist, d[x + w*y] );
			}

			approx += dist * abs( d[x + w*y] );
		}
	}

// this should never happen

	if( approx < 0 ) {

		printf(
		"##Negative metric?  wi=%d, hi=%d"
		"\nColumn dists: ", wi, hi );

		for( int x = 1; x < w; ++x )
			printf( "%d ", cdist[x] );

		printf( "\nRow dists: " );

		for( int y = 1; y < h; ++y )
			printf( "%d ", rdist[y] );

		printf( "\n" );

		exit( 42 );
	}

// Normalize:
// - divide by 2 deltas per move unit.
// - divide by N pixels (per pixel cost).
// - divide by Poisson noise on area N.

	int		N = wi * hi;

	approx /= 2.0 * N * sqrt( N );

	printf(
	"Approximate EM metric %f for %d points.\n",
	approx, N );

	return approx;
}
예제 #5
0
// For the input (pts) region and value lists {av, bv):
// - Return images {i1, i2, diff} (and dims Nx, Ny).
// - Optionally write image files.
//
static void MakeMetricImagesFFT(
	vector<double>			&i1,
	vector<double>			&i2,
	vector<double>			&diff,
	int						&Nx,
	int						&Ny,
	const vector<Point>		&pts,
	const vector<double>	&av,
	const vector<double>	&bv,
	bool					write_images,
	const char				*msg,
	FILE*					flog )
{
/* ---------- */
/* Initialize */
/* ---------- */

	i1.clear();
	i2.clear();
	diff.clear();
	Nx	= 0;
	Ny	= 0;

/* -------------------- */
/* Set image dimensions */
/* -------------------- */

	IBox	B;

	BBoxFromPoints( B, pts );

	Nx = CeilPow2( B.R - B.L + 1 );
	Ny = CeilPow2( B.T - B.B + 1 );

	int	N2 = Nx * Ny;

	fprintf( flog,
	"MetricImages: Range x %d %d, y %d %d, use Nx=%d, Ny=%d\n",
	B.L, B.R, B.B, B.T, Nx, Ny );

/* ----------- */
/* Fill images */
/* ----------- */

	i1.resize( N2, 0.0 );
	i2.resize( N2, 0.0 );
	diff.resize( N2 );

	int	np = pts.size();

	for( int i = 0; i < np; ++i ) {

		double	x = pts[i].x - B.L,
				y = pts[i].y - B.B;

		DistributePixel( x, y, av[i], i1, Nx, Ny );
		DistributePixel( x, y, bv[i], i2, Nx, Ny );
	}

	for( int i = 0; i < N2; ++i )
		diff[i] = i1[i] - i2[i];

/* ------------ */
/* Write images */
/* ------------ */

	if( write_images ) {

		char	fname[32];

		sprintf( fname, "fft%d-a.tif", FFTFileIdx );
		VectorDblToTif8( fname, i1, Nx, Ny );

		sprintf( fname, "fft%d-b.tif", FFTFileIdx );
		VectorDblToTif8( fname, i2, Nx, Ny );

		sprintf( fname, "fft%d-d.tif", FFTFileIdx );
		VectorDblToTif8( fname, diff, Nx, Ny );

		++FFTFileIdx;

		double	e1 = 0.0, e2 = 0.0, ed = 0.0;

		for( int i = 0; i < N2; ++i ) {

			e1 += i1[i]*i1[i];
			e2 += i2[i]*i2[i];
			ed += diff[i]*diff[i];
		}

		fprintf( flog,
		"MetricImages: Energies (1,2,dif) %f %f %f\n",
		e1, e2, ed );
	}
}