加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Bullet中的基本数据类型

(2010-12-12 21:50:13)
标签:

杂谈

分类: 物理引擎

Bullet中的常用数据类型包括: btScalar、btVector3、 btQuaternion、btMatrix3x3以及btTransform

下面我们看看这些基本数据类型功能及用法:

 

1、btScalar

       在bullet中,btScalar是单精度或双精度浮点数。如果我们定义了宏BT_USE_DOUBLE_PRECISION,则btScalar是double,否则是float。

btScalar的实现代码:

#if defined(BT_USE_DOUBLE_PRECISION)
typedef double btScalar;
//this number could be bigger in double precision
#define BT_LARGE_FLOAT 1e30
#else
typedef float btScalar;
//keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX
#define BT_LARGE_FLOAT 1e18f
#endif

 

2、btVector3

      在Bullet中,3D位置和向量用btVector3表示。在btVector3中,实际上包含四个值:x, y, z, w,第四个分量w值恒为0。加第四个分量,主要是考虑SIMD对齐(通常SIMD指令可以处理四个浮点数)。

     除了常用的加、减、点积、叉积、混合积、乘一个标量值,归一化等操作外,还包括几个特殊的函数或操作:

比如:angle返回当前向量和另一个向量的夹角。

  
    SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const 
    {
        btScalar s = btSqrt(length2() * v.length2());
        btFullAssert(s != btScalar(0.0));
        return btAcos(dot(v) / s);
    }

绕单位向量旋转一rotate个角度:

SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar angle )
{
    // wAxis must be a unit lenght vector
 
    btVector3 o = wAxis * wAxis.dot( *this );
    btVector3 x = *this - o;
    btVector3 y;
 
    y = wAxis.cross( *this );
10   
11      return ( o + x * btCos( angle ) + y * btSin( angle ) );
12  }

在win32中,btVector3还会使用sse指令加速操作:

比如:

#ifdef BT_USE_SSE // _WIN32
    union {
        __m128 mVec128;
        btScalar    m_floats[4];
    };
    SIMD_FORCE_INLINE    __m128    get128() const
    {
        return mVec128;
    }
10      SIMD_FORCE_INLINE    void    set128(__m128 v128)
11      {
12          mVec128 = v128;
13      }
14  #else
15      btScalar    m_floats[4];
16  #endif

 

3、 btQuaternion

     这是bullet中四元数类。在3D数学中,四元数可以用来表示物体的方位和旋转。另外,也可以使用矩阵或欧拉角的方式表示旋转,它们之间可以相互转化。

     我们知道四元数通过一个方向轴和一个旋转角表示物体的方位。

     在Bullet中,我们常通过设置旋转方向和角度的方法来设置四元数,单位化的四元数表示为:

       http://s14/middle/61feffe149736dc14902d&amp;690

     其中,u是旋转向量,alpha角是旋转角度。一个向量v被一个四元数q旋转的操作为:

     http://s6/middle/61feffe149736dc8efa05&amp;690

     在btQuaternion中,通过函数SetRotation我们来设置某个方向,一定角度的四元数。

  
    void setRotation(const btVector3& axis, const btScalar& angle)
    {
        btScalar d = axis.length();
        btAssert(d != btScalar(0.0));
        btScalar s = btSin(angle * btScalar(0.5)) / d;
        setValue(axis.x() * s, axis.y() * s, axis.z() * s, 
10              btCos(angle * btScalar(0.5)));
11      }

 

另外,btQuaternion也包括了欧拉角和四元数的转化,我们通过void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)来直接设置欧拉角,函数内部会转化为相应的四元数值。【yaw表示绕y轴旋转角度,pich绕x轴旋转角度,roll绕z轴旋转角度

另外一个重要的函数是slerp,它在两个四元数之间进行平滑插入操作,常用插值动画中使用该函数。

  
    btQuaternion slerp(const btQuaternion& q, const btScalar& t) const
    {
        btScalar theta = angle(q);
        if (theta != btScalar(0.0))
        {
10              btScalar d = btScalar(1.0) / btSin(theta);
11              btScalar s0 = btSin((btScalar(1.0) - t) * theta);
12              btScalar s1 = btSin(t * theta);   
13                          if (dot(q) < 0) // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp
14                            return btQuaternion((m_floats[0] * s0 + -q.x() * s1) * d,
15                                                (m_floats[1] * s0 + -q.y() * s1) * d,
16                                                (m_floats[2] * s0 + -q.z() * s1) * d,
17                                                (m_floats[3] * s0 + -q.m_floats[3] * s1) * d);
18                          else
19                            return btQuaternion((m_floats[0] * s0 + q.x() * s1) * d,
20                                                (m_floats[1] * s0 + q.y() * s1) * d,
21                                                (m_floats[2] * s0 + q.z() * s1) * d,
22                                                (m_floats[3] * s0 + q.m_floats[3] * s1) * d);
23                          
24          }
25          else
26          {
27              return *this;
28          }
29      }

4、btMatrix3x3

       btMatrix3x3是一个3*3的矩阵,它可以和欧拉角和四元数之间相互转化。

       void setRotation(const btQuaternion& q)

       void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ)

      void getRotation(btQuaternion& q) const

       void getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const

       当然,也可以求转置矩阵、伴随矩阵等等。

        另外,diagonalize计算旋转矩阵R,具体解释可以看下编写这个函数的人如何解释:

http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=2562&start=0

 

5、btTransform

      该类同时表示位置和旋转。主要用于点或向量在不同坐标系统之间的转换。

      Bullet中使用右手坐标系,和OpenGL是一致的。

      http://s14/middle/61feffe149736dd21845d&amp;690 

    在btTransform中,旋转用m_basis表示,平移通过m_origin表示:

  ///Storage for the rotation
    btMatrix3x3 m_basis;
  ///Storage for the translation
    btVector3   m_origin;

    我们可以对btTransform实施平移、旋转操作。

    btTransform可以返回四元数表示的旋转:getRotation

    void setFromOpenGLMatrix(const btScalar *m)
    {
        m_basis.setFromOpenGLSubMatrix(m);
        m_origin.setValue(m[12],m[13],m[14]);
    }
 
  
    void getOpenGLMatrix(btScalar *m) const 
10      {
11          m_basis.getOpenGLSubMatrix(m);
12          m[12] = m_origin.x();
13          m[13] = m_origin.y();
14          m[14] = m_origin.z();
15          m[15] = btScalar(1.0);
16      }

getOpenGLMatrix返回btTransform表示的OpenGL矩阵(4*4).

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有