如何从矩阵中获取Vector3

时间:2013-12-17 11:21:57

标签: c++ math matrix directx

我想开始用这个问题陈述我的目标, 我目前正在用C ++和DirectX创建一个小型游戏引擎,目前我需要在广告牌精灵(总是面对镜头的那种)和模型上进行光线投射。

对于我的旧式游戏,广告牌精灵的光线投射现在更加重要了,所以让我们完成模型光线投射。

我目前正在使用以下代码来测试我的精灵:

for(int i = 0; i < spriteObjs.size();i++)
    {
        BOOL hit = FALSE;
        FLOAT distToHit = 100;
        D3DXVECTOR3 v1 = D3DXVECTOR3((-2.5f*spriteObjs.at(i)->scaling.x)+spriteObjs.at(i)->position.x,(5*spriteObjs.at(i)->scaling.y)+spriteObjs.at(i)->position.y,0+spriteObjs.at(i)->position.z);
        D3DXVECTOR3 v2 = D3DXVECTOR3((2.5f*spriteObjs.at(i)->scaling.x)+spriteObjs.at(i)->position.x,(5*spriteObjs.at(i)->scaling.y)+spriteObjs.at(i)->position.y,0+spriteObjs.at(i)->position.z);
        D3DXVECTOR3 v3 = D3DXVECTOR3((-2.5f*spriteObjs.at(i)->scaling.x)+spriteObjs.at(i)->position.x,(-5*spriteObjs.at(i)->scaling.y)+spriteObjs.at(i)->position.y,0+spriteObjs.at(i)->position.z);
        D3DXVECTOR3 v4 = D3DXVECTOR3((2.5f*spriteObjs.at(i)->scaling.x)+spriteObjs.at(i)->position.x,(-5*spriteObjs.at(i)->scaling.y)+spriteObjs.at(i)->position.y,0+spriteObjs.at(i)->position.z);
        if(D3DXIntersectTri(&v1,&v2,&v3,&camera.position,&lookDir,NULL,NULL,&distToHit))
        {
            //cout << "hit target: "<<spriteObjs.at(i)->quad.textureName << "  at distance: " << distToHit << endl;
        }
        if(D3DXIntersectTri(&v2,&v3,&v4,&camera.position,&lookDir,NULL,NULL,&distToHit))
        {
            //cout << "hit target: "<<spriteObjs.at(i)->quad.textureName << "  at distance: " << distToHit << endl;
        }
    }

这导致在查看精灵然后测试光线时给出一个真,但是,这并不考虑精灵本身的视图矩阵给出的旋转,因此这适用于精灵的“前视图” ,但是当侧视它时(它是一个平面,所以它没有宽度)你将永远无法击中它..当然因为它是用它的脸朝向相机绘制的,你仍然看到精灵的正面是正常的。 / p>

但是在代码中这没有被反映出来,它只是一个静态四边形,所以我需要从世界矩阵(或倒置视图矩阵(您的选择))获得旋转并将其与数定义的向量3相乘/数学顶点的位置(在本例中为v1到v4)

关于我如何在四边形中定义顶点的一些额外代码(所以你得到2.5和5来自的原因)

VertexPosNorTex triangleVerts[] = 
{
    {D3DXVECTOR3(-2.5,5,0),D3DXVECTOR3(1,0,0),D3DXVECTOR2(0,0)},
    {D3DXVECTOR3(2.5,5,0),D3DXVECTOR3(1,0,0),D3DXVECTOR2(1,0)},
    {D3DXVECTOR3(-2.5,-5,0),D3DXVECTOR3(1,0,0),D3DXVECTOR2(0,1.5)},
    {D3DXVECTOR3(2.5,-5,0),D3DXVECTOR3(1,0,0),D3DXVECTOR2(1,1.5)},
};

这会导致四边形看起来像

   5
----------
|        |
|        |
|        |
|        |  10
|        |
|        |
|        |
----------

