I'm sure there is a simple explanation for this behavior that makes mathematical good sense, but I need a way to look at my model along the up vector. I have tested it with the three unit vectors to confirm it is viewing along the up vector that causes my model to disappear, at least in the current configuration.
tldr; Model disappears when camera is along up vector, how do I fix it?
Edit: Also forgot to mention besides changing the up vector to confirm, I also confirmed this was the problem by looking off the up factor by a small amount like so, which works fine I could potentially use this fact, but on principle I would like to know why I can't view along the up vector and possibly correct it in a way that makes mathematical sense:
if (Keyboard.GetState().IsKeyDown(Keys.D3))
_cameraPosition = new Vector3(0f, 1f, 0.000001f);
One Solution, as suggested by DMGregory. You can change the up vector when switching to the top view like so and that works, better than using float epsilon I suppose. Code below, but I am still not sure that this is the best way to accomplish this effect:
if (Keyboard.GetState().IsKeyDown(Keys.D1))
{
_cameraUp = Vector3.UnitY;
_cameraPosition = Vector3.UnitX;
}
if (Keyboard.GetState().IsKeyDown(Keys.D2))
{
_cameraUp = Vector3.UnitY;
_cameraPosition = Vector3.UnitZ;
}
if (Keyboard.GetState().IsKeyDown(Keys.D3))
{
_cameraUp = -Vector3.UnitZ;
_cameraPosition = Vector3.UnitY;
}
Code to follow, monkey from blender is the idol:
public class MyGame : Game
{
private GraphicsDeviceManager _graphics;
private Model _idol;
private Matrix _idolWorld;
private Vector3 _idolPosition;
private Vector3 _cameraPosition;
private Vector3 _cameraUp;
private float _width;
private float _height;
private float _near;
private float _far;
private Matrix _view;
private Matrix _projection;
public MyGame()
{
_graphics = new GraphicsDeviceManager(this);
_graphics.PreferredBackBufferWidth = 1920;
_graphics.PreferredBackBufferHeight = 1080;
_graphics.ApplyChanges();
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
_width = (float)(_graphics.PreferredBackBufferWidth >> 1);
_height = (float)(_graphics.PreferredBackBufferHeight >> 1);
_near = -MathHelper.Max(_width, _height) - 1f;
_far = -_near;
_idolPosition = Vector3.Zero;
_idolWorld = Matrix.Identity;
_cameraPosition = new Vector3(0f, 0f, 1f);
_cameraUp = Vector3.UnitY;
_view = Matrix.CreateLookAt(_idolPosition + _cameraPosition, _idolPosition, _cameraUp);
_projection = Matrix.CreateOrthographicOffCenter(-_width, _width, -_height, _height, _near, _far);
base.Initialize();
}
protected override void LoadContent()
{
// TODO: use this.Content to load your game content here
_idol = Content.Load<Model>("Idol");
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
// TODO: Add your update logic here
if (Keyboard.GetState().IsKeyDown(Keys.D1))
_cameraPosition = new Vector3(1f, 0f, 0f);
if (Keyboard.GetState().IsKeyDown(Keys.D2))
_cameraPosition = new Vector3(0f, 0f, 1f);
if (Keyboard.GetState().IsKeyDown(Keys.D3))
_cameraPosition = new Vector3(0f, 1f, 0f);
_view = Matrix.CreateLookAt(_idolPosition + _cameraPosition, _idolPosition, _cameraUp);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
foreach (ModelMesh mesh in _idol.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = _idolWorld;
effect.View = _view;
effect.Projection = _projection;
}
mesh.Draw();
}
base.Draw(gameTime);
}
}
mesh
? \$\endgroup\$_near
, and you might find it's too close to the camera to see. \$\endgroup\$_cameraUp
toVector3.UnitY
. So when you look straight up, you might be giving the camera a contradictory instruction like "point your nose this way AND point the top of your head in that same direction" — depending on how your system deals with these contradictions, you could get either an invalid view matrix or one oriented a different way than you'd intended. \$\endgroup\$