1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using Microsoft.Xna.Framework;
5: using Microsoft.Xna.Framework.Audio;
6: using Microsoft.Xna.Framework.Content;
7: using Microsoft.Xna.Framework.GamerServices;
8: using Microsoft.Xna.Framework.Graphics;
9: using Microsoft.Xna.Framework.Input;
10: using Microsoft.Xna.Framework.Media;
11: using Microsoft.Xna.Framework.Net;
12: using Microsoft.Xna.Framework.Storage;
13:
14:
15: namespace XNACamera
16: {
17: /// <summary>
18: /// This is a game component that implements IUpdateable.
19: /// </summary>
20: public class Camera : Microsoft.Xna.Framework.GameComponent
21: {
22: public Matrix view { get; protected set; }
23: public Matrix projection { get; protected set; }
24:
25: Vector3 pos; //vektor posisi kamera
26: Vector3 target; //vektor posisi target
27: Vector3 dir; //vektor arah kamera
28: Vector3 up; //vektor yang tegak lurus terhadap bidang kamera
29:
30: MouseState prevMouseState;
31:
32: float speed = 3;
33: float rollValue = 0;
34: float currentPitch = 0;
35: float totalPitch = MathHelper.PiOver4 / 2;
36: float currentYaw = 0;
37: float totalYaw = MathHelper.PiOver4 / 2;
38:
39: public Camera(Game game, Vector3 _pos, Vector3 _target, Vector3 _up)
40: : base(game)
41: {
42: pos = _pos;
43: target = _target;
44: up = _up;
45: dir = target - pos;
46: dir.Normalize(); //membuat besar vector dir menjadi vektor normal (memiliki besar 1)
47:
48: prevMouseState = Mouse.GetState();
49: }
50:
51: /// <summary>
52: /// Allows the game component to perform any initialization it needs to before starting
53: /// to run. This is where it can query for any required services and load content.
54: /// </summary>
55: public override void Initialize()
56: {
57: base.Initialize();
58: }
59:
60: /// <summary>
61: /// Allows the game component to update itself.
62: /// </summary>
63: /// <param name="gameTime">Provides a snapshot of timing values.</param>
64: public override void Update(GameTime gameTime)
65: {
66: KeyboardState keyState = Keyboard.GetState();
67: MouseState mouseState = Mouse.GetState();
68:
69: #region reset camera
70: if (keyState.IsKeyDown(Keys.R))
71: {
72: pos = new Vector3(180, 700, 180);
73: target = new Vector3(180, 0, 180);
74: up = new Vector3(0, 0, -1);
75: dir = target - pos;
76: dir.Normalize();
77:
78: currentPitch = 0;
79: currentYaw = 0;
80: }
81: #endregion
82:
83:
84: #region scale camera
85: if (mouseState.ScrollWheelValue != rollValue)
86: {
87: pos -= dir * speed * (rollValue - mouseState.ScrollWheelValue) / 15;
88: rollValue = mouseState.ScrollWheelValue;
89: }
90:
91: if (keyState.IsKeyDown(Keys.W)) pos += up * speed;
92: if (keyState.IsKeyDown(Keys.S)) pos -= up * speed;
93: if (keyState.IsKeyDown(Keys.A)) pos += Vector3.Cross(up, dir) * speed;
94: if (keyState.IsKeyDown(Keys.D)) pos -= Vector3.Cross(up, dir) * speed;
95: #endregion
96:
97: #region yaw rotation
98: float yawAngle = (-MathHelper.PiOver4 / 150) * (mouseState.X - prevMouseState.X) / 2;
99: if ((Math.Abs(currentYaw + yawAngle) < totalYaw) && (mouseState.LeftButton == ButtonState.Pressed))
100: {
101: dir = Vector3.Transform(dir, Matrix.CreateFromAxisAngle(up, yawAngle));
102: currentYaw += yawAngle;
103: }
104: #endregion
105:
106: #region roll rotation
107: if (mouseState.RightButton == ButtonState.Pressed) up = Vector3.Transform(up, Matrix.CreateFromAxisAngle(dir, MathHelper.PiOver4 / 45));
108: #endregion
109:
110: #region pitch rotation
111: float pitchAngle = (MathHelper.PiOver4 / 150) * (mouseState.Y - prevMouseState.Y) / 4;
112: if (Math.Abs(currentPitch + pitchAngle) < totalPitch && mouseState.LeftButton == ButtonState.Pressed)
113: {
114: dir = Vector3.Transform(dir, Matrix.CreateFromAxisAngle(Vector3.Cross(up, dir), pitchAngle));
115: currentPitch += pitchAngle;
116: }
117: #endregion
118:
119: createLookAt();
120: prevMouseState = Mouse.GetState();
121: base.Update(gameTime);
122: }
123:
124: /// <summary>
125: /// Mengupdate projection matrix dan view matrix dari camera
126: /// </summary>
127: private void createLookAt()
128: {
129: view = Matrix.CreateLookAt(pos, pos + dir, up);
130: projection = Matrix.CreatePerspectiveFieldOfView(
131: MathHelper.PiOver4,
132: Game.GraphicsDevice.Viewport.AspectRatio,
133: 1, 10000
134: );
135: }
136: }
137: }