GameSoul's Blog
   游戏的程序就是一行行的代码,需要你的灵魂才能赋予它以生命,有了生命的游戏才能带给大家快乐,也才能给你所想要的,你的游戏是你的热情,是你的汗水,是你的喜怒哀乐,是你的梦想,你的游戏,其实就是你自己.

准备用OBB绑定于3D游戏中人物的骨骼块来做碰撞,在3D动作或格斗游戏用的较多,碰撞算法在网上找的,比较复杂,先拿来用吧,写了个简单的OBB类。

OrientedBoundingBox


#pragma once

#include "GSMatrix4X4.h"
#include "GSVector3D.h"
using namespace GSFrameWork;

#include <GL/gl.h>

class COrientedBoundingBox
{
public:

 COrientedBoundingBox()
 {
  mVel.set(0,0,0);
  mPosition.set(0,0,0);
  mTransforms.identity();
  mRotate.set(0,0,0);
  mAngleVel.set(0,0,0);
 }

 COrientedBoundingBox(GSVector3D_f _min,GSVector3D_f _max)
 {
  set(_min,_max);
  mTransforms.identity();
  mRotate.set(0,0,0);
  mAngleVel.set(0,0,0);
 }

 ~COrientedBoundingBox()
 {}

 void set(GSVector3D_f _min,GSVector3D_f _max)
 {
  mMin = _min;
  mMax = _max;
  update();
 }

 void render()
 {
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  
  glMultMatrixf(mTransforms.m);
  
  float halfSize = mSize * 0.5f;

  glBegin(GL_QUADS);         
  glColor3f(0.0f,1.0f,0.0f);      
  glVertex3f( halfSize, halfSize,-halfSize);     
  glVertex3f(-halfSize, halfSize,-halfSize);     
  glVertex3f(-halfSize, halfSize, halfSize);    
  glVertex3f( halfSize, halfSize, halfSize);     
  glColor3f(1.0f,0.5f,0.0f);      
  glVertex3f( halfSize,-halfSize, halfSize);     
  glVertex3f(-halfSize,-halfSize, halfSize);     
  glVertex3f(-halfSize,-halfSize,-halfSize);     
  glVertex3f( halfSize,-halfSize,-halfSize);     
  glColor3f(1.0f,0.0f,0.0f);      
  glVertex3f( halfSize, halfSize, halfSize);    
  glVertex3f(-halfSize, halfSize, halfSize);    
  glVertex3f(-halfSize,-halfSize, halfSize);    
  glVertex3f( halfSize,-halfSize, halfSize);     
  glColor3f(1.0f,1.0f,0.0f);     
  glVertex3f( halfSize,-halfSize,-halfSize);     
  glVertex3f(-halfSize,-halfSize,-halfSize);    
  glVertex3f(-halfSize, halfSize,-halfSize);     
  glVertex3f( halfSize, halfSize,-halfSize);    
  glColor3f(0.0f,0.0f,1.0f);      
  glVertex3f(-halfSize, halfSize, halfSize);     
  glVertex3f(-halfSize, halfSize,-halfSize);     
  glVertex3f(-halfSize,-halfSize,-halfSize);     
  glVertex3f(-halfSize,-halfSize, halfSize);    
  glColor3f(1.0f,0.0f,1.0f);      
  glVertex3f( halfSize, halfSize,-halfSize);     
  glVertex3f( halfSize, halfSize, halfSize);     
  glVertex3f( halfSize,-halfSize, halfSize);    
  glVertex3f( halfSize,-halfSize,-halfSize);     
  glEnd();           

  glPopMatrix();
 }

