Friday, August 5, 2022

Implementation: First Person and Orbit Cameras

Overview 
An OpenGL application uses specialized cameras navigate a terrain in 3D scenes or wade thru sections of a complex structure. Some of such implementations are First Person Shooter (FPS) Camera or Orbit Camera or ARC ball Camera.

Details
System  class diagram
New Camera classes derived from DualProjectionCamera are defined. They are FPSCamera and OrbitCamera,

A new mesh class  QuadMesh is defined for loading vertexdata of 3D objects such as walls, ceilings etc in a scene. It's used by another  Quad object for loading vertex data to vertex shader and texture data to the vertex and fragment shaders. 

FPSCamera
FPSCamera class is derived from DualProjectionCamera class. This camera captures objects from the viewpoint of a viewer. Some aspects have to be considered, like the characteristics of the camera (orbiting with the mouse and translation with keyboard keys).
The camera has the following characteristics:
Orbit: The character can look left, right, up, and down; however, if we imagine the character’s head, it can’t be tilted.
Translation: The character can move in four directions: forward, backward, left, and right, up and down. 
It process mouse and keyboard inputs and calculates forward, backward, left, and right, up and down movements. They are updated into MatrixData  objects.

Constructor
Initializes hwnd with the Window handle of the hosting window. Internally calls DualProjectionCamera constructor.

Members
Name  Description
camera_frontcontains front of the camera which gets updated when the viewer moves forward or backward or sideways.
camera_poscontains current position based on the movements of the viewer.
camera_upcontains front of the camera which gets updated when the viewer moves up or down.
mouse_sensitivitySensitivity of the mouse to calculate finer movements of the viewer.
velocitySpeed to calculate finer movements of the viewer.

Methods
NameDescription
OnKeyThis method handles keyboard input events and updates camera_pos as below:
W,S : Viewer Move forward or backward
A,D:Viewer Move Left  or right
R,F:Viewer Move Up or Down
OnMouseMoveUpdates camera_pos based on the mouse movements.
setSenseivitySets mouse_sensitivity and velocity values
updateViewMatrixSets starting values of camera_pos, camera_front and camera_up values.

OrbitCamera
OrbitCamera class is derived from DualProjectionCamera class. 
An orbit camera moves in a circle around a central object. The camera always looks at the center of the object. The viewer moves around the object in a circular path while keeping the focus fixed on that center point.  To calculate polar coordinates and spherical coordinates are used.
A polar coordinate represents a point in a 2D space as radius and angle. The point lies on the circumference where the radius is computed from the center point and the angle between the point and  the polar axis.
As shown below, the blue line represents polar axis. r represents the radius.

A spherical coordinate system specifies a given point in three-dimensional space by using a distance and two angles as its three coordinates. 
These are radius r,  the polar angle, θ, and the azimuthal angle, φ, which is the angle of rotation of the radial line around the polar axis.
The three coordinates (r, θ, φ), provide a coordinate system on a sphere, typically called the spherical polar coordinates. 


Given sphere with center point c and [r, θ, φ], the corresponding [x, y, z] coordinates are:
x = c.x + r * cos(θ) * cos(φ)
y = c.y + r * sin(θ)
z = c.z + r * cos(θ) * sin(φ)
They are updated into MatrixData  objects.

Constructor
Initializes hwnd with the Window handle of the hosting window. Internally calls DualProjectionCamera constructor.

Members
Name  Description
_minRadiusThe minimum value of radius set during zoom operation.
azimuthAngle_contains the value of current azimuth angle.
center_The center defaulted to 0,0,0.
polarAngle_contains the value of current polar angle.
radiusThe current value of the radius.
upVector_The up vector defaulted to 0,1,0.
zoomfactorThe increments of the zoom both ways defaulted to 0.5
mouse_sensitivitySensitivity of the mouse to calculate finer movements of the viewer.

Methods
NameDescription
OnKeyThis method handles keyboard input events and updates radius as below:
Left Arrow : Makes radius bigger
Right Arrow : Makes radius smaller
OnMouseMoveLeft Button: Rotates all the objects
Right Button: Changes Azimuth and Polar angles resulting in circular motion of the objects
Middle Button: Changes center point resulting in panning motion of the objects horizontally and vertically.
geteyeReturns current viewer position
getNormalizedViewVectorReturns normalized value of  (center_ - getEye())
getUpVectorReturns upVector_
getViewPointReturns center_
moveHorizontalPans entire scene horizontally as a result of mouse movement
moveVerticalPans entire scene vertically as a result of mouse movement
rotateAzimuthRotates entire scene horizontally as a result of mouse movement
rotatePolarRotates entire scene vertically as a result of mouse movement
updateViewMatrixSets view matrix data based on current positions of the eye, center_ and upVector_.
zoomSets fov based on keyboard input resuting in zoom out and zoom in actions.

The Source Code can be accessed from FPSCamera, OrbitCamera

No comments:

Post a Comment