正文

游戏数学(40)

精通C#游戏编程 作者:(英)斯库勒


 

使用这段代码,可以对我们将使用的任何矩阵求逆。

关于Matrix类的内容就是这些,现在这个类对于2D和3D应用程序都适用。接下来就实际使用这个类。

8.5.7  对精灵执行矩阵操作

创建一个新的游戏状态MatrixTestState。这个状态将绘制一个精灵,并对该精灵应用各种矩阵。下面是绘制精灵的代码,你应该已经很熟悉这段代码了。

class MatrixTestState : IGameObject

{

Sprite _faceSprite = new Sprite();

Renderer _renderer = new Renderer();

public MatrixTestState(TextureManager textureManager)

{

_faceSprite.Texture = textureManager.Get("face");

Gl.glEnable(Gl.GL_TEXTURE_2D);

}

public void Render()

{

Gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);

_renderer.DrawSprite(_faceSprite);

_renderer.Render();

}

public void Update(double elapsedTime)

{

}

}

代码中使用了前面章节中用到的脸部精灵。矩阵将在MatrixTestState构造函数中应用到精灵上。

Matrix m = new Matrix();

m.SetRotate(new Vector(0, 0, 1), Math.PI/5);

for (int i = 0; i < _faceSprite.VertexPositions.Length; i++ )

{

_faceSprite.VertexPositions[i] *= m;

}

运行代码,可以注意到脸部已经被旋转过了。旋转是沿着Z轴(0,0,1)执行的,这是从屏幕内部指向外部的轴。把脸部精灵想象成屏幕上的一张纸。为了进行旋转,你在纸上按了一个图钉,使其附着到屏幕上了。图钉就代表Z轴。旋转纸精灵就是在沿着该轴旋转。对于正射投影中的2D对象,Y轴和Z轴对于旋转来说没有什么用处,但是在3D游戏中就不一样了。任何一个归一化的轴都可以用于旋转对象,不只是X、Y和Z这3个主轴。

在代码示例中,旋转量以弧度Math.PI/5给出,这个值等于36°。旋转矩阵将被应用到组成精灵的每个顶点。我们现在已经使用了一个稍微旋转了精灵的矩阵。接下来就添加一个缩放精灵的矩阵。通过使用矩阵乘法,缩放矩阵将与旋转矩阵结合起来。修改构造函数中的已有代码,使其如下所示。

Matrix m = new Matrix();

m.SetRotate(new Vector(0, 0, 1),Math.PI/5);

Matrix mScale = new Matrix();

mScale.SetScale(new Vector(2.0, 2.0, 0.0));

m *= mScale;

for (int i = 0; i < _faceSprite.VertexPositions.Length; i++ )

{

_faceSprite.VertexPositions[i] *= m;

}

这段代码创建的缩放矩阵将对象在X轴和Y轴上放大一倍。这个矩阵和旋转矩阵通过矩阵乘法结合到一起,然后把结果赋值给矩阵m。然后这个合并后的矩阵m被应用到脸部精灵,以缩放和旋转该精灵。矩阵乘法的顺序很重要:将矩阵a和矩阵b相乘的结果不一定与将矩阵b和矩阵a相乘的结果相同。尝试采用不同的矩阵,以熟悉它们之间相互组合后可以得到什么样的结果。

最后的代码段将演示逆矩阵。逆矩阵会逆转一个矩阵操作。如果将旋转-缩放矩阵乘以其逆矩阵,结果将是一个单位矩阵。对精灵应用单位矩阵时,不会产生任何效果。

Matrix m = new Matrix();

m.SetRotate(new Vector(0, 0, 1),Math.PI/5);

Matrix mScale = new Matrix();

mScale.SetScale(new Vector(2.0, 2.0, 2.0));

m *= mScale;

Vector scale = m.GetScale();

m *= m.Inverse();

for (int i = 0; i < _faceSprite.VertexPositions.Length; i++ )

{

_faceSprite.VertexPositions[i] *= m;

}

你还可以尝试平移矩阵,并试着以不同的顺序组合矩阵,看看会得到什么效果。


上一章目录下一章

Copyright © 读书网 www.dushu.com 2005-2020, All Rights Reserved.
鄂ICP备15019699号 鄂公网安备 42010302001612号