从0开发游戏引擎之三维几何体数据类

简介: Shape类只是单纯的形状数据,并不能用具真正的绘制,真正的绘制工作是Gizmo类去做的。该类只是作为Gizmo的一个成员去使用的。Shape的函数只是提供了加工数据的,然后把加工后的数据存下来。不多哔哔了,直接贴代码。原理有空了再详细写。

Shape类只是单纯的形状数据,并不能用具真正的绘制,真正的绘制工作是Gizmo类去做的。该类只是作为Gizmo的一个成员去使用的。Shape的函数只是提供了加工数据的,然后把加工后的数据存下来。不多哔哔了,直接贴代码。原理有空了再详细写。


Shape.h


#pragma once
#define VSFRONT    0  //面前
#define VSBACK     1  //面后
#define VSPLANAR   2  //面上
#define VSCLIPPED  0   //剪裁
#define VSCULLED   1   //刨除
#define VSCONTAIN  2   //包含
#define EPSILON_E3 0.00001
//线段类
class GLLine
{
private:
public:
  Vector2 m_vcOrig; //源点|起点
  Vector2 m_vcDir;    //单位方向长度
  float   m_len;    //向量长度|模
  //通过起点和终点获取线段
  void Set(Vector2 &vcOrig, Vector2 &vcEnd);
  //通过点和方向获取线段
  void Set(Vector2 &vcOrig, Vector2 &vcDir, float len);
  GLLine(Vector2 &vcOrig, Vector2 &vcEnd);
  Vector2 getEnd()const;
  GLLine() {};
  ~GLLine() {};
};
//圆
class GLCircle
{
private:
public:
  float radius;
  Vector2 center;
  void Set(Vector2 pos, float r);
  GLCircle(Vector2 pos, float r);
  GLCircle() {}
  ~GLCircle() {}
};
//多边形类
class GLPolygon
{
private:
public:
  GLLine *m_line;
  int m_lineNum;
  GLPolygon(GLLine the_lines[], int the_lineNum);
  GLPolygon(Vector2 the_points[], int the_pointNum);
  void Set(GLLine lines[], int lineNum);
  void Set(Vector2 points[], int pointNum);
  Vector2 m_vcMin;
  Vector2 m_vcMax;
  GLPolygon() { m_line = nullptr; }
  ~GLPolygon() {}
};
class GLAABB
{
public:
  Vector2 m_vcMin; //最小边界
  Vector2 m_vcMax; //最大边界
  Vector2 m_vcCenter;  // 中心
   //通过最大点,最小点获取Aabb
  void Set(Vector2 &vcMin, Vector2 &vcMax);
  //通过长宽高和位置获取Aabb
  void Set(float width, float height, Vector2 &centerPos);
  //
  void Set(Vector2 aabb[]);
  GLAABB(float wid, float hei, Vector2 center);
  GLAABB() {}
  ~GLAABB() {}
};
class  GLRay
{
public:
  Vector2 m_vcOrig;  //源点
  Vector2 m_vcDir;  //单位方向
  //通过点和方向获取射线
  void Set(Vector2 &vcOrig, Vector2 &vcDir);
  GLRay() {}
  ~GLRay() {}
};
class GLPlane
{
public:
  Vector3D m_vcN;      //平面法向量
  Vector3D m_vcPoint;   // 平面上的点
  float m_fD;        // 到原点的距离(ax+by+cz+d=0,-d)
  void Set(Vector3D &vcN, float fD);//通过法线和常量d获取平面
  void Set(Vector3D &vcN, Vector3D &vcP);//通过法线,点获取平面
  void Set(Vector3D &v0, Vector3D &v1, Vector3D &v2);//通过三个点获取平面
    /*点和平面的位置关系(VSFRONT VSBACK VSPLANAR)
  算法描述
  用平面上点和vcPoint组成向量和平面向量做点积,根据值的符号判断位置*/
  int Classify(Vector3D &vcPoint);//判断点是不是在平面上
  GLPlane(){}
  ~GLPlane(){}
};
class GLPoint
{
public:
  Vector3D m_center;
  void setCenter(Vector3D &center);
  int Cull(GLPlane *pPlanes, int nNumPlanes);//判断点是不是在平面里
  GLPoint() {}
  ~GLPoint() {}
};
//球类
class GLSphere
{
public:
  Vector3D m_center;
  float m_radius;
public:
  GLSphere(Vector3D &center,float radius);
  void Set(Vector3D center, float radius);//通过中心点和半径获取球
  int Cull(GLPlane *pPlanes, int nNumPlanes);//判断多面体和球位置关系(VSCULLED,VSCLIPPED,VSVISIBLE)
  bool IsPointIn(Vector3D &point);//判断点在球内
  bool Intersects(Vector3D &v1, Vector3D &v2);//是否与线段相交
  GLSphere() {}
  ~GLSphere() {}
};
class GLAABB3D
{
public:
  Vector3D m_vcMin; //最小边界
  Vector3D m_vcMax; //最大边界
  Vector3D m_vcCenter;  // 中心
  Vector3D CORNERPOINT[8];//八个顶点
  float length;
  float width;
  float height;
  GLAABB3D(Vector3D &vcMin, Vector3D &vcMax);
  GLAABB3D(float length, float width, float height, Vector3D &position);
  void Set(Vector3D &vcMin, Vector3D &vcMax);//通过最大点,最小点获取Aabb
  void Set(float length, float width, float height, Vector3D &position);//通过长宽高和位置获取Aabb
  void Set(Vector3D everyPoint[]);
  bool IsPointIn(Vector3D &point);//判断点在AABB内
  int Cull(GLPlane *pPlanes, int nNumPlanes);//判断多面体和AABB位置关系(VSCULLED,VSCLIPPED,VSVISIBLE)
  GLAABB3D() {}
  ~GLAABB3D() {}
};
class GLLine3D
{
private:
public:
  Vector3D m_vcOrig;  //源点|起点
  Vector3D m_vcDir;   //单位方向长度
  float   m_len;    //向量长度|模
  void Set(Vector3D &vcOrig, Vector3D &vcEnd);  //通过起点和终点获取线段
                          //通过点和方向获取线段
  void Set(Vector3D &vcOrig, Vector3D &vcDir, float len);
  GLLine3D(Vector3D &vcOrig, Vector3D &vcEnd);
  Vector3D getEnd()const;
  GLLine3D() {};
  ~GLLine3D() {};
};
class GLRay3D
{
public:
  Vector3D m_vcOrig;  //源点
  Vector3D m_vcDir; //单位方向
  void Set(Vector3D &vcOrig, Vector3D &vcDir);//通过点和方向获取射线
  bool Intersects(GLSphere &sphere_a, Vector3D &hitPoint);
  bool Intersects(GLLine3D &line_a, Vector3D &hitPoint);
  bool Intersects(GLPlane & plane_a, int size, Vector3D & hitPoint);
  GLRay3D() {}
  ~GLRay3D() {}
};
class GLTrianglePlane:public GLPlane
{
public:
  Vector3D m_v0, m_v1, m_v2;
  Vector3D m_vertex[3];
  void set(Vector3D v0, Vector3D v1, Vector3D v2);
  bool IsPointIn(Vector3D & point);
};


