// OpenGLのジオメトリ描画関数

#pragma once

#define _USE_MATH_DEFINES
#include <math.h>

#include <vector>

#include "../lm/vector2.h"
#include "../lm/vector3.h"
#include "../lm/range3.h"

#include "GlInclude.h"


namespace lib_gl
{


//! 辺が基底ベクトルに平行で, 原点中心の直方体を描画
inline void glDrawBox( float width_x , float width_y , float width_z );

//! 底面がxz平面と平行なシリンダを描画
inline void glDrawCylinder( float radius , float height , unsigned int slice );
//! ふた付の底面がxz平面と平行なシリンダを描画
inline void glDrawCylinderClosed( float radius , float height , unsigned int slice );

//! 穴がxz平面と平行なトーラスを表示する
inline void glDrawTorus(double rad_major, double rad_minor, int res_major, int res_minor);

// xy/yz/zx平面上にグリッド状の平面を描画する
inline void glDrawGridXY( size_t  num_half_grids , float grid_interval );
inline void glDrawGridYZ( size_t  num_half_grids , float grid_interval );
inline void glDrawGridZX( size_t  num_half_grids , float grid_interval );

// xy/yz/zx平面上に平面を描画する
inline void glDrawPlaneXY( float size_x , float size_y );
inline void glDrawPlaneYZ( float size_y , float size_z );
inline void glDrawPlaneZX( float size_z , float size_x );

// xy/yz/zx平面上に四角形を描画する
inline void glDrawLineRectXY( float size_x , float size_y );
inline void glDrawLineRectYZ( float size_y , float size_z );
inline void glDrawLineRectZX( float size_z , float size_x );

//! 原点からx,y,z方向へ指定した長さの軸を直線で描画する.
inline void glDrawGlobalAxis( float axis_length );

//! xyz方向を画面端に描画する
inline void DrawMiniAxis(int view_width, float line_width = 1.0f);
inline void NormalizeArrayVec(double* v);

//! 原点からx,y方向へ指定した長さの軸を直線で描画する.
inline void glDrawAxisXY( float axis_length );

//! xy,yz,zx平面を描画する.
inline void glDrawWireXYZPlanes( float plane_size );

//! 線分を描画する.
inline void glDrawSegment( const lm::vec3f& s0 , const lm::vec3f& s1 );
inline void glDrawSegment( float x0 , float y0 , float z0 , float x1 , float y1 , float z1 );

//! 点を描画する.
inline void glDrawPoint( const float x , const float y );
inline void glDrawPoint( const float x , const float y , const float z );
inline void glDrawPoint( const lm::vec2f& pos );
inline void glDrawPoint( const lm::vec3f& pos );

//! 十字の点を描画する.
inline void glDrawCrossPoint( const float x , const float y , const float z , float size );
inline void glDrawCrossPoint( const lm::vec3f& pos , float size );

//! 現在のビューポートの中心を通る十字を表示する
inline void glDrawCenterCross(float line_width);
//! 現在のビューポートの正規化座標で指定点を通る十字を表示する
inline void glDrawViewportCross(float cx, float cy, float line_width);
//! 現在のビューポートの境界を表示する
inline void glDrawViewportBorder(float line_width);
//! 現在のビューポート全体に四角形を表示する
inline void glDrawViewportRect(void);

//! BBoxをラインで表示する
inline void glDrawRangeLine(const lm::range3f& bbox);



// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//! 辺が基底ベクトルに平行で, 原点中心の直方体を描画
inline void glDrawBox( float width_x , float width_y , float width_z )
{
	float half_x = width_x / 2.0f;
	float half_y = width_y / 2.0f;
	float half_z = width_z / 2.0f;

	glBegin(GL_QUADS);

	glNormal3f( 1.0f , 0.0f , 0.0f );
	glVertex3f( half_x ,  half_y ,  half_z );
	glVertex3f( half_x , -half_y ,  half_z );
	glVertex3f( half_x , -half_y , -half_z );
	glVertex3f( half_x ,  half_y , -half_z );

	glNormal3f( 0.0f , 1.0f , 0.0f );
	glVertex3f(  half_x , half_y ,  half_z );
	glVertex3f(  half_x , half_y , -half_z );
	glVertex3f( -half_x , half_y , -half_z );
	glVertex3f( -half_x , half_y ,  half_z );

	glNormal3f( 0.0f , 0.0f , 1.0f );
	glVertex3f(  half_x ,  half_y , half_z );
	glVertex3f( -half_x ,  half_y , half_z );
	glVertex3f( -half_x , -half_y , half_z );
	glVertex3f(  half_x , -half_y , half_z );

	glNormal3f( -1.0f , 0.0f , 0.0f );
	glVertex3f( -half_x ,  half_y ,  half_z );
	glVertex3f( -half_x ,  half_y , -half_z );
	glVertex3f( -half_x , -half_y , -half_z );
	glVertex3f( -half_x , -half_y ,  half_z );

	glNormal3f( 0.0f , -1.0f , 0.0f );
	glVertex3f(  half_x , -half_y ,  half_z );
	glVertex3f( -half_x , -half_y ,  half_z );
	glVertex3f( -half_x , -half_y , -half_z );
	glVertex3f(  half_x , -half_y , -half_z );

	glNormal3f( 0.0f , 0.0f , -1.0f );
	glVertex3f(  half_x ,  half_y , -half_z );
	glVertex3f(  half_x , -half_y , -half_z );
	glVertex3f( -half_x , -half_y , -half_z );
	glVertex3f( -half_x ,  half_y , -half_z );

	glEnd();
}

//! 底面がxz平面と平行なシリンダを描画
inline void glDrawCylinder( float radius , float height , unsigned int slice )
{
	std::vector< lm::vec3f > directions( slice );
	for( unsigned int i = 0 ; i < slice ; ++i )
	{
		float angle = 2.0f * float(M_PI) * static_cast<float>(i) / static_cast<float>(slice);
		directions[i].y = 0.0f;
		directions[i].z = cos(angle);
		directions[i].x = sin(angle);
	}

	float half_height = height / 2.0f;

	glBegin(GL_QUAD_STRIP);
	for( unsigned int i = 0 ; i < slice+1 ; ++i )
	{
		int idx = i % slice;
		const lm::vec3f& dir = directions[ idx ];
		glNormal3fv( dir.v() );
		glVertex3f( dir.x * radius ,  half_height , dir.z * radius );
		glVertex3f( dir.x * radius , -half_height , dir.z * radius );
	}
	glEnd();
}

inline void glDrawTorus(double rad_major, double rad_minor, int res_major, int res_minor)
{
	for(int i = 0; i < res_minor; i++ )
	{
		glBegin( GL_QUAD_STRIP );
		for(int j = 0; j <= res_major; j++ )
		{
			for(int k = 1; k >= 0; k-- )
			{
				double s = (i + k) % res_minor + 0.5;
				double t = j % res_major;

				double na = t * 2.0 * M_PI / res_major;
				double nb = s * 2.0 * M_PI / res_minor;

				double nx = cos(nb) * cos(na);
				double ny = sin(nb);
				double nz = cos(nb) * sin(na);

				double x = rad_minor * nx + rad_major * cos(na);
				double y = rad_minor * ny;
				double z = rad_minor * nz + rad_major * sin(na);

				glNormal3d( nx, ny, nz );
				glVertex3d( x, y, z );
			}
		}
		glEnd();
	}
}

inline void glDrawCylinderClosed( float radius , float height , unsigned int slice )
{
	std::vector< lm::vec3f > directions( slice );
	for( unsigned int i = 0 ; i < slice ; ++i )
	{
		float angle = 2.0f * float(M_PI) * static_cast<float>(i) / static_cast<float>(slice);
		directions[i].y = 0.0f;
		directions[i].z = cos(angle);
		directions[i].x = sin(angle);
	}

	float half_height = height / 2.0f;

	glBegin(GL_TRIANGLE_FAN);
	glNormal3f( 0.0f , 1.0f , 0.0f );
	glVertex3f( 0.0f , half_height , 0.0f );
	for( unsigned int i = 0 ; i < slice+1 ; ++i )
	{
		int idx = i % slice;
		const lm::vec3f& dir = directions[ idx ];
		glVertex3f( dir.x * radius , half_height , dir.z * radius );
	}
	glEnd();

	glBegin(GL_TRIANGLE_FAN);
	glNormal3f( 0.0f , -1.0f , 0.0f );
	glVertex3f( 0.0f , -half_height , 0.0f );
	for( unsigned int i = 0 ; i < slice+1 ; ++i )
	{
		int idx = ( slice - i ) % slice;
		lm::vec3f& dir = directions[idx%slice];
		glVertex3f( dir.x * radius , -half_height , dir.z * radius );
	}
	glEnd();

	glBegin(GL_QUAD_STRIP);
	for( unsigned int i = 0 ; i < slice+1 ; ++i )
	{
		int idx = i % slice;
		const lm::vec3f& dir = directions[ idx ];
		glNormal3fv( dir.v() );
		glVertex3f( dir.x * radius ,  half_height , dir.z * radius );
		glVertex3f( dir.x * radius , -half_height , dir.z * radius );
	}
	glEnd();
}

//! xy平面上にグリッド状の平面を描画する
inline void glDrawGridXY( size_t  num_half_grids , float grid_interval )
{
	float half_length = (float)num_half_grids * grid_interval;

	glBegin(GL_LINES);
	for(int i=-(int)num_half_grids;i<=(int)num_half_grids;i++)
	{
		float dist = static_cast<float>( i ) * grid_interval;
		glVertex3f(         dist ,  half_length , 0.0f );
		glVertex3f(         dist , -half_length , 0.0f );
		glVertex3f(  half_length ,         dist , 0.0f );
		glVertex3f( -half_length ,         dist , 0.0f );
	}
	glEnd();
}

//! yz平面上にグリッド状の平面を描画する
inline void glDrawGridYZ( size_t  num_half_grids , float grid_interval )
{
	float half_length = (float)num_half_grids * grid_interval;

	glBegin(GL_LINES);
	for(int i=-(int)num_half_grids;i<=(int)num_half_grids;i++)
	{
		float dist = static_cast<float>( i ) * grid_interval;
		glVertex3f( 0.0f ,         dist ,  half_length );
		glVertex3f( 0.0f ,         dist , -half_length );
		glVertex3f( 0.0f ,  half_length ,         dist );
		glVertex3f( 0.0f , -half_length ,         dist );
	}
	glEnd();
}

//! zx平面上にグリッド状の平面を描画する
inline void glDrawGridZX( size_t  num_half_grids , float grid_interval )
{
	float half_length = (float)num_half_grids * grid_interval;

	glBegin(GL_LINES);
	for(int i=-(int)num_half_grids;i<=(int)num_half_grids;i++)
	{
		float dist = static_cast<float>( i ) * grid_interval;
		glVertex3f(  half_length , 0.0f ,         dist );
		glVertex3f( -half_length , 0.0f ,         dist );
		glVertex3f(         dist , 0.0f ,  half_length );
		glVertex3f(         dist , 0.0f , -half_length );
	}
	glEnd();
}

//! xy平面上に平面を描画する
inline void glDrawPlaneXY( float size_x , float size_y )
{
	float half_x = size_x * 0.5f;
	float half_y = size_y * 0.5f;

	glBegin(GL_QUADS);
	glNormal3f( 0.0f , 0.0f , 1.0f );
	glTexCoord2f( 0.0f , 0.0f );  glVertex3f( -half_x , -half_y , 0.0f );
	glTexCoord2f( 1.0f , 0.0f );  glVertex3f(  half_x , -half_y , 0.0f );
	glTexCoord2f( 1.0f , 1.0f );  glVertex3f(  half_x ,  half_y , 0.0f );
	glTexCoord2f( 0.0f , 1.0f );  glVertex3f( -half_x ,  half_y , 0.0f );
	glEnd();
}

//! yz平面上に平面を描画する
inline void glDrawPlaneYZ( float size_y , float size_z )
{
	float half_y = size_y * 0.5f;
	float half_z = size_z * 0.5f;

	glBegin(GL_QUADS);
	glNormal3f( 1.0f , 0.0f , 0.0f );
	glTexCoord2f( 0.0f , 0.0f );  glVertex3f( 0.0f , -half_y , -half_z );
	glTexCoord2f( 1.0f , 0.0f );  glVertex3f( 0.0f ,  half_y , -half_z );
	glTexCoord2f( 1.0f , 1.0f );  glVertex3f( 0.0f ,  half_y ,  half_z );
	glTexCoord2f( 0.0f , 1.0f );  glVertex3f( 0.0f , -half_y ,  half_z );
	glEnd();
}

//! zx平面上に平面を描画する
inline void glDrawPlaneZX( float size_z , float size_x )
{
	float half_z = size_z * 0.5f;
	float half_x = size_x * 0.5f;

	glBegin(GL_QUADS);
	glNormal3f( 0.0f , 1.0f , 0.0f );
	glTexCoord2f( 0.0f , 0.0f );  glVertex3f( -half_x , 0.0f , -half_z );
	glTexCoord2f( 1.0f , 0.0f );  glVertex3f( -half_x , 0.0f ,  half_z );
	glTexCoord2f( 1.0f , 1.0f );  glVertex3f(  half_x , 0.0f ,  half_z );
	glTexCoord2f( 0.0f , 1.0f );  glVertex3f(  half_x , 0.0f , -half_z );
	glEnd();
}

//! xy平面上に四角形を描画する
inline void glDrawLineRectXY( float size_x , float size_y )
{
	float half_x = size_x * 0.5f;
	float half_y = size_y * 0.5f;

	glBegin(GL_LINE_LOOP);
	glNormal3f( 0.0f , 0.0f , 1.0f );
	glTexCoord2f( 0.0f , 0.0f );  glVertex3f( -half_x , -half_y , 0.0f );
	glTexCoord2f( 1.0f , 0.0f );  glVertex3f(  half_x , -half_y , 0.0f );
	glTexCoord2f( 1.0f , 1.0f );  glVertex3f(  half_x ,  half_y , 0.0f );
	glTexCoord2f( 0.0f , 1.0f );  glVertex3f( -half_x ,  half_y , 0.0f );
	glEnd();
}

//! yz平面上に四角形を描画する
inline void glDrawLineRectYZ( float size_y , float size_z )
{
	float half_y = size_y * 0.5f;
	float half_z = size_z * 0.5f;

	glBegin(GL_LINE_LOOP);
	glNormal3f( 1.0f , 0.0f , 0.0f );
	glTexCoord2f( 0.0f , 0.0f );  glVertex3f( 0.0f , -half_y , -half_z );
	glTexCoord2f( 1.0f , 0.0f );  glVertex3f( 0.0f ,  half_y , -half_z );
	glTexCoord2f( 1.0f , 1.0f );  glVertex3f( 0.0f ,  half_y ,  half_z );
	glTexCoord2f( 0.0f , 1.0f );  glVertex3f( 0.0f , -half_y ,  half_z );
	glEnd();
}

//! zx平面上に四角形を描画する
inline void glDrawLineRectZX( float size_z , float size_x )
{
	float half_z = size_z * 0.5f;
	float half_x = size_x * 0.5f;

	glBegin(GL_LINE_LOOP);
	glNormal3f( 1.0f , 0.0f , 0.0f );
	glTexCoord2f( 0.0f , 0.0f );  glVertex3f( -half_x , 0.0f , -half_z );
	glTexCoord2f( 1.0f , 0.0f );  glVertex3f( -half_x , 0.0f ,  half_z );
	glTexCoord2f( 1.0f , 1.0f );  glVertex3f(  half_x , 0.0f ,  half_z );
	glTexCoord2f( 0.0f , 1.0f );  glVertex3f(  half_x , 0.0f , -half_z );
	glEnd();
}


//! 原点からx,y,z方向へ指定した長さの軸を直線で描画する.
inline void glDrawGlobalAxis( float axis_length )
{
	glBegin( GL_LINES );
	glColor3d(1,0,0); glVertex3f( 0.0f , 0.0f , 0.0f ); glVertex3f( axis_length , 0.0f , 0.0f );
	glColor3d(0,1,0); glVertex3f( 0.0f , 0.0f , 0.0f ); glVertex3f( 0.0f , axis_length , 0.0f );
	glColor3d(0,0,1); glVertex3f( 0.0f , 0.0f , 0.0f ); glVertex3f( 0.0f , 0.0f , axis_length );
	glEnd();
}


inline void NormalizeArrayVec(double* v)
{
	double len = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
	v[0] /= len;  v[1] /= len;  v[2] /= len;
}

inline void DrawMiniAxis(int view_width, float line_width)
{
	glPushAttrib(
		GL_ENABLE_BIT |
		GL_VIEWPORT_BIT |
		GL_LINE_BIT |
		GL_TRANSFORM_BIT |
		GL_SCISSOR_BIT );

	glDisable(GL_LIGHTING);
	glEnable(GL_SCISSOR_TEST);

	int src_viewport[4];
	glGetIntegerv(GL_VIEWPORT, src_viewport);

	glScissor(src_viewport[0], src_viewport[1], view_width, view_width);
	glViewport(src_viewport[0], src_viewport[1], view_width, view_width);

	glClear(GL_DEPTH_BUFFER_BIT);

	glLineWidth(line_width);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();

	double mat_modelview[16];
	glGetDoublev(GL_MODELVIEW_MATRIX, mat_modelview);
	NormalizeArrayVec(&mat_modelview[0]);
	NormalizeArrayVec(&mat_modelview[4]);
	NormalizeArrayVec(&mat_modelview[8]);

	mat_modelview[12] = 0.0f;
	mat_modelview[13] = 0.0f;
	mat_modelview[14] = 0.5f;

	mat_modelview[2] *= -1.0f;
	mat_modelview[6] *= -1.0f;
	mat_modelview[10] *= -1.0f;

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	glMultMatrixd(mat_modelview);

	static const double axis_length = 0.75;
	glBegin(GL_LINES);
	glColor3d(1,0,0); glVertex3d(0,0,0); glVertex3d(axis_length, 0, 0);
	glColor3d(0,1,0); glVertex3d(0,0,0); glVertex3d(0, axis_length, 0);
	glColor3d(0,0,1); glVertex3d(0,0,0); glVertex3d(0, 0, axis_length);
	glEnd();

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();

	glPopAttrib();
}


//! 原点からx,y方向へ指定した長さの軸を直線で描画する.
inline void glDrawAxisXY( float axis_length )
{
	glBegin( GL_LINES );
	glColor3d(1,0,0); glVertex3f( 0.0f , 0.0f , 0.0f ); glVertex3f( axis_length , 0.0f , 0.0f );
	glColor3d(0,1,0); glVertex3f( 0.0f , 0.0f , 0.0f ); glVertex3f( 0.0f , axis_length , 0.0f );
	glEnd();
}

//! xy,yz,zx平面を描画する.
inline void glDrawWireXYZPlanes( float plane_size )
{
	float half_length = plane_size * 0.5f;

	glColor3d(1,0,0);
	glBegin( GL_LINE_LOOP );
	glVertex3f( 0.0f , -half_length , -half_length );
	glVertex3f( 0.0f , -half_length ,  half_length );
	glVertex3f( 0.0f ,  half_length ,  half_length );
	glVertex3f( 0.0f ,  half_length , -half_length );
	glEnd();

	glColor3d(0,1,0);
	glBegin( GL_LINE_LOOP );
	glVertex3f( -half_length , 0.0f , -half_length );
	glVertex3f(  half_length , 0.0f , -half_length );
	glVertex3f(  half_length , 0.0f ,  half_length );
	glVertex3f( -half_length , 0.0f ,  half_length );
	glEnd();

	glColor3d(0,0,1);
	glBegin( GL_LINE_LOOP );
	glVertex3f( -half_length , -half_length , 0.0f );
	glVertex3f( -half_length ,  half_length , 0.0f );
	glVertex3f(  half_length ,  half_length , 0.0f );
	glVertex3f(  half_length , -half_length , 0.0f );
	glEnd();
}


inline void glDrawSegment( const lm::vec3f& s0 , const lm::vec3f& s1 )
{
	glBegin( GL_LINES );
	glVertex3f( s0.x , s0.y , s0.z );
	glVertex3f( s1.x , s1.y , s1.z );
	glEnd();
}

inline void glDrawSegment( float x0 , float y0 , float z0 , float x1 , float y1 , float z1 )
{
	glBegin( GL_LINES );
	glVertex3f( x0 , y0 , z0 );
	glVertex3f( x1 , y1 , z1 );
	glEnd();
}

inline void glDrawPoint( const float x , const float y )
{
	glBegin( GL_POINTS );
	glVertex2f( x , y );
	glEnd();
}

inline void glDrawPoint( const float x , const float y , const float z )
{
	glBegin( GL_POINTS );
	glVertex3f( x , y , z );
	glEnd();
}

inline void glDrawPoint( const lm::vec2f& pos )
{
	glDrawPoint( pos.x , pos.y );
}

inline void glDrawPoint( const lm::vec3f& pos )
{
	glDrawPoint( pos.x , pos.y , pos.z );
}

inline void glDrawCrossPoint( const float x , const float y , const float z , float size )
{
	glBegin(GL_LINES);
	glVertex3f( x - size , y , z );
	glVertex3f( x + size , y , z );
	glVertex3f( x , y - size , z );
	glVertex3f( x , y + size , z );
	glVertex3f( x , y , z - size );
	glVertex3f( x , y , z + size );
	glEnd();
}

inline void glDrawCrossPoint( const lm::vec3f& pos , float size )
{
	glDrawCrossPoint( pos.x , pos.y , pos.z , size );
}


inline void glDrawCenterCross(float line_width)
{
	glDrawViewportCross(0.0f, 0.0f, line_width);
}

inline void glDrawViewportCross(float cx, float cy, float line_width)
{
	glPushAttrib(GL_ENABLE_BIT|GL_LINE_BIT|GL_TRANSFORM_BIT);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	glLineWidth(line_width);
	glDrawSegment(-1.0f, cy, 0.0f, 1.0f, cy, 0.0f);
	glDrawSegment(cx, -1.0f, 0.0f, cx, 1.0f, 0.0f);

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();

	glPopAttrib();
}

inline void glDrawViewportBorder(float line_width)
{
	glPushAttrib(GL_ENABLE_BIT|GL_LINE_BIT|GL_TRANSFORM_BIT);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	glLineWidth(line_width);

	glBegin(GL_LINE_LOOP);
	glVertex3f(-1.0f, -1.0f, 0.0f);
	glVertex3f(-1.0f, 1.0f, 0.0f);
	glVertex3f(1.0f, 1.0f, 0.0f);
	glVertex3f(1.0f, -1.0f, 0.0f);
	glEnd();

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();

	glPopAttrib();
}

inline void glDrawViewportRect(void)
{
	glPushAttrib(GL_ENABLE_BIT|GL_TRANSFORM_BIT);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	glBegin(GL_QUADS);
	glTexCoord2d(0, 0);
	glVertex3f(-1.0f, -1.0f, 0.0f);
	glTexCoord2d(0, 1);
	glVertex3f(-1.0f, 1.0f, 0.0f);
	glTexCoord2d(1, 1);
	glVertex3f(1.0f, 1.0f, 0.0f);
	glTexCoord2d(1, 0);
	glVertex3f(1.0f, -1.0f, 0.0f);
	glEnd();

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();

	glPopAttrib();
}


//! BBoxをラインで表示する
void glDrawRangeLine(const lm::range3f& r)
{
	if(!r.is_valid())
		return;

	float tx = r.max_x();
	float ty = r.max_y();
	float tz = r.max_z();
	float bx = r.min_x();
	float by = r.min_y();
	float bz = r.min_z();

	glBegin(GL_LINE_LOOP);
	glVertex3f(tx, ty, tz);
	glVertex3f(tx, by, tz);
	glVertex3f(bx, by, tz);
	glVertex3f(bx, ty, tz);
	glEnd();

	glBegin(GL_LINE_LOOP);
	glVertex3f(tx, ty, bz);
	glVertex3f(tx, by, bz);
	glVertex3f(bx, by, bz);
	glVertex3f(bx, ty, bz);
	glEnd();

	glBegin(GL_LINES);
	glVertex3f(tx, ty, tz);
	glVertex3f(tx, ty, bz);
	glVertex3f(tx, by, tz);
	glVertex3f(tx, by, bz);
	glVertex3f(bx, by, tz);
	glVertex3f(bx, by, bz);
	glVertex3f(bx, ty, tz);
	glVertex3f(bx, ty, bz);
	glEnd();
}


}
