射线与XNA中的3D四边形相交



,所以我成功地制作了射线,代表鼠标未注射到世界上,现在我需要检查该射线是否可以与Quad对象相交,这是我使用的代码获取射线:

public Ray GetMouseRay()
    {
        Vector2 mousePosition = new Vector2(cursor.getX(), cursor.getY());
        Vector3 nearPoint = new Vector3(mousePosition, 0);
        Vector3 farPoint = new Vector3(mousePosition, 1);
        nearPoint = viewport.Unproject(nearPoint, projectionMatrix, viewMatrix, Matrix.Identity);
        farPoint = viewport.Unproject(farPoint, projectionMatrix, viewMatrix, Matrix.Identity);
        Vector3 direction = farPoint - nearPoint;
        direction.Normalize();
        return new Ray(nearPoint, direction);
    }

类似地,这是我的四边形结构,我用它在3D空间中绘制"立方体世界"。 公共结构四边形 { public vector3起源; public vector3 Uppleft; public vector3 lowerft; public vector3 uppright; public vector3 Lowerright; public vector3正常; public vector3 up; public vector3左;

    public VertexPositionNormalTexture[] Vertices;
      public int[] Indexes;
    public short[] Indexes;

    public Quad( Vector3 origin, Vector3 normal, Vector3 up, 
        float width, float height )
    {
        Vertices = new VertexPositionNormalTexture[4];
        Indexes = new short[6];
        Origin = origin;
        Normal = normal;
        Up = up;
        // Calculate the quad corners
        Left = Vector3.Cross( normal, Up );
        Vector3 uppercenter = (Up * height / 2) + origin;
        UpperLeft = uppercenter + (Left * width / 2);
        UpperRight = uppercenter - (Left * width / 2);
        LowerLeft = UpperLeft - (Up * height);
        LowerRight = UpperRight - (Up * height);
        FillVertices();
    }
    private void FillVertices()
    {
        // Fill in texture coordinates to display full texture
        // on quad
        Vector2 textureUpperLeft = new Vector2( 0.0f, 0.0f );
        Vector2 textureUpperRight = new Vector2( 1.0f, 0.0f );
        Vector2 textureLowerLeft = new Vector2( 0.0f, 1.0f );
        Vector2 textureLowerRight = new Vector2( 1.0f, 1.0f );
        // Provide a normal for each vertex
        for (int i = 0; i < Vertices.Length; i++)
        {
            Vertices[i].Normal = Normal;
        }
        // Set the position and texture coordinate for each
        // vertex
        Vertices[0].Position = LowerLeft;
        Vertices[0].TextureCoordinate = textureLowerLeft;
        Vertices[1].Position = UpperLeft;
        Vertices[1].TextureCoordinate = textureUpperLeft;
        Vertices[2].Position = LowerRight;
        Vertices[2].TextureCoordinate = textureLowerRight;
        Vertices[3].Position = UpperRight;
        Vertices[3].TextureCoordinate = textureUpperRight;
        // Set the index buffer for each vertex, using
        // clockwise winding
        Indexes[0] = 0;
        Indexes[1] = 1;
        Indexes[2] = 2;
        Indexes[3] = 2;
        Indexes[4] = 1;
        Indexes[5] = 3;
    }
}

我发现射线类具有一个方法相交(),该方法将 plane struct作为参数,而平面结构则与构造函数中的原点相距正常和距离,但是我的平面有位置和正常的,而不是距离原点的距离,所以我无法转换它们。我如何检测我的射线是否与我的四边形结构相交?

编辑:我意识到我无法使用平面结构,因为它的尺寸不是有限的,并且不像我的四边形那样包含角落。我现在需要找到一种方法来检测此射线是否与我创建的四边形相交...

感谢您的阅读,我意识到这个问题有点冗长,并提前感谢。

我不确定它们的意思是"沿着正常距离距离"的含义,但是我认为这只是距离原点的距离。您可以从A vector3

上的长度属性中获得它

如果那不起作用,还有一个用于 plane的构造函数在平面上需要三个点:

public Plane (
     Vector3 point1,
     Vector3 point2,
     Vector3 point3
)

您可以将其与飞机上的任何3点(例如四方的角)一起使用。

由于您使用的是立方体,因此可以使用Ray.Intersects(Plane)方法。您只需要几个飞机。

确定了第一个相交点后,您可以为立方体的每个垂直面构造更多平面。然后,您可以使用Plane.Distance(Vector3)(我很确定存在或类似的东西)来确保您的观点在每对垂直平面之间。如果不是之间,那么您可以忽略交叉点。

并不是对您的问题的直接答案,但也许您发现这相关。

您是否考虑过构建边界盒对象并使用相交(ray)?http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.boundingbox.intersects.aspx

编辑1:这是我通常这样做的。根据您的数据结构,它也可能更容易优化(例如,如果您构造了较大的边界框以钻入其中)。

编辑2:根据Niko的建议:我不想从样本中发布相关代码(因为总共几页可以使上下文有意义),但我可以指出您对您感兴趣的部分in。

  1. 从http://xbox.create.msdn.com/en-us/education/catalog/sample/picking_triangle下载示例
  2. 光标底部文件包含您已经知道的内容,计算射线
  3. 转到game.cs文件。在那里,您会找到updatePicking(),该()调用rayintersectsmodel(...),它调用rayintersectstriangle(...)

射线的变换是此部分:

Matrix inverseTransform = Matrix.Invert( modelTransform );
ray.Position = Vector3.Transform( ray.Position, inverseTransform );
ray.Direction = Vector3.TransformNormal( ray.Direction, inverseTransform );

当然,您想走多深(您的采摘程度)当然可以满足您的需求,但是您有它。

相关内容

  • 没有找到相关文章

最新更新