Shape.cpp


#include "Engine.h"
//线段
GLLine::GLLine(Vector2 &vcOrig, Vector2 &vcEnd)
{
  m_vcOrig = vcOrig;
  m_vcDir = (vcEnd - vcOrig).Normalize();
  m_len = (vcEnd - vcOrig).length();
}
void GLLine::Set(Vector2 &vcOrig, Vector2 &vcEnd)
{
  m_vcOrig = vcOrig;
  m_vcDir =(vcEnd - vcOrig).Normalize();
  m_len = (vcEnd - vcOrig).length();
}
void GLLine::Set(Vector2 &vcOrig, Vector2 &vcDir, float len)
{
  m_vcOrig = vcOrig;
  m_vcDir = vcDir;
  m_len = len;
}
Vector2 GLLine::getEnd() const
{
  return Vector2(m_vcOrig.x + m_len*m_vcDir.x, m_vcOrig.y + m_len*m_vcDir.y);
}
//3D空间中的线
GLLine3D::GLLine3D(Vector3D &vcOrig, Vector3D &vcEnd)
{
  m_vcOrig = vcOrig;
  m_vcDir = (vcEnd - vcOrig).Normalize();
  m_len = (vcEnd - vcOrig).length();
}
void GLLine3D::Set(Vector3D &vcOrig, Vector3D &vcEnd)
{
  m_vcOrig = vcOrig;
  m_vcDir = (vcEnd - vcOrig).Normalize();
  m_len = (vcEnd - vcOrig).length();
}
void GLLine3D::Set(Vector3D &vcOrig, Vector3D &vcDir, float len)
{
  m_vcOrig = vcOrig;
  m_vcDir = vcDir;
  m_len = len;
}
Vector3D GLLine3D::getEnd()const
{
  return Vector3D(m_vcOrig.x + m_len*m_vcDir.x, m_vcOrig.y + m_len*m_vcDir.y,m_vcOrig.z+m_len*m_vcDir.z);
}
//圆形
GLCircle::GLCircle(Vector2 pos, float r)
{
  this->center = pos;
  this->radius = r;
}
void GLCircle::Set(Vector2 pos, float r)
{
  this->center = pos;
  this->radius = r;
}
//多边形
GLPolygon::GLPolygon(GLLine lines[], int lineNum)
{
  m_line = new GLLine[lineNum];
  memcpy(m_line, lines, sizeof(GLLine)*lineNum);
  this->m_lineNum = lineNum;
}
GLPolygon::GLPolygon(Vector2 points[], int pointNum)
{
  m_lineNum = pointNum;
  m_line = new GLLine[pointNum];
  for (int i = 0;i < pointNum;i++)
  {
    m_line[i].Set(points[i], points[(i + 1) % pointNum]);
  }
  m_vcMin.x = points[0].x;
  m_vcMin.y = points[0].y;
  m_vcMax.x = points[0].x;
  m_vcMax.y = points[0].y;
  for (int i = 1; i<pointNum; ++i)
  {
    if (m_vcMin.x > points[i].x)
      swap(m_vcMin.x, points[i].x);
    if (m_vcMin.y > points[i].y)
      swap(m_vcMin.y, points[i].y);
    if (m_vcMax.x < points[i].x)
      swap(m_vcMax.x, points[i].x);
    if (m_vcMax.y < points[i].y)
      swap(m_vcMax.y, points[i].y);
  }
}
void GLPolygon::Set(GLLine lines[], int lineNum)
{
  delete[]m_line;
  m_line = new GLLine[lineNum];
  memcpy(m_line,lines,sizeof(GLLine)*lineNum);
  this->m_lineNum = lineNum;
}
void GLPolygon::Set(Vector2 points[], int pointNum)
{
  delete[]m_line;
  m_lineNum = pointNum;
  m_line = new GLLine[pointNum];
  for (int i = 0;i < pointNum;i++)
  {
    m_line[i].Set(points[i], points[(i+1)% pointNum]);
  } 
}
GLAABB::GLAABB(float wid, float hei, Vector2 center)
{
  Set(wid, hei, center);
}
void GLAABB::Set(Vector2 &vcMin, Vector2 &vcMax)
{
  this->m_vcMin = vcMin;
  this->m_vcMax = vcMax;
  this->m_vcCenter = m_vcMin+(vcMax - vcMin) / 2;
}
void GLAABB::Set(float width, float height, Vector2 &centerPos)
{
  this->m_vcCenter = centerPos;
  //算最小点
  this->m_vcMin.x= centerPos.x-width*0.5;
  this->m_vcMin.y = centerPos.y-height*0.5;
  //算最大点
  this->m_vcMax.x = centerPos.x+width*0.5;
  this->m_vcMax.y = centerPos.y+height*0.5;
}
void GLAABB::Set(Vector2 vec[])
{
  m_vcMin =Vector2(9999,9999);
  m_vcMax= Vector2(-9999,-9999);
  for (int i = 0; i < 4; i++)
  {
    if (m_vcMin.x > vec[i].x){m_vcMin.x=vec[i].x;}
    if (m_vcMin.y > vec[i].y){m_vcMin.y=vec[i].y;}
    if (m_vcMax.x < vec[i].x){m_vcMax.x=vec[i].x;}
    if (m_vcMax.y < vec[i].y){m_vcMax.y=vec[i].y;}
  }
}
void GLRay::Set(Vector2 &vcOrig, Vector2 &vcDir)
{
  this->m_vcOrig = vcOrig;
  this->m_vcDir = vcDir.Normalize();
}
void GLPlane::Set(Vector3D &vcN, float fD)
{
  float len=vcN.length();
  m_vcN.x= vcN.x /= len;
  m_vcN.y= vcN.y/= len;
  m_vcN.z= vcN.z/= len;
  m_fD=fD/= len;
}
void GLPlane::Set(Vector3D &vcN,Vector3D &vcP)//法向量和一个点
{
  m_vcN = vcN.Normalize();
  m_fD = -m_vcN.dot(vcP);//面上的法向量点乘一个点
  m_vcPoint = vcP;
}
void GLPlane::Set(Vector3D &v0,Vector3D &v1,Vector3D &v2)
{
  Vector3D vcEdge1 = v1 - v0;
  Vector3D vcEdge2 = v2 - v0;
  m_vcN = vcEdge1.cross(vcEdge2);
  m_vcN.normalize();
  m_fD = -m_vcN.dot(v0);
  m_vcPoint = v0;
}
int GLPlane::Classify(Vector3D &vcPoint)
{
  float len = m_vcN.dot(m_vcPoint) + m_fD;
  if (len > 0)
  {
    return VSPLANAR;
  }
  if (len < 0)
  {
    return VSBACK;
  }
  return VSPLANAR;
}
void GLPoint::setCenter(Vector3D &center)
{
  m_center = center;
}
int GLPoint::Cull(GLPlane *pPlanes, int nNumPlanes)
{
  for (int i = 0;i < nNumPlanes;++i)
  {
    float f = m_center.dot(pPlanes[i].m_vcN)+pPlanes[i].m_fD;
    /*if (f >0)
      return VSFRONT;*/
    if (f <0)
      return VSCULLED;
    if (f == 0)
    {
      return VSCLIPPED;
    }
  }
  return VSCONTAIN;
}
GLSphere::GLSphere(Vector3D &center, float radius)
{
  Set(center, radius);
}
void GLSphere::Set(Vector3D center, float radius)
{
  m_center = center;
  m_radius = radius;
}
int GLSphere::Cull(GLPlane *pPlanes, int nNumPlanes)
{
  for (int i = 0; i < nNumPlanes; i++)
  {
    if (pPlanes[i].m_vcN.x * m_center.x
      + pPlanes[i].m_vcN.y * m_center.y
      + pPlanes[i].m_vcN.z * m_center.z
      + pPlanes[i].m_fD <= -m_radius)
    {
      return VSCULLED;
    }
  }
  return VSCONTAIN;
}
bool GLSphere::IsPointIn(Vector3D &point)
{
  if ((m_center - point).length2q() <= m_radius*m_radius)
  {
    return true;
  }
  return false;
}
bool GLSphere::Intersects(Vector3D &v1, Vector3D &v2)
{
  Vector3D d1 = this->m_center - v1;
  if (d1.length2q() <= this->m_radius*this->m_radius)
    return true;
  Vector3D b_dir = (v2 - v1).Normalize();
  float s = d1.dot(b_dir);
  if (s < 0.000001f)
    return false;
  Vector3D d2 = this->m_center - v2;
  if (d2.length2q() <= this->m_radius*this->m_radius)
    return true;
  //延长线
  float l = (v2 - v1).length2q();
  float m = d1.length2q() - s*s;
  if (m <= this->m_radius*this->m_radius&&l > s*s)
    return true;
  return false;
}
GLAABB3D::GLAABB3D(Vector3D &vcMin, Vector3D &vcMax)
{
  Set(vcMin, vcMax);
}
GLAABB3D::GLAABB3D(float length, float width, float height, Vector3D &position)
{
  Set(length, width, height, position);
}
void GLAABB3D::Set(Vector3D &vcMin, Vector3D &vcMax)
{
  m_vcMin = vcMin;
  m_vcMax = vcMax;
  this->length = fabs(vcMax.x - vcMin.x);
  this->height = fabs( vcMax.y - vcMin.y);
  this->width = fabs(vcMax.z - vcMin.z);
  CORNERPOINT[0] = Vector3D(vcMin.x, vcMin.y, vcMin.z);
  CORNERPOINT[1] = Vector3D(vcMin.x, vcMin.y, vcMax.z);
  CORNERPOINT[2] = Vector3D(vcMin.x, vcMax.y, vcMin.z);
  CORNERPOINT[3] = Vector3D(vcMax.x, vcMin.y, vcMin.z);
  CORNERPOINT[4] = Vector3D(vcMax.x, vcMax.y, vcMin.z);
  CORNERPOINT[5] = Vector3D(vcMax.x, vcMin.y, vcMax.z);
  CORNERPOINT[6] = Vector3D(vcMin.x, vcMax.y, vcMax.z);
  CORNERPOINT[7] = Vector3D(vcMax.x, vcMax.y, vcMax.z);
  m_vcCenter = (vcMax + vcMin) / 2;
}
void GLAABB3D::Set(float length, float width, float height, Vector3D &position)
{
  //长:X - 宽:Z -  高:Y;
  //以中心点画AABB
  m_vcCenter = position;
  m_vcMin.x = position.x - width;
  m_vcMin.y = position.y /*- height*/;
  m_vcMin.z = position.z - width;
  m_vcMax.x = position.x +width;
  m_vcMax.y = position.y + height;
  m_vcMax.z = position.z + width;
  this->length = length;
  this->width = width;
  this->height = height;
  CORNERPOINT[0] = Vector3D(-length*0.5, -height*0.5, -width*0.5);
  CORNERPOINT[1] = Vector3D(-length*0.5, -height*0.5, +width*0.5);
  CORNERPOINT[2] = Vector3D(-length*0.5, +height*0.5, -width*0.5);
  CORNERPOINT[3] = Vector3D(+length*0.5, -height*0.5, -width*0.5);
  CORNERPOINT[4] = Vector3D(-length*0.5, +height*0.5, +width*0.5);
  CORNERPOINT[5] = Vector3D(+length*0.5, +height*0.5, -width*0.5);
  CORNERPOINT[6] = Vector3D(+length*0.5, -height*0.5, +width*0.5);
  CORNERPOINT[7] = Vector3D(+length*0.5, +height*0.5, +width*0.5);
  m_vcCenter = (m_vcMax + m_vcMin) / 2;
}
void GLAABB3D::Set(Vector3D vec[])
{
  m_vcMin = Vector3D(99999, 99999,99999);
  m_vcMax = Vector3D(-99999, -99999,-99999);
  for (int i = 0; i <8;++i)
  {
    if (m_vcMin.x > vec[i].x)
      m_vcMin.x = vec[i].x;
    if (m_vcMin.y > vec[i].y)
      m_vcMin.y = vec[i].y;
    if( m_vcMin.z>=vec[i].z)
      m_vcMin.z = vec[i].z;
    if (m_vcMax.x < vec[i].x)
      m_vcMax.x = vec[i].x;
    if (m_vcMax.y < vec[i].y)
      m_vcMax.y = vec[i].y;
    if (m_vcMax.z < vec[i].z)
      m_vcMax.z = vec[i].z;
  }
  this->length = fabs(m_vcMax.x - m_vcMin.x);
  this->height = fabs(m_vcMax.y - m_vcMin.y);
  this->width = fabs(m_vcMax.z - m_vcMin.z);
  m_vcCenter = (m_vcMax + m_vcMin) / 2;
}
bool GLAABB3D::IsPointIn(Vector3D &point)
{
  if (point.x>m_vcMin.x&&point.x<m_vcMax.x&&
    point.y>m_vcMin.y&&point.y<m_vcMax.y&&
    point.z>m_vcMin.z&&point.z<m_vcMax.z)
  {
    return true;
  }
  return false;
}
int GLAABB3D::Cull(GLPlane *pPlanes, int nNumPlanes)
{
  Vector3D vcMin, vcMax;
  bool bIntersects = false;
  for (int i = 0; i < nNumPlanes; i++)
  {
    // x 
    if (pPlanes[i].m_vcN.x >= 0.0f)
    {
      vcMin.x = m_vcMin.x;
      vcMax.x = m_vcMax.x;
    }
    else
    {
      vcMin.x = m_vcMax.x;
      vcMax.x = m_vcMin.x;
    }
    // y 
    if (pPlanes[i].m_vcN.y >= 0.0f)
    {
      vcMin.y = m_vcMin.y;
      vcMax.y = m_vcMax.y;
    }
    else {
      vcMin.y = m_vcMax.y;
      vcMax.y = m_vcMin.y;
    }
    // z 
    if (pPlanes[i].m_vcN.z >= 0.0f)
    {
      vcMin.z = m_vcMin.z;
      vcMax.z = m_vcMax.z;
    }
    else
    {
      vcMin.z = m_vcMax.z;
      vcMax.z = m_vcMin.z;
    }
    //刨除
    if ((pPlanes[i].m_vcN.dot(vcMin) + pPlanes[i].m_fD) > 0.0f)
      return VSCULLED;
    if ((pPlanes[i].m_vcN.dot(vcMax) + pPlanes[i].m_fD) >= 0.0f)
      bIntersects = true;
  }
  //剪裁
  if (bIntersects)
    return VSCLIPPED;
  //包含
  return VSCONTAIN;
}
void GLRay3D::Set(Vector3D&vcOrig,Vector3D &vcDir)
{
  m_vcOrig = vcOrig;
  m_vcDir = vcDir.Normalize();
}
//射线与线段碰撞
bool GLRay3D::Intersects(GLLine3D &line_a, Vector3D &hitPoint)
{
  Vector3D n = m_vcDir.cross(line_a.m_vcDir);
  if (fabs(n.length()) < EPSILON_E3)
    return false;
  float s = ((line_a.m_vcOrig - this->m_vcOrig).cross(line_a.m_vcDir)).dot(n);
  s /= n.length()*n.length();
  float t = ((this->m_vcOrig - line_a.m_vcOrig).cross(m_vcDir)).dot(-n);
  t /= n.length()*n.length();
  if (s >= 0 && t >= 0 && t <= line_a.m_len)
  {
    Vector3D hit_a = m_vcOrig + m_vcDir*s;
    Vector3D hit_b = line_a.m_vcOrig + line_a.m_vcDir*t;
    if ((hit_a - hit_b).length() < 2)
    {
      hitPoint = hit_a;
      return true;
    }
  }
  return false;
}
//射线与面碰撞
bool GLRay3D::Intersects(GLPlane &plane_a, int size, Vector3D &hitPoint)
{
  float Vd = plane_a.m_vcN.dot(m_vcDir);
  if (fabs(Vd) < EPSILON_E3)
    return false;
  /*if (Vd > 0.0f)
  return false;*/
  float Vo = -(plane_a.m_vcN.dot(m_vcOrig) + plane_a.m_fD);
  float f = Vo / Vd;
  if (f >= 0.0f)
  {
    hitPoint = m_vcOrig + (m_vcDir * f);
    Vector3D d = hitPoint - plane_a.m_vcPoint;
    if (fabs(d.x) <= size && fabs(d.y) <= size && fabs(d.z) <= size)
    {
      return true;
    }
  }
  return false;
}
//射线与球碰撞
bool GLRay3D::Intersects(GLSphere &sphere_a, Vector3D &hitPoint)
{
  Vector3D d = m_vcOrig - sphere_a.m_center;
  if (d.length2q() <= sphere_a.m_radius*sphere_a.m_radius)
    return false;
  float b = m_vcDir.dot(d);
  float c = d.dot(d) - sphere_a.m_radius*sphere_a.m_radius;
  float dt = b*b - c;
  if (dt<0)
    return false;
  //有一个或两个交点
  float t1 = -b + sqrt(dt);
  float t2 = -b - sqrt(dt);
  if (t1 >= 0 && t2 >= 0)
  {
    float f = fmin(t1, t2);
    hitPoint = m_vcOrig + (m_vcDir * f);
    return true;
  }
  return false;
}
void GLTrianglePlane::set(Vector3D v0, Vector3D v1, Vector3D v2)
{
  this->m_v0 = v0;
  this->m_v1 = v1;
  this->m_v2 = v2;
  m_vertex[0] = v0;
  m_vertex[1] = v1;
  m_vertex[2] = v2;
  //GLPlane::Set(v0, v1, v2);
  Set(v0, v1, v2);
}
bool GLTrianglePlane::IsPointIn(Vector3D & point)
{
  Vector3D p0 = m_vertex[1] - m_vertex[0];
  Vector3D p1 = m_vertex[2] - m_vertex[0];
  Vector3D p2 = point - m_vertex[0];
  float dot00 = p0.dot(p0);
  float dot01 = p0.dot(p1);
  float dot02 = p0.dot(p2);
  float dot11 = p1.dot(p1);
  float dot12 = p1.dot(p2);
  float inverDeno = 1.0f / (dot00*dot11 - dot01*dot01);
  float u = (dot02*dot11 - dot01*dot12)*inverDeno;
  if (u < 0 || u > 1)
  {
    return false;
  }
  float v = (dot00*dot12 - dot02*dot01)*inverDeno;
  if (v < 0 || v > 1)
  {
    return false;
  }
  return u + v <= 1;
}
相关文章
|
9月前
|
图形学
Unity三维模型
Unity三维模型
|
数据可视化
【视觉高级篇】20 # 如何用WebGL绘制3D物体?
【视觉高级篇】20 # 如何用WebGL绘制3D物体?
160 0
【视觉高级篇】20 # 如何用WebGL绘制3D物体?
基于C#的ArcEngine二次开发41:投影坐标系与地理坐标系接口、方法及示例代码(二)
基于C#的ArcEngine二次开发41:投影坐标系与地理坐标系接口、方法及示例代码
基于C#的ArcEngine二次开发41:投影坐标系与地理坐标系接口、方法及示例代码(二)
|
数据处理 C#
基于C#的ArcEngine二次开发41:投影坐标系与地理坐标系接口、方法及示例代码(一)
基于C#的ArcEngine二次开发41:投影坐标系与地理坐标系接口、方法及示例代码
基于C#的ArcEngine二次开发41:投影坐标系与地理坐标系接口、方法及示例代码(一)
基于C#的ArcEngine二次开发41:投影坐标系与地理坐标系接口、方法及示例代码(三)
基于C#的ArcEngine二次开发41:投影坐标系与地理坐标系接口、方法及示例代码
基于C#的ArcEngine二次开发41:投影坐标系与地理坐标系接口、方法及示例代码(三)
|
vr&ar 图形学
Unity 的基础光照
Unity 的基础光照
149 0
Unity 的基础光照
从0开发游戏引擎之在3D空间中渲染出三维几何体
这个类里面会使用第9章里的三维体数据来调用OpenGL的接口绘制出来对应的形状。几何体绘制类主要是调试使用的,比如想要更直观的看到一个对象身上的碰撞框。绘制的形状非常多,大家直接看代码吧。
从0开发游戏引擎之使用OpenGL绘制三维球体
绘制球体的难点主要在于 要在遍历循环中 根据经纬度反复的使用Cos、Sin函数算出球面上的XYZ三个顶点坐标,一直反复计算,最终三角面多的形成了一个球的形状。
|
缓存 BI API
从0开发游戏引擎之纹理管理器实现 纹理数据绑定OpenGL滤波方式选择线性滤波
从0开发游戏引擎之纹理管理器实现 纹理数据绑定OpenGL滤波方式选择线性滤波
案例分享:Qt+OSG三维点云引擎(支持原点,缩放,单独轴或者组合多轴拽拖旋转,支持导入点云文件)
案例分享:Qt+OSG三维点云引擎(支持原点,缩放,单独轴或者组合多轴拽拖旋转,支持导入点云文件)
案例分享:Qt+OSG三维点云引擎(支持原点,缩放,单独轴或者组合多轴拽拖旋转,支持导入点云文件)