上节内容中,我们让物体拥有了最基本的平移和缩放的运动。现在我们来看三大运动之一的旋转运动。
同上节的知识一样,要让物体发生旋转,只需要在对应的坐标轴上与一个矩阵相乘。这个矩阵的构造方法有三种,分别是:
Matrix CreateRotationX(float radians);
Matrix CreateRotationY(floatradians);
Matrix CreateRotationZ(float radians);
代表在x、y、z三个坐标轴上的旋转角度,其中radians是弧度表示,如果想使用我们熟悉的角度的话,可以使用MathHelper.ToRadians(10)进行转换。
除了沿着坐标轴旋转以外,还有一种是采用飞行器的偏航、翻滚、俯仰表示方式进行的旋转,使用的矩阵构造方法是:
Matrix CreateFromYawPitchRoll(float yaw, float pitch, float roll);
有兴趣的朋友可以自行学习。
还是沿用上节课我们建好的XNA项目,在VS2010中打开该项目。打开Game1.cs文件,我们来修改Game1类。为其添加成员变量,代表旋转矩阵:
Matrix rotateMatrix=Matrix.Identity;
同时为了便于观察,我们将上节使用的scaleMatrix取值为0.5倍的缩放:
Matrixs caleMatrix = Matrix.CreateScale(0.5f);
然后在Draw()方法中修改basicEffect对象的World属性:
basicEffect.World= scaleMatrix * translateMatrix * rotateMatrix;
在Update()方法中去掉对scaleMatrix的变化并增加对rotateMatrix的处理:
//scaleMatrix= Matrix.CreateScale(0.9f);
rotateMatrix*= Matrix.CreateRotationZ(MathHelper.ToRadians(10));
也即每次点击屏幕产生10度的旋转。
运行程序,观察旋转的结果。然后尝试将Draw()中的
basicEffect.World= scaleMatrix * translateMatrix * rotateMatrix;
改成
basicEffect.World= scaleMatrix * rotateMatrix * translateMatrix;
来观察对旋转的影响。从中可以看出,前者是先沿着物体的x转产生了平移,然后再按平移后所在的位置的z轴进行旋转,产生了像螺线一样的运动。而后者是先沿z轴进行了旋转,再沿x轴进行平移,产生了一边向屏幕右侧平移同时绕自身z轴旋转的效果。因此,在实际项目中要小心处理矩阵运算。
另外,也可以修改代码,观察沿x、y轴旋转的情况。
当我们让三角形绕y轴旋转的时候,会发现一个奇怪的现象,随着物体的旋转,当物体的背面朝向我们时,我们就看不到它了。其实这是渲染引擎的优化设置,因为对于物体的背面,实际上是不进行渲染的,也就是常说的背面消隐,有需要关注的朋友可以查找相关的资料,在这里要想取消背面消隐选项,只需要修改一下GraphicsDevice的栅格化参数,即在Draw()方法中加入下面的代码:
~~~
GraphicsDevice.Clear(Color.CornflowerBlue);
RasterizerState rasterizerState = new RasterizerState();
rasterizerState.CullMode = CullMode.None;
GraphicsDevice.RasterizerState = rasterizerState;
~~~
附本节Game1类的完整源码:
~~~
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
Camera camera;
Matrix world = Matrix.Identity;
BasicEffect basicEffect;
VertexPositionColor[] triangle;
Matrix translateMatrix=Matrix.Identity;
Matrix scaleMatrix = Matrix.CreateScale(0.5f);
Matrix rotateMatrix = Matrix.Identity;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
// Frame rate is 30 fps by default for Windows Phone.
TargetElapsedTime = TimeSpan.FromTicks(333333);
// Extend battery life under lock.
InactiveSleepTime = TimeSpan.FromSeconds(1);
graphics.IsFullScreen = true;
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
camera = new Camera(this, new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up, MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 1.0f, 50.0f);
Components.Add(camera);
basicEffect = new BasicEffect(GraphicsDevice);
triangle = new VertexPositionColor[]{
new VertexPositionColor(new Vector3(0, 1, 0), Color.Red),
new VertexPositionColor(new Vector3(1, -1, 0), Color.Green),
new VertexPositionColor(new Vector3(-1,-1, 0), Color.Blue)
};
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
TouchPanel.EnabledGestures = GestureType.Tap;
if (TouchPanel.IsGestureAvailable)
{
GestureSample gestureSample = TouchPanel.ReadGesture();
if (gestureSample.GestureType == GestureType.Tap)
{
translateMatrix *= Matrix.CreateTranslation(0.3f, 0, 0);
//scaleMatrix = Matrix.CreateScale(0.9f);
rotateMatrix *= Matrix.CreateRotationY(MathHelper.ToRadians(10));
}
}
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
RasterizerState rasterizerState = new RasterizerState();
rasterizerState.CullMode = CullMode.None;
GraphicsDevice.RasterizerState = rasterizerState;
basicEffect.World = scaleMatrix * translateMatrix * rotateMatrix;
basicEffect.View = camera.view;
basicEffect.Projection = camera.projection;
foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, triangle, 0, 1);
}
base.Draw(gameTime);
}
}
~~~
——欢迎转载,请注明出处 [http://blog.csdn.net/caowenbin](http://blog.csdn.net/caowenbin) ——
- 前言
- Windows Phone 7开发环境初体验
- Windows Phone 7 3D开发中使用纹理贴图
- 在Windows Phone中进行3D开发之一坐标系
- 在Windows Phone中进行3D开发之二摄像机
- 在Windows Phone中进行3D开发之三空间
- 在Windows Phone中进行3D开发之四三角形
- 在Windows Phone中进行3D开发之五平移缩放
- 在Windows Phone中进行3D开发之六旋转
- 在Windows Phone中进行3D开发之七纹理
- 在Windows Phone中进行3D开发之八光照
- 在Windows Phone中进行3D开发之九模型
- 在Windows Phone中进行3D开发之十组件
- 在Windows Phone中进行3D开发之十一天空
- 在Windows Phone中进行3D开发之十二飞行
- 在Windows Phone中进行3D开发之十三阳光
- 在Windows Phone中进行3D开发之后记(附源码)