3D:AABBとAABB

バウンディングボックス:AABBです。
これは2Dの矩形を3Dにそのまま拡張した物です。
AABBは回転すると使えません。

 

 

#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#include <GL/freeglut/freeglut.h>
#include <stdio.h>
#include <math.h>

#define WIDTH 320
#define HEIGHT 240

//平行移動用
float x = 0.0f;
float y = 0.0f;
bool flag = false;
bool flag2 = false;
//ライトの位置
GLfloat lightpos[] = { 200.0, 300.0, -500.0, 1.0 };

//3つのベクトル
struct Vector3f{
 float x;
 float y;
 float z;
}vec3d;

Vector3f & operator+(Vector3f &a,Vector3f &b){
 a.x+=b.x;
 a.y+=b.y;
 a.z+=b.z;
 return a;
}

Vector3f & operator-(Vector3f &a,Vector3f &b){
 a.x-=b.x;
 a.y-=b.y;
 a.z-=b.z;
 return a;
}

//直方体構造体
struct Cuboid{
 GLfloat Color[4];//色
 Vector3f Radius;//半径
 Vector3f Pos;//位置
 void Draw();
 void make_cuboid(float width,float height,float depth);
};
void Cuboid::Draw(){
 glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
 glMaterialfv(GL_FRONT, GL_DIFFUSE, Color);
 glTranslatef(Pos.x,Pos.y,Pos.z);
 make_cuboid(Radius.x,Radius.y,Radius.z);
}
//直方体
void Cuboid::make_cuboid(float width,float height,float depth)
{
 glBegin(GL_QUADS);
 //前
 glNormal3f(0.0,0.0,-1.0);
 glVertex3f(width/2,height/2,depth/2);
 glVertex3f(-width/2,height/2,depth/2);
 glVertex3f(-width/2,-height/2,depth/2);
 glVertex3f(width/2,-height/2,depth/2);

 //左
 glNormal3f(1.0,0.0,0.0);
 glVertex3f(width/2,height/2,depth/2);
 glVertex3f(width/2,height/2,-depth/2);
 glVertex3f(width/2,-height/2,-depth/2);
 glVertex3f(width/2,-height/2,depth/2);

 //右
 glNormal3f(-1.0,0.0,0.0);
 glVertex3f(-width/2,height/2,-depth/2);
 glVertex3f(-width/2,height/2,depth/2);
 glVertex3f(-width/2,-height/2,depth/2);
 glVertex3f(-width/2,-height/2,-depth/2);

 //後
 glNormal3f(0.0,0.0,1.0);
 glVertex3f(width/2,height/2,-depth/2);
 glVertex3f(-width/2,height/2,-depth/2);
 glVertex3f(-width/2,-height/2,-depth/2);
 glVertex3f(width/2,-height/2,-depth/2);

 //上
 glNormal3f(0.0,1.0,0.0);
 glVertex3f(width/2,height/2,depth/2);
 glVertex3f(-width/2,height/2,depth/2);
 glVertex3f(-width/2,height/2,-depth/2);
 glVertex3f(width/2,height/2,-depth/2);

 //下
 glNormal3f(0.0,-1.0,0.0);
 glVertex3f(width/2,-height/2,depth/2);
 glVertex3f(-width/2,-height/2,depth/2);
 glVertex3f(-width/2,-height/2,-depth/2);
 glVertex3f(width/2,-height/2,-depth/2);
 glEnd();
}

 

Cuboid Green,Yellow;

//当り判定
bool Calc_Hit(Cuboid& a,Cuboid& b){
 Vector3f Min,Min2;
 Vector3f Max,Max2;
 Min=a.Pos-a.Radius;
 Min2=b.Pos-b.Radius;
 Max=a.Pos+a.Radius;
 Max2=b.Pos+b.Radius;
 if(Min.x<Max2.x && Max.x>Min2.x
  && Min.y<Max2.y && Max.y>Min2.y
   && Min.z<Max2.z && Max.z>Min2.z){
  return true;
 }else{
  return false;
 }
}

 

class GLFONT
{
public:
 HFONT Hfont;
 HDC Hdc;
 GLFONT(wchar_t *fontname, int size);
 void DrawStringW(int x,int y,wchar_t *format, ...);
};
//コンストラクタ フォント作成
GLFONT::GLFONT(wchar_t *fontname, int size)
{
 Hfont = CreateFontW(
        size,      //フォント高さ
        0,       //文字幅
        0,       //テキストの角度
        0,       //ベースラインとx軸との角度
        FW_REGULAR,     //フォントの太さ
        FALSE,      //イタリック体
        FALSE,      //アンダーライン
        FALSE,      //打ち消し線
        SHIFTJIS_CHARSET,   //文字セット
        OUT_DEFAULT_PRECIS,   //出力精度
        CLIP_DEFAULT_PRECIS,  //クリッピング精度
        ANTIALIASED_QUALITY,  //出力品質
        FIXED_PITCH | FF_MODERN, //ピッチとファミリー
        fontname);     //書体名

 Hdc = wglGetCurrentDC();
 SelectObject(Hdc, Hfont);
}
//ワイド文字列の描画
void GLFONT::DrawStringW(int x,int y,wchar_t *format, ...)
{
 wchar_t buf[256];
 va_list ap;
 int Length=0;
 int list=0;
 
 //ポインタがNULLの場合は終了
 if ( format == NULL )
  return;

 //文字列変換
 va_start(ap, format);
 vswprintf_s(buf, format, ap);
 va_end(ap);

 Length = wcslen(buf);
 list = glGenLists(Length);
 for( int i=0; i<Length; i++ ){
  wglUseFontBitmapsW(Hdc, buf[i], 1, list + (DWORD)i);
 }

 glDisable(GL_LIGHTING);
 glRasterPos2i(x, y);
 //ディスプレイリストで描画
 for( int i=0; i<Length; i++ )
 {
  glCallList(list + i);
 }
 glEnable(GL_LIGHTING);
 //ディスプレイリスト破棄
 glDeleteLists(list, Length);
 list = 0;
 Length = 0;
}

