1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
| // Default constructor, do nothing
Camera::Camera ()
: cameraPosition (), cameraOrientation (), viewMatrix (),
mouseSensibility (10.0), movementsSpeed (1.0)
{
// Initialisation of the key configuration with default data
keyConfig.insert (std::make_pair ("Left", sf::Key::Left));
keyConfig.insert (std::make_pair ("Right", sf::Key::Right));
keyConfig.insert (std::make_pair ("Forward", sf::Key::Up));
keyConfig.insert (std::make_pair ("Backward", sf::Key::Down));
// Initialisation of the state of each keys
keyStates.insert (std::make_pair (keyConfig["Left"], false));
keyStates.insert (std::make_pair (keyConfig["Right"], false));
keyStates.insert (std::make_pair (keyConfig["Forward"], false));
keyStates.insert (std::make_pair (keyConfig["Backward"], false));
}
// Another constructor that initializes the frustum associated to the camera
Camera::Camera (const double fovY_, const double viewAspect_, const double zNear_,
const double zFar_)
: cameraPosition (), cameraOrientation ()
{
}
// Set the position of the camera
void Camera::SetPosition (const Vector3d & position_)
{
cameraPosition = position_;
// Reconstruct the view matrix
ConstructViewMatrix ();
}
// This function gets input from mouse and keyboard
void Camera::UpdateFromInput (sf::RenderWindow & app_)
{
// Get a reference to the input manager associated to our window, and store it for later use
const sf::Input & Input = app_.GetInput();
// ----------------------------------- ROTATION -----------------------------------
// This function gets the position of the mouse
int mouseX = Input.GetMouseX();
int mouseY = Input.GetMouseY();
int halfWidth = app_.GetWidth() / 2;
int halfHeight = app_.GetHeight() / 2;
// Call the function that updates the orientation
UpdateOrientation (mouseX, mouseY, halfWidth, halfHeight);
// Set the mouse position to the center of the screen, so that the mouse cursor will
// never be outside the screen
app_.SetCursorPosition (halfWidth, halfHeight);
// ------------------------------------- MOVE -------------------------------------
// Update the state of each keys
KeyStates::iterator itEnd = keyStates.end();
for (KeyStates::iterator it = keyStates.begin() ; it != itEnd ; ++it)
it->second = Input.IsKeyDown (it->first);
// Call the function that updates the position of the camera
UpdatePosition ();
// Construct the view matrix, according to the new orientation and position
ConstructViewMatrix ();
}
// This function must be called by UpdateFromInput. It updates the camera
// orientation given the positions of the mouse
void Camera::UpdateOrientation (const int mouseX_, const int mouseY_,
const int halfWidth_, const int halfHeight_)
{
// And those the angles around each axis
static double angleX = 0.0, angleY = 0.0;
// The two rotation quaternions
Quaterniond rotationX, rotationY;
// If the mouse has moved on the x-axis
if ((mouseX_ - halfWidth_) != 0)
{
// Compute the angle by which the camera has to be rotated
// (a movement on the x-axis means a rotation about the Y camera
// axis)
angleY += (mouseX_ - halfWidth_) / mouseSensibility;
}
// Build a rotation quaternion
rotationY.SetRotationAboutYAxis (angleY);
// If the mouse has moved on the y-axis
if ((mouseY_ - halfHeight_) != 0)
{
// Compute the angle by which the camera has to be rotated
// (a movement on the y-axis means a rotation about the X camera
// axis)
angleX += (mouseY_ - halfHeight_) / mouseSensibility;
}
// Build a rotation quaternion
rotationX.SetRotationAboutXAxis (angleX);
// Concatenate the two quaternions (the order IS IMPORTANT)
cameraOrientation = rotationX * rotationY;
}
// This function must be called by UpdateFromInput. It updates the position of
// the camera
void Camera::UpdatePosition ()
{
// Get the conjugate quaternion of the camera orientation since cameraOrientation
// is a normalized quaternion, and get the new axis given to the new orientation
Quaterniond orientationConjugate = Conjugate (cameraOrientation);
Vector3d xAxis (1.0, 0.0, 0.0), zAxis (0.0, 0.0, 1.0);
xAxis = xAxis * orientationConjugate;
zAxis = zAxis * orientationConjugate;
// Since this is a FPS camera, I have to "block" the position camera on the y-axis
zAxis.y = 0.0;
if (keyStates[keyConfig["Left"]])
cameraPosition -= xAxis * movementsSpeed;
if (keyStates[keyConfig["Right"]])
cameraPosition += xAxis * movementsSpeed;
if (keyStates[keyConfig["Forward"]])
cameraPosition -= zAxis * movementsSpeed;
if (keyStates[keyConfig["Backward"]])
cameraPosition += zAxis * movementsSpeed;
}
// Construct the view matrix with the orientation and the position
void Camera::ConstructViewMatrix ()
{
// First set the orientation given the quaternion
viewMatrix.Set (cameraOrientation);
// Now, we're gonna get the first three rows
Vector3d xAxis (viewMatrix (0, 0), viewMatrix (1, 0), viewMatrix (2, 0));
Vector3d yAxis (viewMatrix (0, 1), viewMatrix (1, 1), viewMatrix (2, 1));
Vector3d zAxis (viewMatrix (0, 2), viewMatrix (1, 2), viewMatrix (2, 2));
// Finally, set the position part of the matrix
viewMatrix.SetTranslation (-Dot (xAxis, cameraPosition),
-Dot (yAxis, cameraPosition),
-Dot (zAxis, cameraPosition));
} |
Partager