В последнее время я преуспеваю в реализации столкновения с камерой первого лица и местности, но я ударил еще одну стену, которая дрожит при движении по карте высоты. Хотя это не такая необычная проблема, я не мог найти четкого решения или направления, которым я должен следовать, чтобы добиться желаемого эффекта. Может ли кто-нибудь предложить, как я могу адаптировать мою реализацию, чтобы сделать рендеринг гладким?XNA 4.0: движение камеры первого лица на джиттере местности
класс камеры:
public class Camera
{
public Matrix view { get; protected set; }
public Matrix projection { get; protected set; }
public Vector3 direction { get; protected set; }
public Vector3 side_direction { get; protected set; }
public Vector3 position { get; set; }
public Vector3 up { get; protected set; }
public float _rotationX { get; protected set; }
public float _rotationY { get; protected set; }
public float rotX
{
get { return _rotationX; }
set
{
_rotationX = value;
RotateX(value);
}
}
public float rotY
{
get { return _rotationY; }
set
{
_rotationY = value;
RotateY(value);
}
}
public Matrix rotationX;
public Matrix rotationY;
public Camera(Game game, Vector3 pos, Vector3 up)
: base(game)
{
this.direction = new Vector3(0, 0, 1);
this.side_direction = new Vector3(1, 0, 1);
this.rotationX = Matrix.Identity;
this.rotationY = Matrix.Identity;
this.position = pos;
this.up = up;
this.view = Matrix.CreateLookAt(pos, pos + direction, up);
this.projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.PiOver4, (float)Game.Window.ClientBounds.Width/
(float)Game.Window.ClientBounds.Height,
1, 3000);
}
public override void Initialize()
{
base.Initialize();
}
public void RotateX (float degree)
{
if (_rotationX + degree >= 89)
_rotationX = 89;
else if (_rotationX + degree <= -89)
_rotationX = -89;
else
_rotationX = _rotationX + degree;
float radians = MathHelper.ToRadians(_rotationX);
rotationX = Matrix.CreateRotationX(radians);
updateView();
}
public void RotateY (float degree)
{
_rotationY = (_rotationY + degree) % 360;
float radians = MathHelper.ToRadians(_rotationY);
rotationY = Matrix.CreateRotationY(radians);
updateView();
}
protected void updateView()
{
this.side_direction = Vector3.Transform(new Vector3(1, 0, 1), rotationX);
this.direction = Vector3.Transform(new Vector3(0, 0, 1), rotationX);
this.side_direction = Vector3.Transform(side_direction, rotationY);
this.direction = Vector3.Transform(direction, rotationY);
this.view = Matrix.CreateLookAt(position, position + direction, up);
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
}
public void moveForward(float p)
{
this.position = position + direction * p;
updateView();
}
public void moveSide(float p)
{
this.position = position + side_direction * p;
updateView();
}
public void moveForward(float p, Terrain t)
{
Vector3 tmp = position + direction * p;
tmp.Y = t.GetTerrainHeight(tmp.X, tmp.Z);
this.position = tmp;
updateView();
}
public void moveSide(float p, Terrain t)
{
Vector3 tmp = position + side_direction * p;
tmp.Y = t.GetTerrainHeight(tmp.X, tmp.Z);
this.position = tmp;
updateView();
}
public void Draw(ref BasicEffect effect)
{
effect.Projection = this.projection;
effect.View = this.view;
}
}
`
Что происходит с камерой, когда она дрожит? Вы считали [сглаживание] (http://en.wikipedia.org/wiki/Smoothing) движением? – Anko
Камера следит за одной точкой, которая является вектором положения камеры (Camera.position), матрица просмотра вычисляется из Camera.position и Camera.direction, а остальная часть - в функции moveForward (float, Terrain). Я не думаю, что сглаживание поможет, если камера обновляется 60 раз в секунду (да, fps в порядке) – thormond
Вы пробовали? Более частые обновления могут означать, что вам нужно более сильное сглаживание (т. Е. Рассмотрение большего количества значений для сглаживания). – Anko