Property definitions

gamnit $ UICamera :: defaultinit
# Orthogonal camera to draw UI objects with services to work with screens of different sizes
#
# X axis: left to right of the screen, from `position.x` to `position.x + width`
# Y axis: top to bottom of the screen, from `position.y` to `position.y + height`
# Z axis: far to near the camera (usually when values are higher), from `far` to `near`
class UICamera
	super Camera

	# Clipping wall near the camera, defaults to 100.0
	var near = 100.0 is writable

	# Clipping wall the farthest of the camera, defaults to -100.0
	var far: Float = -100.0 is writable

	# Width in world units, calculated from `height` and the screen aspect ratio
	fun width: Float do return height * display.aspect_ratio

	# Height in world units, defaults to 1080.0
	#
	# Set this value using `reset_height`.
	var height = 1080.0

	# Reset the camera position so that `height` world units are visible on the Y axis
	#
	# This can be used to set standardized UI units independently from the screen resolution.
	fun reset_height(height: nullable Float)
	do
		if height == null then height = display.height.to_f
		self.height = height
	end

	# Convert the position `x, y` on screen, to UI coordinates
	fun camera_to_ui(x, y: Numeric): Point3d[Float]
	do
		# FIXME this kind of method should use something like a canvas
		# instead of being hard coded on the display.

		var wx = x.to_f * width / display.width.to_f - position.x
		var wy = y.to_f * height / display.height.to_f - position.y
		return new Point3d[Float](wx, -wy, 0.0)
	end

	# Center of the screen, from the point of view of the camera, at z = 0
	var center: IPoint3d[Float] = new CameraAnchor(self, 0.5, -0.5)

	# Center of the top of the screen, at z = 0
	var top: IPoint3d[Float] = new CameraAnchor(self, 0.5, 0.0)

	# Center of the bottom of the screen, at z = 0
	var bottom: IPoint3d[Float] = new CameraAnchor(self, 0.5, -1.0)

	# Center of the left border of the screen, at z = 0
	var left: IPoint3d[Float] = new CameraAnchor(self, 0.0, -0.5)

	# Center of the right border of the screen, at z = 0
	var right: IPoint3d[Float] = new CameraAnchor(self, 1.0, -0.5)

	# Top left corner of the screen, at z = 0
	var top_left: IPoint3d[Float] = new CameraAnchor(self, 0.0, 0.0)

	# Top right corner of the screen, at z = 0
	var top_right: IPoint3d[Float] = new CameraAnchor(self, 1.0, 0.0)

	# Bottom left corner of the screen, at z = 0
	var bottom_left: IPoint3d[Float] = new CameraAnchor(self, 0.0, -1.0)

	# Bottom right corner of the screen, at z = 0
	var bottom_right: IPoint3d[Float] = new CameraAnchor(self, 1.0, -1.0)

	redef fun mvp_matrix
	do
		var view = new Matrix.identity(4)

		# Translate the world away from the camera
		view.translate(-position.x, -position.y, -position.z)

		# Use a projection matrix with a depth
		var projection = new Matrix.orthogonal(0.0, width, -height, 0.0, near, far)

		return view * projection
	end
end
lib/gamnit/cameras.nit:196,1--277,3