Opengl屏幕限制在不同的深度

时间:2014-07-27 02:21:27

标签: android opengl-es coordinates collision depth

我尝试使用opengl es 2.0建立一个使用碰撞检测的3D粒子模拟,但我无法弄清楚如何检测与屏幕边缘的碰撞。

如果我正确地调整平截头体和摄像机位置,当粒子处于0.0 z深度时,我可以使X和Y屏幕限制在-1.0和1.0之间或多或少,但问题是找到屏幕边缘时粒子z位置不为零。

基本上,我需要检查粒子是否在每个深度的屏幕范围内。有谁知道怎么做?

谢谢!

1 个答案:

答案 0 :(得分:0)

答案是截头飞机。下面是C ++ / Direct3D示例,您可能会发现它很有用:

class Frustum
{
public:
    Plane plane[6]; // array of planes
public:
    // default constructor
    Frustum() 
    {
        for( unsigned int i=0; i<6; i++ ) plane[i] = Plane( 0,0,0,0 );
    }
    // perspective projection frustum
    Frustum( Matrix* matrix, 
             unsigned int width, unsigned int height, 
             float fov, float nearClip, float farClip, 
             float xFactor, float yFactor )
    {
    // frustrum planes
    Vector r_origin( matrix->_41, matrix->_42, matrix->_43 );
    Vector vpn( matrix->_31, matrix->_32, matrix->_33 );
    Vector vright( matrix->_11, matrix->_12, matrix->_13 );
    Vector vup( matrix->_21, matrix->_22, matrix->_23 );

    // for right-handed coordinate system
    vpn *= - 1, vright *= -1, vup *= -1;

    // somewhat an offset
    float orgOffset = D3DXVec3Dot( &r_origin, &vpn );

    // far plane
    plane[4].a = -vpn.x;
    plane[4].b = -vpn.y;
    plane[4].c = -vpn.z;
    plane[4].d = -farClip - orgOffset;

    // near plane
    plane[5].a = vpn.x;
    plane[5].b = vpn.y;
    plane[5].c = vpn.z;
    plane[5].d = nearClip + orgOffset;

    // field of view
    float fovx = fov * xFactor; 
    float fovy = fovx * height/width * yFactor; 
    fovx *= 0.5f, fovy *= 0.5f;
    float tanx = tan( D3DXToRadian(fovx) );
    float tany = tan( D3DXToRadian(fovy) );

    // left plane
    Vector n = (vpn * tanx) + vright;
    D3DXVec3Normalize( &n, &n );
    plane[0].a = n.x;
    plane[0].b = n.y;
    plane[0].c = n.z;

    // right plane
    n = (vpn * tanx) - vright;
    D3DXVec3Normalize( &n, &n );
    plane[1].a = n.x;
    plane[1].b = n.y;
    plane[1].c = n.z;

    // bottom plane
    n = (vpn * tany) + vup;
    D3DXVec3Normalize( &n, &n );
    plane[2].a = n.x;
    plane[2].b = n.y;
    plane[2].c = n.z;

    // top plane
    n = (vpn * tany) - vup;
    D3DXVec3Normalize( &n, &n );
    plane[3].a = n.x;
    plane[3].b = n.y;
    plane[3].c = n.z;

    for( unsigned int i=0; i < 4; i++ )
    {
        n.x = plane[i].a;
        n.y = plane[i].b;
        n.z = plane[i].c;
        plane[i].d = D3DXVec3Dot( &n, &r_origin );
    }
    }
};

请注意,要计算与平截头体平面的交点,您必须使用粒子的世界空间坐标。