%% Underwater Environment
%
% This example shows the use of color grading and color fog to simulate
% underwater environment. It also shows how to apply a 2D overlay to the
% Viewer window.
%
% At first we load the work cell model and attach a spotlight to the
% robot camera module. Then, F3D Viewer image temperature, tint and
% saturation are modified. A color uniform fog helps the impression of
% underwater conditions.
%
% The user-defined button can be used to switch ambient light on and off,
% allowing to model both shallow and deep water environment.
%
% The work cell model is based on the 2017 ARIAC competition organized by
% the NIST Institute:
% https://www.nist.gov/el/intelligent-systems-division-73500/agile-robotics-industrial-automation-competition

%   Copyright 1998-2021 HUMUSOFT s.r.o.

%% Initialize the 3D Foundation object
FW = F3D.World(mfilename);
initialize(FW, [5.5 4.3 -10]);

% Set the viewport properties
VP = FW.Viewports.Main;
VP.Title = mfilename;
Path = fileparts(which(mfilename));
setLogo(VP, fullfile(Path, 'data', 'MatlabLogo.png'));
setOverlay(VP, fullfile(Path, 'data', 'HUD.png'));

% Import X3D model
load(FW.Root, fullfile(Path, 'f3dex_workcell.f3d'));
propagate(FW.Root, 'Shininess', 0.6);

% Add a rotating spotlight
FW.CoordinateSystem = 'vrml';
Searchlight = findBy(FW.Root, 'Name', 'Actor124', 'first');
Searchlight.SpotLight = F3D.Type.SpotLight('Color', [1 1 1], 'Radius', 20, 'Angle', pi/6);
Searchlight.Collisions = false;
Searchlight.Gravity = false;
Searchlight.Physics = true;
Searchlight.AngularVelocity = [0 0 10];

% Color grading
VP.Rendering = F3D.Type.Rendering('Temperature', 3000, 'Tint', -0.5, 'Saturation', 0.5, 'LensDistortion', 0.4);

% Colored fog
FW.Environment = F3D.Type.Environment('FogDensity', 3, 'FogColor', [0 0.1 0.25], 'AmbientIntensity', 0.5, 'VolumetricFog', true);

% User button
VP.Button5 = F3D.Type.Button([0 0 0], 'A', 'Switch ambient light', @switchAmbient);

%% Callback functions
function switchAmbient(World, ~)
    if World.Environment.AmbientIntensity < 1
        World.Environment.AmbientIntensity = 10;
    else
        World.Environment.AmbientIntensity = 0.5;
    end
end