%% Volume Visualization
%
% This example shows volume visualization in the virtual reality environment.
%
% Volume visualization is the creation of graphical representations of data
% sets that are defined on three-dimensional grids. In addition to standard
% volumetric plots, virtual reality visualization can add interactivity and
% immersion to the phenomenon under study. Observer can navigate through
% the 3D volume, invoke callbacks by double clicking on certain objects in
% the scene, display the volumetric data in relation to some other real-life
% objects or environment.
%
% In the example, we first construct the volumetric data defined on the 3D
% grid. The data corresponding to voxels outside a sphere and in one of its
% octants are set to NaN, so that it is possible to see inside the sphere.
% The data is then visualized using three different types of volumetric
% objects, each created with different transparency, voxel size and color
% map.
%
% For all objects in the scene (floor grid and three volumetric plots) we
% then define an OnActivate callback that causes the object to spin -
% interpolate its Rotation property. We use the virtual world 'propagate'
% method to define this callback for all objects in the scene in one go,
% with single MATLAB command.

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

%% Initialize the 3D Foundation object
FW = F3D.World(mfilename);
initialize(FW, [0 6 3]);

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

% Create floor grid
F3D.Geometry.templateGrid(FW.Root, [10 10 10]);

% Sample data
n = 16;
c = (1 + n)/2;
Data = zeros(n, n, n);
for k = 1:n
    for j = 1:n
        for i = 1:n
            Data(i, j, k) = sqrt((i - c)^2 + (j - c)^2 + (k - c)^2);
        end
    end
end
h = max(Data(:))/1.6;
Data(Data > h) = NaN;
n2 = round(n/2);
Data(n2:end, n2:end, n2:end) = NaN;
Scales = 1 - Data/h;

% Convert data to uint8 for more efficient processing
Data = uint8(Data*30);

% Create 3 different volumetric visualizations of the same data
Sun1 = addChild(FW.Root);
createShape(Sun1, 'voxel', [2 2 2], 1/1, Data, jet(16));
Sun1.Location = [-3 0 1];
Sun1.VertexBlend = 1;
Sun1.Shininess = 0;

Sun2 = addChild(FW.Root);
createShape(Sun2, 'voxel', [2 2 2], [0.5 0.5 1], Data, gray(16));
Sun2.Location = [0 0 1];
Sun2.VertexBlend = 1;
Sun2.Transparency = 0.6;
Sun2.Shininess = 0;

Sun3 = addChild(FW.Root);
createShape(Sun3, 'voxel', [2 2 2], Scales, Data);
Sun3.Location = [3 0 1];
Sun3.VertexBlend = 1;
Sun3.Transparency = 0;
Sun3.Shininess = 0;

propagate(FW.Root, 'OnActivate', @(this, ~) interpolate(this, 'Rotation', [0 0 pi*2], 'hill', 3));