Я пытаюсь правильно нарисовать несколько 3D-моделей на экране с помощью подвижной камеры, но я сталкиваюсь с двумя проблемами.Первая проблема видна сразу: модели должны быть кубами, но рисуются в виде прямоугольных призм.Как будто их раздавливают / сжимают, но я не могу найти причину для этого.
Стороны кубов
Вторая проблема проявляется при взгляде внизна "кубах".Хотя они должны просто вращаться, при вращении они кажутся странными.
Глядя вниз
Все еще смотрю вниз, но повернул CW на 90 градусов
Вот мой код камеры:
public class Camera
{
private Driver Driver;
private int ScreenWidth { get { return Driver.GraphicsDevice.Viewport.Width; } }
private int ScreenHeight { get { return Driver.GraphicsDevice.Viewport.Height; } }
public Matrix ViewMatrix { get; private set; }
public Matrix ProjectionMatrix { get; private set; }
private const float NearClippingPlane = 0.1f;
private const float FarClippingPlane = 200.0f;
public Vector3 Position { get; private set; }
private Vector3 _direction; // Do not use _direction!
private Vector3 Direction
{
get { return _direction; }
set
{
if (value == Vector3.Zero) { }
else
{
var normalizedTemp = value;
normalizedTemp.Normalize();
if (normalizedTemp.Y > -.9999f) _direction = normalizedTemp;
}
}
}
private Vector3 Up;
private const float MovementSpeed = 10f;
private const float PanSpeed = 10f;
private MouseState previousMouseState;
private Vector3 HorizontalPlaneDirection
{
get
{
var direction = new Vector3(Direction.X, 0, Direction.Z);
if (direction != Vector3.Zero)
direction.Normalize();
return direction;
}
}
public Camera(Driver game, Vector3 position, Vector3 target, Vector3 up)
{
Driver = game;
// Build camera view matrix
Position = position;
Direction = target - position;
Up = up;
CreateLookAt();
ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(60), ScreenWidth / ScreenHeight, NearClippingPlane, FarClippingPlane);
}
public void Initialize()
{
// Set mouse position and do initial get state
Mouse.SetPosition(ScreenWidth / 2, ScreenHeight / 2);
previousMouseState = Mouse.GetState();
}
public void Update(GameTime gameTime, KeyboardState keyboard, MouseState mouse)
{
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
float moveSpeed = MovementSpeed * elapsed;
float panSpeed = PanSpeed * elapsed;
if (keyboard.IsKeyDown(Keys.W))
Position += HorizontalPlaneDirection * moveSpeed;
if (keyboard.IsKeyDown(Keys.S))
Position -= HorizontalPlaneDirection * moveSpeed;
if (keyboard.IsKeyDown(Keys.A))
Position += Vector3.Cross(Up, HorizontalPlaneDirection) * moveSpeed;
if (keyboard.IsKeyDown(Keys.D))
Position -= Vector3.Cross(Up, HorizontalPlaneDirection) * moveSpeed;
if (keyboard.IsKeyDown(Keys.Space))
Position += Up * moveSpeed;
if (keyboard.IsKeyDown(Keys.LeftShift))
Position -= Up * moveSpeed;
// Rotation in the world
Direction = Vector3.Transform(Direction, Matrix.CreateFromAxisAngle(Up, -MathHelper.ToRadians(1) * (mouse.X - previousMouseState.X) * panSpeed));
Direction = Vector3.Transform(Direction, Matrix.CreateFromAxisAngle(Vector3.Cross(Up, HorizontalPlaneDirection), MathHelper.ToRadians(1) * (mouse.Y - previousMouseState.Y) * panSpeed));
Driver.ResetMouseState();
// Reset prevMouseState
previousMouseState = Mouse.GetState();
CreateLookAt();
}
private void CreateLookAt()
{
ViewMatrix = Matrix.CreateLookAt(Position, Position + Direction, Up);
}
}
И код для рисования модели:
public void Draw(Camera Camera)
{
foreach (var mesh in Model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
//effect.EnableDefaultLighting();
//effect.PreferPerPixelLighting = true;
effect.World = GetWorldMatrix();
effect.View = Camera.ViewMatrix;
effect.Projection = Camera.ProjectionMatrix;
}
mesh.Draw();
}
}
Я знаю, что биты кода длинные и, вероятно, их трудно найти, но я очень ценю любую помощь.Спасибо!