extends Spatial # Controls a camera rig # # This class adds some features to cameras that are missing in Godot as of 3.0: # # - Fading in and out. Optimally, this would be done via a fullscreen effect, # but there is not built-in method for this. # # In order to work in both normal rendering and virtual reality, the fading # effect is achieved by surrounding the camera with an alpha-blended black box :-) # # - Carrying multiple cameras. The ArVrCamera will fill the console with countless # error messages if it is used outside of VR (and object picking doesn't work). # # This is "solved" by using a camera rig with two cameras and disabling the one # that currently isn't used. # # ------------------------------------------------------------------------------------------------- # How far the camera is faded out. 0.0 is fully faded out, 1.0 is fully visible. export(float, 1.0) onready var FadeLevel = 1.0 setget setFadeLevel # Culling mask applied to the cameras export(int, FLAGS) onready var CullMask = -1 setget setCullMask # Fade level override (currently only used for VR calibration) onready var OverrideFadeLevel = 1.0 setget setOverrideFadeLevel # ------------------------------------------------------------------------------------------------- # Whether the frustum mask meshes are visible # @remarks # For improved performance, the frustum masks are hidden when they're fully faded out. # This avoid having a full-screen alpha-blended quad visible the entire time. var frustumMaskVisible # All cameras attached to the camera controller var cameras # World environment node that is used within the scene var worldEnvironment # ------------------------------------------------------------------------------------------------- # Initializes the script component when the node is added to the scene func _ready(): InitializeIfNotYetDone() # ------------------------------------------------------------------------------------------------- # Performs the initialization if it hasn't happened yet func InitializeIfNotYetDone(): if OverrideFadeLevel == null: OverrideFadeLevel = 1.0 if self.worldEnvironment == null: self.worldEnvironment = get_node("../WorldEnvironment") if self.worldEnvironment == null: self.worldEnvironment = get_node("../Environment/WorldEnvironment") assert(self.worldEnvironment != null) self.worldEnvironment = self.worldEnvironment.environment updateWorldBrightness() if self.cameras == null: self.cameras = findCameras() setCullMask(self.CullMask) # ------------------------------------------------------------------------------------------------- # Changes the fade level on all frustum masks # @param fadeLevel Fade level that will be applied to the frustum masks func setFadeLevel(var fadeLevel): FadeLevel = fadeLevel updateWorldBrightness() # ------------------------------------------------------------------------------------------------- # Changes the override fade level on all frustum masks # @param fadeLevel Fade level override that will be applied to the frustum masks func setOverrideFadeLevel(var overrideFadeLevel): OverrideFadeLevel = overrideFadeLevel updateWorldBrightness() # ------------------------------------------------------------------------------------------------- # Changes the culling mask of all cameras # @param cullMask Culling mask that will be applied to all cameras func setCullMask(var cullMask): CullMask = cullMask # If the property is assigned before onReady, don't do anything until onReady is called if self.cameras == null: return var cameraCount = self.cameras.size() while cameraCount > 0: cameraCount -= 1 self.cameras[cameraCount].set_cull_mask(cullMask) # ------------------------------------------------------------------------------------------------- # Updates the brightness of the world environment # @param brightness Brightness factor that will be applied to the world environment func updateWorldBrightness(): # If an update is attempted before onReady, don't do anything until onReady is called if self.worldEnvironment == null: return # Use the lower of the two fade levels in case both apply var combinedFadeLevel = min(FadeLevel, OverrideFadeLevel) # Calculate the opacity that should be applied to the frustum mask var opacity if combinedFadeLevel < 1.0: opacity = min(sqrt(1.0 - combinedFadeLevel), 1.0) else: opacity = 0.0 self.worldEnvironment.adjustment_enabled = true self.worldEnvironment.adjustment_brightness = 1.0 - opacity # ------------------------------------------------------------------------------------------------- # Finds all cameras that the camera controller node is carrying # @returns A list of all cameras carried by the camera controller func findCameras(): var cameras = [] recursivelyCollectCameras(self, cameras) return cameras # ------------------------------------------------------------------------------------------------- # Recursively searches a node for cameras and appends them to a list # @param node Node that will be searched for cameras # @param cameraList List to which all found cameras will be appended func recursivelyCollectCameras(var node, var cameraList): for childNode in node.get_children(): if childNode is Camera: cameraList.append(childNode) else: recursivelyCollectCameras(childNode, cameraList)