 bool intersects(COrientedBoundingBox &obb)
 {
  updateMatrix();

  GSMatrix4X4_f invertMe = mTransforms;
  invertMe.invert();
  GSMatrix4X4_f t = obb.mTransforms * invertMe;

  GSVector3D_f obbCenter = t * obb.mCenter;
  GSVector3D_f obbExtents = obb.mExtents;
  GSVector3D_f separation = obbCenter - mCenter;

  GSMatrix4X4_f rotations(t);
  GSMatrix4X4_f absrotations = rotations.abs();

  float r,r0,r1,r01;
//
  r = fabs(separation.x);
  r1 = obbExtents.dotProduct(absrotations.col(0));
  r01 = mExtents.x + r1;

  if(r > r01) return false;

  r = fabs(separation.y);
  r1 = obbExtents.dotProduct(absrotations.col(1));
  r01 = mExtents.y + r1;

  if(r > r01) return false;

  r = fabs(separation.z);
  r1 = obbExtents.dotProduct(absrotations.col(2));
  r01 = mExtents.z + r1;

  if(r > r01) return false;
//
  r = fabs(rotations.row(0).dotProduct(separation));
  r0 = mExtents.dotProduct(absrotations.row(0));
  r01 = r0 + obbExtents.x;

  if(r > r01) return false;

  r = fabs(rotations.row(1).dotProduct(separation));
  r0 = mExtents.dotProduct(absrotations.row(1));
  r01 = r0 + obbExtents.y;

  if(r > r01) return false;

  r = fabs(rotations.row(2).dotProduct(separation));
  r0 = mExtents.dotProduct(absrotations.row(2));
  r01 = r0 + obbExtents.z;

  if(r > r01) return false;

//

  r = fabs(separation.z * rotations.mm[0][1] - separation.y * rotations.mm[0][2]);
  r0 = mExtents.y * absrotations.mm[0][2] + mExtents.z * absrotations.mm[0][1];
  r1 = obbExtents.y + absrotations.mm[2][0] + obbExtents.z * absrotations.mm[1][0];
  r01 = r0 + r1;

  if(r > r01) return false;

  r = fabs(separation.z * rotations.mm[1][1] - separation.y * rotations.mm[1][2]);
  r0 = mExtents.y * absrotations.mm[1][2] + mExtents.z * absrotations.mm[1][1];
  r1 = obbExtents.x + absrotations.mm[2][0] + obbExtents.z * absrotations.mm[0][0];
  r01 = r0 + r1;

  if(r > r01) return false;

  r = fabs(separation.z * rotations.mm[2][1] - separation.y * rotations.mm[2][2]);
  r0 = mExtents.y * absrotations.mm[2][2] + mExtents.z * absrotations.mm[2][1];
  r1 = obbExtents.x + absrotations.mm[1][0] + obbExtents.y * absrotations.mm[0][0];
  r01 = r0 + r1;

  if(r > r01) return false;

//
  r = fabs(separation.x * rotations.mm[0][2] - separation.z * rotations.mm[0][0]);
  r0 = mExtents.x * absrotations.mm[0][2] + mExtents.z * absrotations.mm[0][0];
  r1 = obbExtents.y * absrotations.mm[2][1] + obbExtents.z * absrotations.mm[1][1];
  r01 = r0 + r1;

  if(r > r01) return false;

  r = fabs(separation.x * rotations.mm[1][2] - separation.z * rotations.mm[1][0]);
  r0 = mExtents.x * absrotations.mm[1][2] + mExtents.z * absrotations.mm[1][0];
  r1 = obbExtents.x * absrotations.mm[2][1] + obbExtents.z * absrotations.mm[0][1];
  r01 = r0 + r1;

  if(r > r01) return false;


  r = fabs(separation.x * rotations.mm[2][2] - separation.z * rotations.mm[2][0]);
  r0 = mExtents.x * absrotations.mm[2][2] + mExtents.z * absrotations.mm[2][0];
  r1 = obbExtents.x * absrotations.mm[1][1] + obbExtents.y * absrotations.mm[0][1];
  r01 = r0 + r1;

  if(r > r01) return false;
//

  r = fabs(separation.y * rotations.mm[0][0] - separation.x * rotations.mm[0][1]);
  r0 = mExtents.x * absrotations.mm[0][1] + mExtents.y * absrotations.mm[0][0];
  r1 = obbExtents.y * absrotations.mm[2][2] + obbExtents.z * absrotations.mm[1][2];
  r01 = r0 + r1;

  if (r > r01) return false;


  r = fabs(separation.y * rotations.mm[1][0] - separation.x * rotations.mm[1][1]);
  r0 = mExtents.x * absrotations.mm[1][1] + mExtents.y * absrotations.mm[1][0];
  r1 = obbExtents.x * absrotations.mm[2][2] + obbExtents.z * absrotations.mm[0][2];
  r01 = r0 + r1;

  if (r > r01) return false;

  r =fabs(separation.y * rotations.mm[2][0] - separation.x * rotations.mm[2][1]);
  r0 = mExtents.x * absrotations.mm[2][1] + mExtents.y * absrotations.mm[2][0];
  r1 = obbExtents.x * absrotations.mm[1][2] + obbExtents.y * absrotations.mm[0][2];
  r01 = r0 + r1;

  if (r > r01) return false;

  return true;

 }
 

 void setSize(float size)
 {
  mSize = size;
  float halfSize = mSize * 0.5f;
  mMin.set(-halfSize,-halfSize,-halfSize);
  mMax.set(halfSize,halfSize,halfSize);
  update();
 }

 void update()
 {
  mCenter = (mMin + mMax) * 0.5f;
  mExtents = (mMax - mMin) * 0.5f;

  mPosition += mVel;
  mRotate += mAngleVel;
  updateMatrix();
 }

 void updateMatrix()
 {
  mTransforms.identity();
  mTransforms.translate(mPosition.x,mPosition.y,mPosition.z);
  if(mRotate.x)
   mTransforms.rotate_x(mRotate.x);
  if(mRotate.y)
   mTransforms.rotate_y(mRotate.y);
  if(mRotate.z)
   mTransforms.rotate_z(mRotate.z);
 }

 GSMatrix4X4_f   mTransforms;
 GSVector3D_f    mMin;
 GSVector3D_f    mMax;
 GSVector3D_f    mCenter;
 GSVector3D_f    mExtents;
 GSVector3D_f    mPosition;
 GSVector3D_f    mRotate;
 GSVector3D_f    mVel;
 GSVector3D_f    mAngleVel;
 float           mSize;
};

posted on 2007-05-29 23:22  GameSoul  阅读(4081)  评论(2编辑  收藏  举报