Пример #1
0
/*
============
idBox::AddPoint
============
*/
bool idBox::AddPoint( const idVec3& v )
{
	idMat3 axis2;
	idBounds bounds1, bounds2;
	
	if( extents[0] < 0.0f )
	{
		extents.Zero();
		center = v;
		axis.Identity();
		return true;
	}
	
	bounds1[0][0] = bounds1[1][0] = center * axis[0];
	bounds1[0][1] = bounds1[1][1] = center * axis[1];
	bounds1[0][2] = bounds1[1][2] = center * axis[2];
	bounds1[0] -= extents;
	bounds1[1] += extents;
	if( !bounds1.AddPoint( idVec3( v * axis[0], v * axis[1], v * axis[2] ) ) )
	{
		// point is contained in the box
		return false;
	}
	
	axis2[0] = v - center;
	axis2[0].Normalize();
	axis2[1] = axis[ Min3Index( axis2[0] * axis[0], axis2[0] * axis[1], axis2[0] * axis[2] ) ];
	axis2[1] = axis2[1] - ( axis2[1] * axis2[0] ) * axis2[0];
	axis2[1].Normalize();
	axis2[2].Cross( axis2[0], axis2[1] );
	
	AxisProjection( axis2, bounds2 );
	bounds2.AddPoint( idVec3( v * axis2[0], v * axis2[1], v * axis2[2] ) );
	
	// create new box based on the smallest bounds
	if( bounds1.GetVolume() < bounds2.GetVolume() )
	{
		center = ( bounds1[0] + bounds1[1] ) * 0.5f;
		extents = bounds1[1] - center;
		center *= axis;
	}
	else
	{
		center = ( bounds2[0] + bounds2[1] ) * 0.5f;
		extents = bounds2[1] - center;
		center *= axis2;
		axis = axis2;
	}
	return true;
}
Пример #2
0
/*
============
idBox::AddBox
============
*/
bool idBox::AddBox( const idBox &a ) {
	int i, besti;
	float v, bestv;
	idVec3 dir;
	idMat3 ax[4];
	idBounds bounds[4], b;

	if ( a.extents[0] < 0.0f ) {
		return false;
	}

	if ( extents[0] < 0.0f ) {
		center = a.center;
		extents = a.extents;
		axis = a.axis;
		return true;
	}

	// test axis of this box
	ax[0] = axis;
	bounds[0][0][0] = bounds[0][1][0] = center * ax[0][0];
	bounds[0][0][1] = bounds[0][1][1] = center * ax[0][1];
	bounds[0][0][2] = bounds[0][1][2] = center * ax[0][2];
	bounds[0][0] -= extents;
	bounds[0][1] += extents;
	a.AxisProjection( ax[0], b );
	if ( !bounds[0].AddBounds( b ) ) {
		// the other box is contained in this box
		return false;
	}

	// test axis of other box
	ax[1] = a.axis;
	bounds[1][0][0] = bounds[1][1][0] = a.center * ax[1][0];
	bounds[1][0][1] = bounds[1][1][1] = a.center * ax[1][1];
	bounds[1][0][2] = bounds[1][1][2] = a.center * ax[1][2];
	bounds[1][0] -= a.extents;
	bounds[1][1] += a.extents;
	AxisProjection( ax[1], b );
	if ( !bounds[1].AddBounds( b ) ) {
		// this box is contained in the other box
		center = a.center;
		extents = a.extents;
		axis = a.axis;
		return true;
	}

	// test axes aligned with the vector between the box centers and one of the box axis
	dir = a.center - center;
	dir.Normalize();
	for ( i = 2; i < 4; i++ ) {
		ax[i][0] = dir;
		ax[i][1] = ax[i-2][ Min3Index( dir * ax[i-2][0], dir * ax[i-2][1], dir * ax[i-2][2] ) ];
		ax[i][1] = ax[i][1] - ( ax[i][1] * dir ) * dir;
		ax[i][1].Normalize();
		ax[i][2].Cross( dir, ax[i][1] );

		AxisProjection( ax[i], bounds[i] );
		a.AxisProjection( ax[i], b );
		bounds[i].AddBounds( b );
	}

	// get the bounds with the smallest volume
	bestv = idMath::INFINITY;
	besti = 0;
	for ( i = 0; i < 4; i++ ) {
		v = bounds[i].GetVolume();
		if ( v < bestv ) {
			bestv = v;
			besti = i;
		}
	}

	// create a box from the smallest bounds axis pair
	center = ( bounds[besti][0] + bounds[besti][1] ) * 0.5f;
	extents = bounds[besti][1] - center;
	center *= ax[besti];
	axis = ax[besti];

	return false;
}