Создание камеры и матриц

Последнее обновление: 14.11.2015

Итак, создадим новый проект и в начале определим в классе игры три переменных, которые будут представлять используемые нами матрицы:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace First3DGame
{
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Matrix projectionMatrix; // матрица проекции
        Matrix viewMatrix; // матрица вида
        Matrix worldMatrix; // мировая матрица

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
		
        protected override void Initialize()
        {
            viewMatrix = Matrix.CreateLookAt(new Vector3(0, 0, 6), Vector3.Zero, Vector3.Up);

            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.PiOver4,
                (float)Window.ClientBounds.Width /
                (float)Window.ClientBounds.Height,
                1, 100);

            worldMatrix = Matrix.Identity;
			
            base.Initialize();
        }
		
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
        }

        protected override void UnloadContent()
        {
            
        }
        
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed 
				|| Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();
            
            base.Update(gameTime);
        }
        
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            base.Draw(gameTime);
        }
    }
}

В методе Initialize() переменные матриц инициализируются. Для создания матрицы вида используется следующее выражение:

viewMatrix = Matrix.CreateLookAt(new Vector3(0, 0, 6), Vector3.Zero, Vector3.Up);

Таким образом, камера, обозревающая трехмерную сцену, будет находиться в точке пространства с координатами {x=0, y=0, z=6}. При этом камера будет направлена на точку с нулевыми координатами. Чтобы не писать new Vector3(0, 0, 0), мы можем использовать более краткий вариант Vector3.Zero.

Управляя координатами первого вектора, мы можем приближать, либо отдалять камеру. Например, мы можем отдалиться от объекта - для этого надо увеличить координату z: new Vector3(0, 0, 20). А управляя координатами x и y можно поворачивать камеру соответственно вокруг осей X и Y.

Вектор Vector3.Up устанавливает вертикальную ориентацию камеры, фактически он представляет значение new Vector3(0, 1, 0), то есть камера будет прямо направлена вверх. Это стандартное значение, которое часто используется для настройки камеры.

Для создания матрицы проекции применяется выражение:

projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.PiOver4,
                (float)Window.ClientBounds.Width /
                (float)Window.ClientBounds.Height,
                1, 100);

Первый параметр имеет значение MathHelper.PiOver4. Эта константа представляет число PI деленное на 4, то есть 45°. Это стандартное значение, для трехмерных сцен, устанавливающее угол обзора. Например, угол обзора человека составляет 180°, учитывая периферическое зрение. Для трехмерных приложений вполне достаточно 45°. В приложениях для игровых консолей нередко используется 60°, а в играх под ПК - 80-100°

Кроме того, для вычисления значения мы можем использовать другое выражение: MathHelper.ToRadians(45f), в которое передается значение в градусах. Оно будет аналогично выше использованной константе.

Для вычисления аспектного отношения ширину окна игры делим на высоту. Если бы наше приложение занимало бы весь экран, то тогда можно было бы проще использовать встроенное значение GraphicsDevice.DisplayMode.AspectRatio

Видимое пространство определяется значениями 1 и 100. Здесь надо учитывать, что если мы будем использовать большие значения, например, 1 и 10000, то это может сказаться на производительности, так как будут отображаться все объекты из этого пространства.

Мировая матрица указывает на позицию, в которой будет отрисосываться объект. В нашем случае пока никаких объектов нет, поэтому устанавливаем начальный вектор new Vector3(0,0,0), который также можно получить из значения Vector3.Identity:

worldMatrix = Matrix.Identity;

Таким образом, если бы у нас был объект, то он отрисовывался в соответствии с этой матрицей в точке (0, 0, 0). Если бы нам надо было бы задать другую точку, то можно было бы применить метод Matrix.CreateWorld:

worldMatrix = Matrix.CreateWorld(new Vector3(0, 0, 0), Vector3.Forward, Vector3.Up);

Первый вектор, передаваемый в этот метод, также указывает на точку отрисовки объекта, а значение Vector3.Forward представляет вектор направления, который имеет значения (0, 0, −1).

Итак, мы разобрали используемые матрицы, и теперь займемся рисованием объектов.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850