** DirectX9 3D ** ** 快速上手 ** ** 5
**
** By sssa2000
**
** 4/18/2005 ** **
**
这一章的内容相对很简单,控制 Mesh 的移动,旋转等等,其实这一切都是在对矩阵进行操作。在 DX 中,用到的变换有 3 种,一种是基于 Word 坐标系的,一种是基于 View 坐标系的,还有一种是基于投影的变换。而这些变换都是通过矩阵的运算来实现的,在 .Net 的托管环境下,实现这些操作相对于非托管来说简单一写,不用对矩阵的每个值运算。
关于矩阵的运算和变换的关系,很多文章都有分析, GameRes 也有很多这样的好文章,例如: http://dev.gameres.com/Program/Visual/3D/3DGame.mht 这里就有很详细的介绍。
我们这篇文章不研究细节,因为毕竟是快速开发,我们的目标就是用键盘控制读入的 Mesh 的运动。
其实在前面一篇文章中我们就有提到几个函数,只是没有介绍。我们来看看我们这一篇中要用到的几个简单的函数,从字面我们就可以判断出这些函数有什么用:
Matrix.RotateX 方法: public void RotateX ( float angle );
Matrix. RotateY 方法: public void RotateY ( float angle );
Matrix.RotateX 方法: public void RotateZ ( float angle );
Matrix.Translation 方法: public static Matrix Translation(float offsetx, float offsety, float offsetz);
好,我们现在重新打开上一次的读入 Mesh 的那个工程,我们现在要加入新的部分,既然是用键盘控制那么就要首先对键盘的状态进行分析:
String status=null;// 用于保存状态
protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e)
{
// Handle the escape key for quiting
if (e.KeyCode == Keys.Escape)
{
// Close the form and return
this .Close();
return ;
}
// Handle left and right keys
else if ((e.KeyCode == Keys.Left) || (e.KeyCode == Keys.NumPad4))
{
status="left"; // 向左旋转
}
else if ((e.KeyCode == Keys.Right) || (e.KeyCode == Keys.NumPad6))
{
status="right";// 向右旋转
}
else if ((e.KeyCode ==Keys.Up )||(e.KeyCode ==Keys.NumPad8 ))
{
status="up";// 向上旋转
}
else if ((e.KeyCode ==Keys.Down )||(e.KeyCode ==Keys.NumPad2 ))
{
status="down";// 向下旋转
}
else if (e.KeyCode ==Keys.Enter)
{
status="stop";// 停止旋转
}
else if (e.KeyCode ==Keys.W )
{
status="goahead";// 向前
}
else if (e.KeyCode ==Keys.S )
{
status="goback";// 向后
}
else if (e.KeyCode ==Keys.A)
{
status="goleft";// 向左
}
else if (e.KeyCode ==Keys.D )
{
status="goright";// 向右
}
}
很简单,以至于没什么可说的,下面就要对 Mesh 进行移动,由于我们观察的运动都是相对运动,所以无论你是对摄像机进行操作还是进行世界变换都是可以的,随你所好。我们对 DrawMesh 函数进行修改 , 主要是对状态的判断,然后对相应的矩阵进行变换:
private void DrawMesh( string stat)
if (stat=="left")
{
angle=angle+ 0.1f ;
device.Transform.World = Matrix.RotationY (angle);
}
else if (stat=="right")
{
angle=angle -0.1f ;
device.Transform.World = Matrix.RotationY (angle);
}
else if (stat=="up")
{
angle=angle+ 0.1f ;
device.Transform.World = Matrix.RotationX (angle);
}
else if (stat=="down")
{
angle=angle -0.1f ;
device.Transform.World = Matrix.RotationX (angle);
}
else if (stat=="stop")
{
angle= 0.0f ;
//device.Reset ()
}
else if (stat=="goahead")
{
v=v+ 0.1f ;
}
else if (stat=="goback")
{
v=v -0.1f ;
}
else if (stat=="goleft")
{
offsetx=offsetx+ 0.01f ;
device.Transform.World = Matrix.Translation(offsetx,0,0);
}
else if (stat=="goright")
{
offsetx=offsetx -0.01f ;
device.Transform.World = Matrix.Translation(offsetx,0,0);
}
for ( int i = 0; i < meshMaterials.Length; i++)
{
device.Material = meshMaterials[i];
device.SetTexture(0, meshTextures[i]);
mesh.DrawSubset(i);
}
</spa