GLFONT *font;


void Line3D(float x1,float y1,float z1,float x2,float y2,float z2){
  //線幅
  glLineWidth(1.0);
  //線
  glBegin(GL_LINES);
 glVertex3f(x1,y1,z1);
 glVertex3f(x2,y2,z2);
  glEnd();
}

void DrawMeasure(int measure,float size){
 glDisable(GL_LIGHTING);
 glColor4f(0.5f, 0.5f, 0.5f, 0.5f);
 for(int x=0;x<=measure;x++){Line3D(x*size-(size*measure/2),0,-(size*measure/2),x*size-(size*measure/2),0,measure*size-(size*measure/2));}
 for(int y=0;y<=measure;y++){Line3D(-(size*measure/2),0,y*size-(size*measure/2),measure*size-(size*measure/2),0,y*size-(size*measure/2));}
 glDisable(GL_DEPTH_TEST);
 glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
 Line3D(0,0,0,(measure/2+2)*size,0,0);
 glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
 Line3D(0,0,0,0,(measure/2+2)*size,0);
 glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
 Line3D(0,0,0,0,0,(measure/2+2)*size);
 glEnable(GL_LIGHTING);
 glEnable(GL_DEPTH_TEST);
}

void set_world(){
 glLoadIdentity();
 //視点の設定
 gluLookAt(200.0,300.0,500.0, //カメラの座標
      0.0,0.0,0.0, // 注視点の座標
     0.0,1.0,0.0); // 画面の上方向を指すベクトル
}
void display(void)
{
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glViewport(0, 0, WIDTH, HEIGHT);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離)
 gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 2000.0);
 glMatrixMode(GL_MODELVIEW);

 set_world();

 if(Calc_Hit(Green,Yellow)){
  glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
  font->DrawStringW(-200,110,L"Hit !!");
 }else{
  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
  font->DrawStringW(-200,110,L"No Hit !!");
 }

 DrawMeasure(16,40);

 Yellow.Draw();

 set_world();

 Green.Draw();

 glutSwapBuffers();
}
void timer(int value) {
 if(flag){x-=1.0f;}else{x+=1.0f;}
 if(x>100.0f)flag=true;
 if(x<-100.0f)flag=false;
 if(flag2){y-=3.0f;}else{y+=3.0f;}
 if(y>100.0f)flag2=true;
 if(y<-100.0f)flag2=false;
 Green.Pos.x=x;
 Yellow.Pos.y=y;
 glutTimerFunc(10 , timer , 0);
}
void idle(void)
{
 glutPostRedisplay();
}
void Init(){
 glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
 glEnable(GL_DEPTH_TEST);
 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);
 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
 glEnable(GL_BLEND);//ブレンドの有効化
 font = new GLFONT(L"MS明朝", 24);
 Green.Color[0]=0.0f;
 Green.Color[1]=1.0f;
 Green.Color[2]=0.0f;
 Green.Color[3]=0.8f;
 Green.Pos.x=0.0f;
 Green.Pos.y=0.0f;
 Green.Pos.z=0.0f;
 Green.Radius.x=50.0f;
 Green.Radius.y=30.0f;
 Green.Radius.z=20.0f;
 Yellow.Color[0]=1.0f;
 Yellow.Color[1]=1.0f;
 Yellow.Color[2]=0.0f;
 Yellow.Color[3]=0.8f;
 Yellow.Pos.x=0.0f;
 Yellow.Pos.y=50.0f;
 Yellow.Pos.z=0.0f;
 Yellow.Radius.x=80.0f;
 Yellow.Radius.y=50.0f;
 Yellow.Radius.z=50.0f;
}
int main(int argc, char *argv[])
{
 glutInitWindowPosition(100, 100);
 glutInitWindowSize(WIDTH, HEIGHT);
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
 glutCreateWindow("AABB");
 glutDisplayFunc(display);
 glutIdleFunc(idle);
 glutTimerFunc(10 , timer , 0);
 Init();
 glutMainLoop();
 return 0;
}

 

 

 

最終更新:2014年06月15日 20:22
添付ファイル