PhysX中PxTransform类的使用

 

physx中的PxTransForm类:https://github.com/NVIDIAGameWorks/PhysX/blob/4.1/pxshared/include/foundation/PxTransform.h

PxQuat类 https://github.com/NVIDIAGameWorks/PhysX/blob/4.1/pxshared/include/foundation/PxQuat.h


Summary:

PxTransform类用于表示刚体在一个坐标系的位姿,即,表示空间空的一个坐标系相对于另一个坐标系的位姿。
包括两个成员:
PxVec3 p;//原点位置
PxQuat q;//坐标系姿态


 

验证

亲自动手验证了:

//得到 "绕空间向量vec旋转angle弧度"这个动作对应的四元数
//angle:rad
PxQuat getQuatFromVectorAndAngle(PxVec3 vec, float angle/*,   float& x, float& y, float& z,float& real*/)
{
    PxQuat result;
    //绕vec旋转angle 弧度对应的四元数的各个元素:
    float real = std::cosf(angle / 2.0f);
    float x = vec.x*std::sinf(angle / 2.0f);
    float y = vec.y*std::sinf(angle / 2.0f);
    float z = vec.z*std::sinf(angle / 2.0f);

    //return PxQuat(real,x,y,z);//wrong
    return PxQuat(x, y, z,real);//ok/----PxQuat::nw corresponds to real par!!!
}

float pi = 3.1415926;
    

//test move----------------------------
PxTransform transform1(PxVec3(10.f, 0.f, 0.f), PxQuat(PxIdentity));//相对于全局系,沿x轴移动10得到transform1,transform1代表这一个坐标系。
    PxTransform transform2(PxVec3(15.f, 0.f, 0.f), PxQuat(PxIdentity));//x轴移动15
//将transform2看做以transform1为参考,即其相对于transform1的原点移动了10,则transform2与全局系的关系:
PxTransform transform2_to_glob = transform1 * transform2;//即transform2系在全局系下的位姿
//expeted result:
PxVec3 vecExp = PxVec3(25.f, 0.f, 0.f);//另外,姿态是重合的

//设在transform2系下有一个向量(35,0,0),求其在全局系下的坐标
PxVec3 vecInTransform2 = PxVec3(35.f, 0.f, 0.f);
PxVec3 vecInGlob = transform2_to_glob.transform(vecInTransform2);//与之前的认知一样:坐标系A经过一系列变化得到坐标系B,两者之间的关系为4*4矩阵Trans,
                                                                 //Trans的旋转矩阵部分在左上角,为3*3矩阵,其第一列为B系的x轴在A系下的表示..,
                                                                 //空间向量在B系下的表示为vec,则在A系下为Trans*vec
//expeted result:
PxVec3 vecInGlobExp = PxVec3(25.f+35.f, 0.f, 0.f);

//设在全局系下有一个向量(5,0,0),求其在transform2系下的坐标:
PxVec3 vecGbolTo2 = transform2_to_glob.transformInv(PxVec3(5.f, 0.f, 0.f));//OK
//expeted result:
PxVec3 vecGbolTo2Exp = PxVec3(-20.f, 0.f, 0.f);


//test rotate----------------------------
PxTransform transformA(PxVec3(0.f, 0.f, 0.f), getQuatFromVectorAndAngle(PxVec3(0.f, 0.f, 1.0f), pi/2.0f));//相对于全局系,绕z轴转90度到transformA。
PxTransform transformB(PxVec3(0.f, 0.f, 0.f), getQuatFromVectorAndAngle(PxVec3(0.f, 0.f, 1.0f), pi/2.0f));//绕z轴转90度
//将transformB看做以transformA为参考,即其绕transformA的z轴转动了90度,则transformB与全局系的关系:
PxTransform transformB_to_glob = transformA * transformB;////即transformB系在全局系下的位姿
//expeted result:
PxQuat QuatExp = getQuatFromVectorAndAngle(PxVec3(0.f, 0.f, 1.0f), pi);//全局系绕自身z轴转180度

//设在transformB系下有一个向量(30,0,0),求其在全局系下的坐标
PxVec3 vecInTransformB = PxVec3(30.f, 0.f, 0.f);
PxVec3 vecBInGlob = transformB_to_glob.transform(vecInTransformB);
//expeted result:
PxVec3 vecBInGlobExp = PxVec3(-30.f, 0.f, 0.f);

//设在transformB系下有一个位姿:位置是PxVec3(30,0,0),姿态是绕z轴旋转-90度:getQuatFromVectorAndAngle(PxVec3(0.f, 0.f, 1.0f), -pi / 2.0f),
//求其在全局系下的坐标
PxTransform TransformInB(PxVec3(30.f, 0.f, 0.f), getQuatFromVectorAndAngle(PxVec3(0.f, 0.f, 1.0f), -pi / 2.0f));
PxTransform TransformInBInGlob = transformB_to_glob.transform(TransformInB);
//expeted result:
PxTransform TransformInBInGlobExp(PxVec3(-30.f, 0.f, 0.f), getQuatFromVectorAndAngle(PxVec3(0.f, 0.f, 1.0f), pi / 2.0f));


