Browse Source

Added example camera type.

Brucey 5 years ago
parent
commit
9a77e39a2f
1 changed files with 137 additions and 0 deletions
  1. 137 0
      examples/learnopengl/camera.bmx

+ 137 - 0
examples/learnopengl/camera.bmx

@@ -0,0 +1,137 @@
+SuperStrict
+
+Import BRL.Matrix
+
+' Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods
+Enum ECameraMovement
+	Forward
+	Backward
+	Left
+	Right
+End Enum
+
+' Default camera values
+Const DEFAULT_YAW:Float = -90.0
+Const DEFAULT_PITCH:Float = 0.0
+Const DEFAULT_SPEED:Float = 2.5
+Const DEFAULT_SENSITIVITY:Float =  0.1
+Const DEFAULT_ZOOM:Float = 45.0
+
+
+' An abstract camera class that processes input and calculates the corresponding Euler Angles, Vectors and Matrices for use in OpenGL
+Type TCamera
+	' Camera Attributes
+	Field position:SVec3F
+	Field front:SVec3F
+	Field up:SVec3F
+	Field Right:SVec3F
+	Field worldUp:SVec3F
+	' Euler Angles
+	Field yaw:Float
+	Field pitch:Float
+	' Camera options
+	Field movementSpeed:Float
+	Field mouseSensitivity:Float
+	Field zoom:Float
+
+	' Constructor with vectors
+	Method New(position:SVec3F = Null, upX:Float = 0, upY:Float = 1, upZ:Float = 0, yaw:Float = DEFAULT_YAW, pitch:Float = DEFAULT_PITCH)
+		front = New SVec3F(0.0, 0.0, -1.0)
+		movementSpeed = DEFAULT_SPEED
+		mouseSensitivity = DEFAULT_SENSITIVITY
+		zoom = DEFAULT_ZOOM
+		
+		Self.position = position
+		worldUp = New SVec3F(upX, upY, upZ)
+		Self.yaw = yaw
+		Self.pitch = pitch
+
+		updateCameraVectors()
+	End Method
+	
+	' Constructor with scalar values
+	Method New(posX:Float, posY:Float, posZ:Float, upX:Float, upY:Float, upZ:Float, yaw:Float, pitch:Float)
+		front = New SVec3F(0.0, 0.0, -1.0)
+		movementSpeed = DEFAULT_SPEED
+		mouseSensitivity = DEFAULT_SENSITIVITY
+		zoom = DEFAULT_ZOOM
+
+		position = New SVec3F(posX, posY, posZ)
+		worldUp = New SVec3F(upX, upY, upZ)
+		Self.yaw = yaw
+		Self.pitch = pitch
+
+		updateCameraVectors()
+	End Method
+
+	' Returns the view matrix calculated using Euler Angles and the LookAt Matrix
+	Method GetViewMatrix:SMat4F()
+		Return SMat4F.LookAt(position, position + front, up)
+	End Method
+
+	' Processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems)
+	Method ProcessKeyboard(direction:ECameraMovement, deltaTime:Float)
+		Local velocity:Float = movementSpeed * deltaTime
+		If direction = ECameraMovement.Forward Then
+			position = position + (front * velocity)
+		End If
+		If direction = ECameraMovement.Backward Then
+			position = position - (front * velocity)
+		End If
+		If direction = ECameraMovement.Left Then
+			position = position - (Right * velocity)
+		End If
+		If direction = ECameraMovement.Right Then
+			position = position + (Right * velocity)
+		End If
+	End Method
+
+	Method ProcessMouseMovement(xoffset:Float, yoffset:Float, constrainPitch:Int = True)
+		xoffset :* mouseSensitivity
+		yoffset :* mouseSensitivity
+		
+		yaw :+ xoffset
+		pitch :+ yoffset
+		
+		' Make sure that when pitch is out of bounds, screen doesn't get flipped
+		If constrainPitch Then
+			If pitch > 89.0 Then
+				pitch = 89.0
+			End If
+			
+			If pitch < -89.0 Then
+				pitch = -89.0
+			End If
+		End If
+		
+		' Update Front, Right and Up Vectors using the updated Euler angles
+		updateCameraVectors()
+	End Method
+	
+	' Processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis
+	Method ProcessMouseScroll(yoffset:Float)
+		If zoom >= 1.0 And zoom <= 45.0 Then
+			zoom :- yoffset
+		End If
+		
+		If zoom <= 1.0 Then
+			zoom = 1.0
+		End If
+		
+		If zoom >= 45.0 Then
+			zoom = 45.0
+		End If
+	End Method
+	
+Private
+	' Calculates the front vector from the Camera's (updated) Euler Angles
+	Method updateCameraVectors()
+		' Calculate the new Front vector
+		Local newFront:SVec3F = New SVec3F(Float(Cos(yaw) * Cos(pitch)), Float(Sin(pitch)), Float(Sin(yaw) * Cos(pitch)))
+		front = newFront.Normal()
+		' Also re-calculate the Right and Up vector
+		Right = front.Cross(worldUp).Normal() ' Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
+		up = Right.Cross(front).Normal()
+	End Method
+	
+End Type