## Copyright (C) 2009 Martin Helm
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING. If not, see
## .
## -*- texinfo -*-
## @deftypefn {Function File}{[@var{cdata}] =} calc_shading (@var{amb}, @var{dif}, @var{spec}, @var{shine}, @var{colors}, @var{normals}, @var{lvec}, @var{vvec})
##
##
## If called with one output argument returns
## calculated color data for use with the patch function.
##
## @var{amb}, @var{dif}, @var{spec}, @var{shine} are the ambient, diffuse,
## specular and specular exponent properties for the lighting.
##
## @var{colors} can be a one or three column matrix with the same length
## as the @var{normals} matrix of normal vectors.
##
## A scalar or a RGB row vector can also be used for @var{colors}. The
## object has thean a single color.
##
## @var{lvec}: The light direction
##
## @var{vvec}: The view direction
##
## Type
## @example
## @group
## backend ("fltk")
## demo calc_shading
## @end group
## @end example
## to see how it works.
##
## Without 'backend ("fltk")' it will also work but is very slow.
##
## @seealso{isocolors, isonormals}
##
## @end deftypefn
## Author: Martin Helm
## Created: 2009-12-24
## Credits: Kai Habel for his diffuse, specular and surfl functions
function [ cdat ] = calc_shading (amb, dif, spec, shine, \
colors, normals, lvec, vvec)
lvec /= norm (lvec); # normalize light vector
vvec /= norm (vvec); # normalize view vector
## normalize the normal vectors
normals = normals ./ repmat (sqrt (sumsq (normals, 2)), [1, 3]);
## if we have a single color, expand it
if rows (colors) == 1
colors = repmat (colors, [rows(normals), 1]);
endif
## calculate the lighting
if columns (colors) == 1
## if we have scalar colors do it the simple way
lfactor = amb * ones (rows (normals), 1) \
+ dif * diffuse (normals(:, 1), normals(:, 2), normals(:, 3), lvec) \
+ spec * specular (normals(:, 1), normals(:, 2), normals(:, 3), \
lvec, vvec, shine);
cdat = colors .* lfactor;
else # we have rgb colors
## ambient and diffuse like in the scalar case
lfactor = amb * ones (rows (normals), 1) \
+ dif * diffuse (normals(:, 1), normals(:, 2), normals(:, 3), lvec);
lfactor = repmat (lfactor, [1, columns(colors)]);
## we use a white specular light for a better effect
lf_spec = spec * specular (normals(:, 1), normals(:, 2), normals(:, 3), \
lvec, vvec, shine);
lf_spec = repmat (lf_spec, [1, columns(colors)]);
cdat = colors .* lfactor .+ lf_spec;
endif
endfunction
%!demo
%! clf
%! fun = @(x, y, z) cos(x) .+ cos(y) .+ cos(z);
%! points = linspace (-pi, pi, 51);
%! [x, y, z] = meshgrid (points);
%! f = fun (x, y, z);
%! [F, v] = isosurface (x, y, z, f, 1.1);
%! vn = isonormals (x, y, z, f, v);
%! cdat = calc_shading (0.3, 0.4, 0.8, 15.0, [1.0 .0 .0], vn, [-1.0; -0.5; -.8], [-.5; 1.5; -.1]);
%! p = patch ("Faces", F, "Vertices", v, "FaceVertexCData", cdat, "FaceColor", "interp", "EdgeColor", "none");
%! view(30,30)
%! grid on;
%! title(['Demo shading in red, Contour Value = ',num2str(1.1)]);
%! xlabel('X');ylabel('Y');zlabel('Z');
%! axis ([-pi, pi, -pi, pi, -pi, pi]);
%!demo
%! clf
%! fun = @(x, y, z) cos(x) .+ cos(y) .+ cos(z);
%! points = linspace (-pi, pi, 51);
%! [x, y, z] = meshgrid (points);
%! f = fun (x, y, z);
%! [F, v] = isosurface (x, y, z, f, 1.1);
%! vn = isonormals (x, y, z, f, v);
%! c = isocolors (x, y, z, rand(size(x)), rand(size(x)), rand(size(x)), v);
%! cdat = calc_shading (0.5, 0.4, 0.8, 10.0, c, vn, [-1.0; -0.5; -.8], [-.5; 1.5; -.1]);
%! p = patch ("Faces", F, "Vertices", v, "FaceVertexCData", cdat, "FaceColor", "interp", "EdgeColor", "none");
%! view(45,30)
%! grid on;
%! title(['Demo shading, random colored, Contour Value = ',num2str(1.1)]);
%! xlabel('X');ylabel('Y');zlabel('Z');
%! axis ([-pi, pi, -pi, pi, -pi, pi]);