XNA中的拾取与碰撞检测

来源:互联网 发布:php 7 编程实战 pdf 编辑:程序博客网 时间:2024/06/05 02:38
 

一、  拾取与碰撞检测

1、   碰撞检测

XNA中的碰撞检测是通过测试两个物体的包围盒或者包围球是否相交来实现的。XNA为模型的每个Meshe建立一个包围盒和包围球。

1)、获取包围球

         BoundingSphere c1BoundingSphere = model1.Meshes[i].BoundingSphere;

     BoundingSphere c2BoundingSphere = model2.Meshes[j].BoundingSphere;

2)、判断两个包围球是否相交

     if (c1BoundingSphere.Intersects(c2BoundingSphere))

     返回值为true表示两模型相交,返回值为false表示两模型没有相交

2、   拾取

拾取是指通过鼠标来选中某个模型。

1)、获取当前鼠标状态

              MouseState mouseState = Mouse.GetState();

2)、获取鼠标的位置信息

int mouseX = mouseState.X;

int mouseY = mouseState.Y;

          3)、构造摄像机坐标系下的两个点,分别代表了近点和远点

Vector3 nearsource = new Vector3((float)mouseX, (float)mouseY, 0f);

Vector3 farsource = new Vector3((float)mouseX, (float)mouseY, 1f);

         4)、将两个点通过逆投影矩阵转换为世界坐标系下的两个点

Matrix world = Matrix.CreateTranslation(0, 0, 0);

Vector3 nearPoint = graphics.GraphicsDevice.Viewport.Unproject(nearsource,

proj, view, world);

Vector3 farPoint = graphics.GraphicsDevice.Viewport.Unproject(farsource,

proj, view, world);

         5)、构造拾取射线

Vector3 direction = farPoint - nearPoint;

direction.Normalize();

Ray pickRay = new Ray(nearPoint, direction);

         6)、判断射线是否与模型Mesh的包围盒相交

              Nullable<float> result = pickRay.Intersects(sphere);

如果result.HasValue true并且result.Value < selectedDistance则认为物体被拾取。当射线与多个物体相交时可通过result.Value来判断谁在前面,值小的更靠近屏幕。在初始阶段我们将selectedDistance设置为最大值(float.MaxValue;)。

 

注:XNA为我们提供的拾取仅仅能够知道是否与某模型相交,无法提供与哪一点相交的信息,为此,我们可以通过让拾取射线与模型的某个三角片相交并求其交点的方法来实现。
原创粉丝点击