void idCollisionModelManagerLocal::DebugOutput( const idVec3& origin )
{
	int i, k, t;
	char buf[128];
	idVec3 end;
	idAngles boxAngles;
	idMat3 modelAxis, boxAxis;
	idBounds bounds;
	trace_t trace;
	
	if( !cm_testCollision.GetBool() )
	{
		return;
	}
	
	testend = ( idVec3* ) Mem_Alloc( cm_testTimes.GetInteger() * sizeof( idVec3 ), TAG_COLLISION );
	
	if( cm_testReset.GetBool() || ( cm_testWalk.GetBool() && !start.Compare( start ) ) )
	{
		total_translation = total_rotation = 0;
		min_translation = min_rotation = 999999;
		max_translation = max_rotation = -999999;
		num_translation = num_rotation = 0;
		cm_testReset.SetBool( false );
	}
	
	if( cm_testWalk.GetBool() )
	{
		start = origin;
		cm_testOrigin.SetString( va( "%1.2f %1.2f %1.2f", start[0], start[1], start[2] ) );
	}
	else
	{
		sscanf( cm_testOrigin.GetString(), "%f %f %f", &start[0], &start[1], &start[2] );
	}
	
	sscanf( cm_testBox.GetString(), "%f %f %f %f %f %f", &bounds[0][0], &bounds[0][1], &bounds[0][2],
			&bounds[1][0], &bounds[1][1], &bounds[1][2] );
	sscanf( cm_testBoxRotation.GetString(), "%f %f %f", &boxAngles[0], &boxAngles[1], &boxAngles[2] );
	boxAxis = boxAngles.ToMat3();
	modelAxis.Identity();
	
	idTraceModel itm( bounds );
	idRandom random( 0 );
	idTimer timer;
	
	if( cm_testRandomMany.GetBool() )
	{
		// if many traces in one random direction
		for( i = 0; i < 3; i++ )
		{
			testend[0][i] = start[i] + random.CRandomFloat() * cm_testLength.GetFloat();
		}
		for( k = 1; k < cm_testTimes.GetInteger(); k++ )
		{
			testend[k] = testend[0];
		}
	}
	else
	{
		// many traces each in a different random direction
		for( k = 0; k < cm_testTimes.GetInteger(); k++ )
		{
			for( i = 0; i < 3; i++ )
			{
				testend[k][i] = start[i] + random.CRandomFloat() * cm_testLength.GetFloat();
			}
		}
	}
	
	// translational collision detection
	timer.Clear();
	timer.Start();
	for( i = 0; i < cm_testTimes.GetInteger(); i++ )
	{
		Translation( &trace, start, testend[i], &itm, boxAxis, CONTENTS_SOLID | CONTENTS_PLAYERCLIP, cm_testModel.GetInteger(), vec3_origin, modelAxis );
	}
	timer.Stop();
	t = timer.Milliseconds();
	if( t < min_translation ) min_translation = t;
	if( t > max_translation ) max_translation = t;
	num_translation++;
	total_translation += t;
	if( cm_testTimes.GetInteger() > 9999 )
	{
		sprintf( buf, "%3dK", ( int )( cm_testTimes.GetInteger() / 1000 ) );
	}
	else
	{
		sprintf( buf, "%4d", cm_testTimes.GetInteger() );
	}
	common->Printf( "%s translations: %4d milliseconds, (min = %d, max = %d, av = %1.1f)\n", buf, t, min_translation, max_translation, ( float ) total_translation / num_translation );
	
	if( cm_testRandomMany.GetBool() )
	{
		// if many traces in one random direction
		for( i = 0; i < 3; i++ )
		{
			testend[0][i] = start[i] + random.CRandomFloat() * cm_testRadius.GetFloat();
		}
		for( k = 1; k < cm_testTimes.GetInteger(); k++ )
		{
			testend[k] = testend[0];
		}
	}
	else
	{
		// many traces each in a different random direction
		for( k = 0; k < cm_testTimes.GetInteger(); k++ )
		{
			for( i = 0; i < 3; i++ )
			{
				testend[k][i] = start[i] + random.CRandomFloat() * cm_testRadius.GetFloat();
			}
		}
	}
	
	if( cm_testRotation.GetBool() )
	{
		// rotational collision detection
		idVec3 vec( random.CRandomFloat(), random.CRandomFloat(), random.RandomFloat() );
		vec.Normalize();
		idRotation rotation( vec3_origin, vec, cm_testAngle.GetFloat() );
		
		timer.Clear();
		timer.Start();
		for( i = 0; i < cm_testTimes.GetInteger(); i++ )
		{
			rotation.SetOrigin( testend[i] );
			Rotation( &trace, start, rotation, &itm, boxAxis, CONTENTS_SOLID | CONTENTS_PLAYERCLIP, cm_testModel.GetInteger(), vec3_origin, modelAxis );
		}
		timer.Stop();
		t = timer.Milliseconds();
		if( t < min_rotation ) min_rotation = t;
		if( t > max_rotation ) max_rotation = t;
		num_rotation++;
		total_rotation += t;
		if( cm_testTimes.GetInteger() > 9999 )
		{
			sprintf( buf, "%3dK", ( int )( cm_testTimes.GetInteger() / 1000 ) );
		}
		else
		{
			sprintf( buf, "%4d", cm_testTimes.GetInteger() );
		}
		common->Printf( "%s rotation: %4d milliseconds, (min = %d, max = %d, av = %1.1f)\n", buf, t, min_rotation, max_rotation, ( float ) total_rotation / num_rotation );
	}
	
	Mem_Free( testend );
	testend = NULL;
}