%% Color Grading
%
% This example demonstrates image color grading capabilities of 3D
% Foundation Viewer.
%
% In order to model real-life situations or real camera properties, or to
% modify virtual world appearance for further processing of captured 2D
% images or video streams from virtual cameras, it is often desirable
% to modify contrast, saturation, gain, resolution and other visual
% properties of image displayed in the F3D Viewer window.
%
% The example loads the ARIAC work cell model. By clicking on the
% buttons along the left edge of the Viewer you can observe the effect of
% gradual changes in resolution, gain, contrast and saturation on the scene
% appearance. You can also set the random values for these parameters, as
% well as return to their default values.
%
% 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);

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

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

VP.Button1 = F3D.Type.Button([0 0 0], 'D', 'Default values', @demoDefault);
VP.Button2 = F3D.Type.Button([0 0 0], '?', 'Random values', @demoRand);
VP.Button4 = F3D.Type.Button([0 0 0], 'S', 'Animate saturation', @demoSaturation);
VP.Button5 = F3D.Type.Button([0 0 0], 'C', 'Animate contrast', @demoContrast);
VP.Button6 = F3D.Type.Button([0 0 0], 'G', 'Animate gain', @demoGain);
VP.Button8 = F3D.Type.Button([0 0 0], 'R', 'Animate resolution', @demoResolution);

function demoDefault(World, ~)
    World.Viewports.Main.Rendering.Saturation = 1;
    World.Viewports.Main.Rendering.Contrast = 1;
    World.Viewports.Main.Rendering.Gain = 1;
end

function demoRand(World, ~)
    World.Viewports.Main.Rendering.Saturation = rand*3 - 1;
    World.Viewports.Main.Rendering.Contrast = rand*3 - 1;
    World.Viewports.Main.Rendering.Gain = rand*2;
    World.Viewports.Main.Rendering
end

function demoSaturation(World, ~)
    for i = [linspace(1, 4, 60) linspace(4, -2, 60) linspace(-2, 1, 60)]
        World.Viewports.Main.Rendering.Saturation = i;
        keepRate(World, 30);
    end
end

function demoContrast(World, ~)
    for i = [linspace(1, 4, 60) linspace(4, -2, 60) linspace(-2, 1, 60)]
        World.Viewports.Main.Rendering.Contrast = i;
        keepRate(World, 30);
    end
end

function demoGain(World, ~)
    for i = [linspace(1, 4, 60) linspace(4, 0, 60) linspace(0, 1, 60)]
        World.Viewports.Main.Rendering.Gain = i;
        keepRate(World, 30);
    end
end

function demoResolution(World, ~)
    for i = [linspace(1, 0.32, 90) linspace(.32, 1, 90)].^4
        World.Viewports.Main.Rendering.ResolutionScale = i;
        keepRate(World, 30);
    end
end