空間に立方体があり、動き回る一人称カメラがある簡単なデモを作成しようとしています。過去にc++とopenglで似たようなものを作りました。
私の問題は次のとおりです。
- キューブをスペース内のどこにでも問題なく配置できます
- カメラを作成して移動できます
- しかし、両方を同時に作成すると、立方体はカメラに対して常に同じ位置にあります。
問題はワールドマトリックスにあると思われます。カメラはマトリックスを操作し、キューブに影響を与えています。OpenGL では、glPushMatrix と glPopMatrix を使用したため、Matrix は保存され、影響を受けませんでした。
//Draw Cube in openGL
glPushMatrix();
glTranslatef(1000,0,1000);
glRotatef(90,0,1,0);
DrawCube();
glPopMatrix();
XNA で Push/Pop Matrix と同様の機能を実現するにはどうすればよいですか?
私が見ることができる同様のデモ(最初のカメラ+オブジェクト)を知っていますか?(MSDN Microsoft チュートリアルを使用していますが、ほとんどのリンクが壊れています :-( )
私がこれまでに試したことを見ることができます。関連するメソッドを貼り付けました。
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
float timeDifference = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;
ProcessInput(timeDifference);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
//Text
DrawText();
//CUBE
// Set the World matrix which defines the position of the cube
cubeEffect.World = Matrix.CreateTranslation(modelPosition);
// Set the View matrix which defines the camera and what it's looking at
cubeEffect.View = Matrix.CreateLookAt(cameraPositionCube, modelPosition, Vector3.Up);
// Set the Projection matrix which defines how we see the scene (Field of view)
cubeEffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 1.0f, 1000.0f);
// Enable textures on the Cube Effect. this is necessary to texture the model
cubeEffect.TextureEnabled = true;
cubeEffect.Texture = cubeTexture;
// Enable some pretty lights
cubeEffect.EnableDefaultLighting();
// apply the effect and render the cube
foreach (EffectPass pass in cubeEffect.CurrentTechnique.Passes)
{
pass.Apply();
cubeToDraw.RenderToDevice(GraphicsDevice);
}
base.Draw(gameTime);
}
private void UpdateViewMatrix()
{
Matrix cameraRotation = Matrix.CreateRotationX(updownRot) * Matrix.CreateRotationY(leftrightRot);
Vector3 cameraOriginalTarget = new Vector3(0, 0, -1);
Vector3 cameraRotatedTarget = Vector3.Transform(cameraOriginalTarget, cameraRotation);
Vector3 cameraFinalTarget = cameraPosition + cameraRotatedTarget;
Vector3 cameraOriginalUpVector = new Vector3(0, 1, 0);
Vector3 cameraRotatedUpVector = Vector3.Transform(cameraOriginalUpVector, cameraRotation);
viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraFinalTarget, cameraRotatedUpVector);
}
private void ProcessInput(float amount)
{
MouseState currentMouseState = Mouse.GetState();
if (currentMouseState != originalMouseState)
{
float xDifference = currentMouseState.X - originalMouseState.X;
float yDifference = currentMouseState.Y - originalMouseState.Y;
leftrightRot -= rotationSpeed * xDifference * amount;
updownRot -= rotationSpeed * yDifference * amount;
Mouse.SetPosition(device.Viewport.Width / 2, device.Viewport.Height / 2);
UpdateViewMatrix();
}
Vector3 moveVector = new Vector3(0, 0, 0);
KeyboardState keyState = Keyboard.GetState();
if (keyState.IsKeyDown(Keys.Up) || keyState.IsKeyDown(Keys.W))
moveVector += new Vector3(0, 0, -1);
if (keyState.IsKeyDown(Keys.Down) || keyState.IsKeyDown(Keys.S))
moveVector += new Vector3(0, 0, 1);
if (keyState.IsKeyDown(Keys.Right) || keyState.IsKeyDown(Keys.D))
moveVector += new Vector3(1, 0, 0);
if (keyState.IsKeyDown(Keys.Left) || keyState.IsKeyDown(Keys.A))
moveVector += new Vector3(-1, 0, 0);
if (keyState.IsKeyDown(Keys.Q))
moveVector += new Vector3(0, 1, 0);
if (keyState.IsKeyDown(Keys.Z))
moveVector += new Vector3(0, -1, 0);
AddToCameraPosition(moveVector * amount);
}
private void AddToCameraPosition(Vector3 vectorToAdd)
{
Matrix cameraRotation = Matrix.CreateRotationX(updownRot) * Matrix.CreateRotationY(leftrightRot);
Vector3 rotatedVector = Vector3.Transform(vectorToAdd, cameraRotation);
cameraPosition += moveSpeed * rotatedVector;
UpdateViewMatrix();
}