这将把sprite广告牌锚定点转到中间,我只使用上面的0.5 UV空间作为纹理(下部分离保持透明,所以你不会看到它(这有助于它看起来的问题)就像从更高的角度看时它们在地面上飞行一样)

所以..在给出足够的解释和我的问题的中途,这是

TL; DR

如何将旋转版本(矩阵)的顶点位置转换回Vector3,其位置处于旋转状态 (因此,例如,从矩阵中检索后,在(1,0,0)处旋转0的1个顶点将类似于(0.86,0,0.1314)。 (例子只是一个随机数,不是由任何代码或数学产生的)

2 个答案:

答案 0 :(得分:0)

我的FB页面上有人评论说:

只需使用D3DXVec3Transform或类似的东西变换顶点,你得到一个Vector4,但你可以简单地忽略变换矩阵的w分量。

- 我还没有测试过(我很快就会)但是我100%肯定这可以用我的代码,因为我已经有99%的功能在同一个功能中实现但我没有用它正确

答案 1 :(得分:0)

原油解决方案,但它确实有效..它不如从视图矩阵中检索旋转那样好(我会得到几乎不可能转换为eulers的四元数)但是它有效..

    for(int i = 0; i < spriteObjs.size();i++)
    {
        if(Vector3Distance(&spriteObjs.at(i)->position,&camera.position) < 150)
        {
            BOOL hit = FALSE;
            FLOAT distToHit = 100;

            float x = 1 * std::cos((angleX+90) * 3.141592f / 180);
            float z = 1 * std::sin((angleX+90) * 3.141592f / 180);
            D3DXVECTOR3 v1 = D3DXVECTOR3((-2.5f *spriteObjs.at(i)->scaling.x / 2)* x    + spriteObjs.at(i)->position.x  ,( 2.5f *spriteObjs.at(i)->scaling.y)   +spriteObjs.at(i)->position.y       ,(-2.5f *spriteObjs.at(i)->scaling.z / 2)* z + spriteObjs.at(i)->position.z);//
            D3DXVECTOR3 v2 = D3DXVECTOR3(( 2.5f *spriteObjs.at(i)->scaling.x / 2)* x    + spriteObjs.at(i)->position.x  ,( 2.5f *spriteObjs.at(i)->scaling.y)   +spriteObjs.at(i)->position.y       ,( 2.5f *spriteObjs.at(i)->scaling.z / 2)* z + spriteObjs.at(i)->position.z);
            D3DXVECTOR3 v3 = D3DXVECTOR3((-2.5f *spriteObjs.at(i)->scaling.x / 2)* x    + spriteObjs.at(i)->position.x  ,( -2.5f *spriteObjs.at(i)->scaling.y)  +spriteObjs.at(i)->position.y       ,(-2.5f *spriteObjs.at(i)->scaling.z / 2)* z + spriteObjs.at(i)->position.z);
            D3DXVECTOR3 v4 = D3DXVECTOR3(( 2.5f *spriteObjs.at(i)->scaling.x / 2)* x    + spriteObjs.at(i)->position.x  ,( -2.5f *spriteObjs.at(i)->scaling.y)  +spriteObjs.at(i)->position.y       ,( 2.5f *spriteObjs.at(i)->scaling.z / 2)* z + spriteObjs.at(i)->position.z);

            if(D3DXIntersectTri(&v1,&v2,&v3,&camera.position,&lookDir,NULL,NULL,&distToHit)) 
            {
                cout << "hit target: "<<spriteObjs.at(i)->objName << "  at distance: " << distToHit << endl;
            }
            if(D3DXIntersectTri(&v2,&v3,&v4,&camera.position,&lookDir,NULL,NULL,&distToHit)) 
            {
                cout << "hit target: "<<spriteObjs.at(i)->objName << "  at distance: " << distToHit << endl;
            }
        }
    }