//test rotate and move----------------------------
PxTransform transformAA(PxVec3(10.f, 0.f, 0.f), PxQuat(PxIdentity));//相对于全局系,沿x轴移动10得到transformAA。
PxTransform transformBB(PxVec3(0.f, 0.f, 0.f), getQuatFromVectorAndAngle(PxVec3(0.f, 0.f, 1.0f), pi / 2.0f));//绕z轴转90度
//将transformB看做以transformA为参考,即其绕transformA的z轴转动了90度,则transformB与全局系的关系:
PxTransform transformBB_to_glob = transformAA * transformBB;
//expeted result:
PxQuat QuatBBExp = getQuatFromVectorAndAngle(PxVec3(0.f, 0.f, 1.0f), pi / 2.0f);
PxVec3 vecBBExp = PxVec3(10.f, 0.f, 0.f);

//设在transformBB系下有一个向量(30,0,0),求其在全局系下的坐标
PxVec3 vecInTransformBB = PxVec3(30.f, 0.f, 0.f);
PxVec3 vecInBBGlob = transformBB_to_glob.transform(vecInTransformBB);
//expeted result:
PxVec3 vecBBInGlobExp = PxVec3(10.f, 30.f, 0.f);//drwa it

 

summary

 

summary:注意比较PxTransform类的这四个函数:

//如上,设A系经过一系列变换得到B系,两者之间的关系已知,空间中一个固定点,其在B系中的表达为入参input,该函数据此求出该空间点在A系中的表示。
//因为B系的原点与A系可能不重合,所以要考虑加上p, p即为B系得原点在A系中得表示哦/。
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 transform(const PxVec3& input) const
    {
        PX_SHARED_ASSERT(isFinite());
        return q.rotate(input) + p;
    }


//如上,设A系经过一系列变换得到B系,两者之间的关系已知,空间中一个固定点,其在A系中的表达为入参input,该函数据此求出该空间点在B系中的表示。
//对于input - p,其中input和p都是在A系中得表达式,input - p即为以B系原点为起点指向空间点的向量在A系中的表示 ,
//然后旋转input - p即可得到空间点在B系中的表示./
    PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 transformInv(const PxVec3& input) const
    {
        PX_SHARED_ASSERT(isFinite());
        return q.rotateInv(input - p);
    }

//如上,设A系经过一系列变换得到B系,两者之间的关系已知. rotate和rotateInv函数相当于仅仅考虑两个坐标系的姿态关系。
//rotate(const PxVec3& input)函数的入参为B系中的向量,该函数将其转换为A系中的表达式。--想象A B两系原点重合。
//rotateInv(const PxVec3& input)函数的入参为A系中的向量,该函数将其转换为B系中的表达式.
    PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 rotate(const PxVec3& input) const
    {
        PX_SHARED_ASSERT(isFinite());
        return q.rotate(input);
    }

    PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 rotateInv(const PxVec3& input) const
    {
        PX_SHARED_ASSERT(isFinite());
        return q.rotateInv(input);
    }


//如上,设A系经过一系列变换得到B系,两者之间的关系已知.该函数的入参为B系中的一个刚体的位姿src,该函数将刚体在B系下的位置src.p转换为
//A系下表示, 将刚体在B系下的姿态src.q转换为A系下表示, 并将两者组合起来以一个PxTransform对象返回。 operator*函数就是基于此函数的。
//由此函数的实现部分可以推知:两个四元数连乘法的意义,B系得姿态在A系中为q,刚体在B系中的姿态为src.q,q * src.q即为刚体在A系统下的姿态。
    //! Transform transform to parent (returns compound transform: first src, then *this)
    PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransform transform(const PxTransform& src) const
    {
        PX_SHARED_ASSERT(src.isSane());
        PX_SHARED_ASSERT(isSane());
        // src = [srct, srcr] -> [r*srct + t, r*srcr]
        return PxTransform(q.rotate(src.p) + p, q * src.q);
    }

    PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransform operator*(const PxTransform& x) const
    {
        PX_SHARED_ASSERT(x.isSane());
        return transform(x);
    }


    //该函数应该是用4*4坐标变换矩阵实例化一个PxTransform,体现了如何将3*3旋转矩阵转换为四元数。
    PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransform(const PxMat44& m); // defined in PxMat44.h

 

posted @ 2020-07-09 22:54  JadeCicada  阅读(902)  评论(0编辑  收藏  举报