差分

ナビゲーションに移動 検索に移動

MonoGameのカメラを作る

5,306 バイト追加, 2017年11月9日 (木) 10:33
ページの作成:「カメラクラスを作っておくと捗る。 <source lang="csharp"> using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework;...」
カメラクラスを作っておくと捗る。

<source lang="csharp">
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Draw3D
{
public class Camera : GameComponent
{
public Camera(Game game) : base(game)
{
_aspectRatio = game.GraphicsDevice.Viewport.AspectRatio;

UpdateProjection();
UpdateView();

this.Enabled = true;
}

/// <summary>
/// カメラの位置
/// </summary>
public Vector3 Position = new Vector3(0, 10, 10);

/// <summary>
/// カメラの焦点
/// </summary>
public Vector3 Target = Vector3.Zero;

/// <summary>
/// カメラの向き
/// </summary>
/// <value>The direction.</value>
public Vector3 Direction
{
get
{
return Vector3.Normalize(this.Position - this.Target);
}
set
{
var norm = Vector3.Normalize(value);
this.Target = this.Position + norm;
}
}

/// <summary>
/// カメラの上(傾き)
/// フライトシミュレーターなどは飛行機が傾けばカメラも傾くアレ。
/// ラジアンではなく度で指定する。
/// </summary>
public float Angle = 0;

/// <summary>
/// この距離より近いオブジェクトが描画されなくなる。
/// </summary>
/// <value>The near plane distance.</value>
public float NearPlaneDistance {
get { return _nearPlaneDistance; }
set { _nearPlaneDistance = value; UpdateProjection(); }
}

private float _nearPlaneDistance = 0.1f;

/// <summary>
/// この距離より遠いオブジェクトが描画されなくなる。
/// </summary>
/// <value>The far plane distance.</value>
public float FarPlaneDistance {
get { return _farPlaneDistance; }
set { _farPlaneDistance = value; UpdateProjection(); }
}

private float _farPlaneDistance = 10000f;

/// <summary>
/// カメラの視野角(1〜179)
/// 肉眼は46度くらいらしい(諸説ある)。
/// 超広角レンズ、または魚眼レンズ - 最大180度の画角(それよりさらに広いものもある)
/// 広角レンズ - 一般に 100度から60度
/// 標準レンズ - 一般に 50度から 25度
/// 望遠レンズ - 一般に 15度から 10度
/// 超望遠レンズ - 一般に 8度から 1度
/// </summary>
/// <value>The field of view.</value>
public float FieldOfView {
get { return _fieldOfView; }
set
{
if (value <= 0)
{
_fieldOfView = 0.01f;
}
else if (180 <= value)
{
_fieldOfView = 179.99f;
}
else
{
_fieldOfView = value;
}
UpdateProjection();
}
}

private float _fieldOfView = 46;

/// <summary>
/// カメラのアスペクト比
/// </summary>
/// <value>The aspect ratio.</value>
public float AspectRatio {
get { return _aspectRatio; }
set { _aspectRatio = value; UpdateProjection(); }
}

private float _aspectRatio;

// --------------------------------

public Matrix View { get { return _view; } }

private Matrix _view;

public Matrix Projection { get { return _projection; } }

private Matrix _projection;

public Matrix ViewProjection { get { return _view * _projection; } }


private void UpdateProjection()
{
//var viewport = this.Game.GraphicsDevice.Viewport;
//_projection = Matrix.CreateOrthographicOffCenter(
// (viewport.Width / -2) * _aspectRatio,
// (viewport.Width / +2) * _aspectRatio,
// (viewport.Height / -2),
// (viewport.Height / +2),
// _nearPlaneDistance,
// _farPlaneDistance);

var fieldOfViewRadian = MathHelper.ToRadians(_fieldOfView);

_projection = Matrix.CreatePerspectiveFieldOfView(
fieldOfViewRadian,
_aspectRatio,
_nearPlaneDistance,
_farPlaneDistance);
}

private void UpdateView()
{
var radian = MathHelper.ToRadians(this.Angle);
var rotate = Matrix.CreateRotationZ(radian);
var upVector = Vector3.Transform(Vector3.Up, rotate);
_view = Matrix.CreateLookAt(this.Position, Target, upVector);
}

public override void Update(GameTime gameTime)
{
if (this.Enabled)
{
this.UpdateView();
}
base.Update(gameTime);
}
}
}
</source>

[[category: MonoGame]]
匿名利用者

案内メニュー