代码改变世界

通过Flick手势来旋转3D模型的windows phone应用

2010-11-22 19:36  Aga.J  阅读(1744)  评论(0编辑  收藏  举报

    前面一篇文章中(Windows phone 手势,鼠标-学习笔记 )介绍了windows phone内和手势有关的API信息,目的就是为了完成这篇文章的旋转3D模型。

在这里我把在3D模型的实例化过程中的视角矩阵和投影矩阵等封装到一个叫相机camera的类中,这个类很简单

class Camera

    {

        Matrix view;

        Matrix projection;

        public Camera()

        {

        }

        public void initializeCamera( GraphicsDeviceManager graphics)

        {

            view = Matrix.CreateLookAt(new Vector3(1000, 900, 0),  

                                        new Vector3(0, 400, 0),

                                        Vector3.Up);

            projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, graphics.GraphicsDevice.Viewport.AspectRatio,

                                                           100, 10000);

        }

        public Matrix Projection

        {

            get { return projection; }

        }

        public Matrix View

        {

            get { return view; }

        }

    }

    要注意到view的初始化时的第一个参数就是相机的实际位置,第二个参数就是相机看的那一点。这里我的参数是根据我的模型设定的。

    然后接下来建立模型,我也把和模型相关的参数方法封装到一个类中,叫rotationModel

class RotationModel

    {

        private Model model;

        private Matrix rotation;                  

        private float rotationY;

        public ClickableModel()

        {

            rotationY = 0.4f;

            rotation = Matrix.CreateRotationY(rotationY);

        }

        public void loadModel(Model m)

        {

            model = m;

        }

        public ModelMeshCollection getMeshes()

        {

            return model.Meshes;

        }

        public void DrawModel(Camera camera)

        {

            Matrix world=rotation;

            Matrix view=camera.View;

            Matrix projection = camera.Projection;

            foreach (ModelMesh mesh in model.Meshes)

            {

                foreach (BasicEffect effect in mesh.Effects)

                {

                    effect.TextureEnabled = true;

                    effect.World = world;          

                    effect.View = view;           

                    effect.Projection = projection;

                    effect.EnableDefaultLighting();

                    effect.LightingEnabled = true;

                }

                mesh.Draw();

            }

        }

        public void changeRotationY(float value)

        {

            rotationY += value;

            rotation = Matrix.CreateRotationY(rotationY);

        }

        public Matrix Rotation

        {

            get { return rotation; }

        }

    }

    注意到这个类里面除了有模型的必要信息和方法外,还有一个rotationY的浮点类型的属性和private Matrix rotation;(其实这就是这个model的坐标矩阵),我所采用的方法是直接旋转这个模型来完成模型的旋转效果(当然,比较好的方法是选择camera,这一点是因为我刚接触3D的东西,一开始一直以为我的rotation操作的是camera,现在知道了其实一直在控制着模型,虽然这样,但是我们其实很容易可以把这种选择方法用在选择camera上)这里通过Matrix.CreateRotationY(rotationY);传入一个旋转量,实现绕Y轴旋转,最后更新rotation,这样每次进行模型的重画时,就会根据这个rotation来画出模型的位置。从而也实现了旋转的效果

    最后,当然是使用我们的手势来完成这样的旋转事件激发了

while (TouchPanel.IsGestureAvailable)

            {

                GestureSample gs = TouchPanel.ReadGesture();

                switch (gs.GestureType)

                {

                    case GestureType.Flick:

                        if (gs.Delta.X > 0)

                           rotationModel.changeRotationY(0.3f);

                        else

                            rotationModel.changeRotationY(-0.3f);

                        break;

                }

            }

    注意到这里应该按照介绍手势Windows phone 手势,鼠标-学习笔记 的那篇文章里说的,先初始化系统能接受的手势类别,再来对每个类别的手势处理进行初始化。

    最后在手势这里,我们可以很轻松的利用上一篇文章3D物体拾取及XNA实现(转)介绍的3D模型的拾取,在tap类型的手势捕获中,判断是否点击了3D模型。