📄 cameratoolbar2.m
字号:
function ret = cameratoolbar2(varargin)
%cameratoolbar2 Interactively manipulate camera.
% cameratoolbar2 creates a new toolbar that enables interactive
% manipulation of a scene's camera and light by dragging the
% mouse on the figure window; the camera properties of the
% current axes (gca) are affected. Several camera properties
% are set when the toolbar is initialized.
%
% cameratoolbar2('NoReset') creates the toolbar without setting
% any camera properties.
%
% cameratoolbar2('SetMode' mode) sets the mode of the
% toolbar. Mode can be: 'orbit', 'orbitscenelight', 'pan',
% 'dollyhv', 'dollyfb', 'zoom', 'roll', 'walk', 'nomode'.
%
% cameratoolbar2('SetCoordSys' coordsys) sets the principal axis
% of the camera motion. coordsys can be: 'x', 'y', 'z', 'none'.
%
% cameratoolbar2('Show') shows the toolbar.
% cameratoolbar2('Hide') hides the toolbar.
% cameratoolbar2('Toggle') toggles the visibility of the toolbar.
%
% cameratoolbar2('ResetCameraAndSceneLight') resets the current
% camera and scenelight.
% cameratoolbar2('ResetCamera') resets the current camera.
% cameratoolbar2('ResetSceneLight') resets the current scenelight.
% cameratoolbar2('ResetTarget') resets the current camera target.
%
% ret = cameratoolbar2('GetMode') returns the current mode.
% ret = cameratoolbar2('GetCoordSys') returns the current
% principal axis.
% ret = cameratoolbar2('GetVisible') returns the visibility.
% ret = cameratoolbar2 returns the handle to the toolbar.
%
% cameratoolbar2('Close') removes the toolbar.
%
% Note: Rendering performance is affected by presence of OpenGL
% hardware.
%
% See also ROTATE3D, ZOOM.
% Copyright 1984-2002 The MathWorks, Inc.
% $Revision: 1.26.4.5 $ $Date: 2004/04/10 23:26:44 $
persistent walk_flag
[hfig,haxes] = currenthandles;
Udata = getUdata;
r = [];
if nargin==0
if iscameraobj(haxes)
axis(haxes,'vis3d')
end
r = cameratoolbar2('show');
cameratoolbar2('setmode', 'orbit')
arg = '';
else
arg = lower(varargin{1});
if ~strcmp(arg, 'init') & ~strcmp(arg, 'motion') & ...
(length(arg)<3 | any(arg(1:3)~='get')) & ...
isempty(Udata)
r = cameratoolbar2('init');
Udata = getUdata;
%if ~strcmp(arg, 'nomode')
% scribeclearmode(hfig,'cameratoolbar', 'nomode');
%end
end
end
switch arg
case 'down'
if(isempty(haxes)) return; end
%can call with cameratoolbar('down',0/1) to prohibit setting of windowbuttonfcn's
switch get(hfig,'SelectionType')
% case 'open'
% if strcmp(get(haxes,'warptofill'),'on')
% axis('vis3d');
% else
% axis('normal');
% end
case 'alt'
postContextMenu(hfig,haxes);
otherwise
if strcmp(get(haxes,'warptofill'),'on') %& ...
%~(isappdata(haxes,'cameratoolbarAxesOptimized') & ...
% isequal(getappdata(haxes,'CameratoolbarAxesOptimized'),1))
if iscameraobj(haxes)
axis(haxes,'vis3d');
else
return
end
%setappdata(haxes,'CameratoolbarAxesOptimized',1);
%bashMsg='Axes camera settings optimized for 3-D camera movement. Type ''axis normal'' to restore';
%disp(bashMsg);
end
Udata = getUdata;
pt = hgconvertunits(hfig,[0 0 get(hfig,'CurrentPoint')],...
get(hfig,'Units'),'pixels',0);
pt = pt(3:4);
Udata.figStartPoint = pt;
Udata.figLastPoint = pt;
Udata.figLastLastPoint = pt;
Udata.buttondown = 1;
Udata.moving = 0;
setUdata(Udata)
validateScenelights(haxes)
%updateScenelightOnOff(haxes,Udata.scenelightOn);
if length(varargin)==1 | varargin{2}
set(hfig, 'windowbuttonmotionfcn', 'cameratoolbar(''motion'')')
set(hfig, 'windowbuttonupfcn', 'cameratoolbar(''up'')')
end
end
case 'motion'
if isstruct(Udata)
pt = hgconvertunits(hfig,[0 0 get(hfig,'CurrentPoint')],...
get(hfig,'Units'),'pixels',0);
pt = pt(3:4);
deltaPix = pt-Udata.figLastPoint;
deltaPixStart = pt-Udata.figStartPoint;
Udata.figLastLastPoint = Udata.figLastPoint;
Udata.figLastPoint = pt;
Udata.time = clock;
mode = lower(Udata.mode);
setUdata(Udata)
% Now perform the desired event from the rotation.
switch mode
case 'orbit'
orbitPangca(haxes,deltaPix, 'o');
case 'orbitscenelight'
orbitLightgca(haxes,deltaPix);
case 'pan'
orbitPangca(haxes,deltaPix, 'p');
case 'dollyhv'
dollygca(haxes,deltaPix);
case 'zoom'
zoomgca(haxes,deltaPix);
case 'dollyfb'
forwardBackgca(haxes,deltaPix, 'c');
case 'roll'
rollgca(haxes,deltaPix, pt);
case 'walk'
Udata.moving = 1;
setUdata(Udata)
if isempty(walk_flag)
walk_flag = 1;
walkgca(haxes,deltaPixStart,[]);
else
walkgca(haxes,deltaPixStart,1);
end
end
end
case 'up'
set(hfig, 'windowbuttonmotionfcn', '')
set(hfig, 'windowbuttonupfcn', '')
Udata.buttondown = 0;
Udata.moving = 0;
pt = hgconvertunits(hfig,[0 0 get(hfig,'CurrentPoint')],...
get(hfig,'Units'),'pixels',0);
pt = pt(3:4);
deltaPix = pt-Udata.figLastLastPoint;
deltaPixStart = pt-Udata.figStartPoint;
Udata.figLastPoint = pt;
% Checking the sensitivity of the camera throw mode w.r.t mouse events
% Speed at the end being proportional to the dist travelled at the end...
speed_sense = sqrt((deltaPix(1)^2)+(deltaPix(2)^2));
% Total distance travelled from start to finish:
dist_sense = sqrt((deltaPixStart(1)^2)+(deltaPixStart(2)^2));
% Scaling down the speed of motion in the throw mode
mode = lower(Udata.mode);
clear walk_flag;
setUdata(Udata)
% Scale down the deltas to get a reasonable speed.
scaled_deltaPix = deltaPix/10;
scaled_deltaPixStart = deltaPixStart/10;
if etime(clock, Udata.time)<.5 & (speed_sense>=7) & (dist_sense>30) ...
& any(deltaPix) & ~strcmp('alt', get(hfig, 'selectiontype'))
Udata.moving = 1;
setUdata(Udata)
switch mode
case 'orbit'
orbitPangca(haxes,scaled_deltaPix, 'o');
case 'orbitscenelight'
orbitLightgca(haxes,scaled_deltaPix);
case 'pan'
orbitPangca(haxes,scaled_deltaPix, 'p');
%case 'roll'
%rollgca(haxes,deltaPix);
case 'walk'
walkgca(haxes,scaled_deltaPixStart,1);
end
end
case 'keymotion'
cameratoolbar2('down',logical(0));
Udata = getUdata;
if isstruct(Udata) & isfield(Udata,'figLastPoint')
if (etime(clock,Udata.time))<.3
multFact=20; %should rotate faster when the key is held down
else
multFact=5;
end
set(hfig,'currentpoint',Udata.figLastLastPoint + multFact*varargin{2});
cameratoolbar2('motion');
cameratoolbar2('up');
end
case 'stopmoving'
Udata.moving = 0;
setUdata(Udata)
case 'updatetoolbar'
updateToolbar(hfig)
case 'setmodegui'
%setmodegui differs from setmode in that setting the same
%mode as the current mode will toggle it off
newmode = lower(varargin{2});
if strcmp(Udata.mode, newmode)
cameratoolbar2('nomode')
Udata = getUdata;
else
showInfoDlg(haxes);
Udata.mode = newmode;
scribeclearmode(hfig,'cameratoolbar', 'nomode');
end
if iscameraobj(haxes)
if strcmp(Udata.mode, 'walk')
camproj(haxes,'perspective');
end
end
setUdata(Udata)
updateToolbar(hfig)
case 'setmode'
newmode = lower(varargin{2});
if strcmp(newmode, 'nomode')
cameratoolbar nomode
else
Udata.mode = newmode;
scribeclearmode(hfig,'cameratoolbar', 'nomode');
if iscameraobj(haxes)
if strcmp(Udata.mode, 'walk')
camproj(haxes,'perspective');
end
end
setUdata(Udata)
updateToolbar(hfig)
end
case 'keypress'
if(isempty(haxes)) return; end
switch get(hfig,'currentcharacter')
case 'o'
cameratoolbar('setmode','orbit');
case 'l'
cameratoolbar('setmode','orbitscenelight');
case 'p'
cameratoolbar('setmode','pan');
case 'd'
cameratoolbar('setmode','dollyhv');
case 'z'
cameratoolbar('setmode','zoom');
case 'r'
cameratoolbar('setmode','roll');
case 'w'
cameratoolbar('setmode','walk');
case 'D'
cameratoolbar('setmode','dollyfb');
case char(28) %left
cameratoolbar('keymotion',[-1 0]);
case char(29) %right
cameratoolbar('keymotion',[ 1 0]);
case char(30) %up
cameratoolbar('keymotion',[ 0 1]);
case char(31) %down
cameratoolbar('keymotion',[ 0 -1]);
case 'c'
postContextMenu(hfig,haxes);
end
case 'setcoordsys'
newcoordsys = lower(varargin{2});
Udata.coordsys = newcoordsys;
setUdata(Udata)
if iscameraobj(haxes)
if length(Udata.coordsys)==1
coordsysval = lower(Udata.coordsys) - 'x' + 1;
d = [0 0 0];
d(coordsysval) = 1;
up = camup(haxes);
if up(coordsysval) < 0
d = -d;
end
% Check if the camera up vector is parallel with the view direction;
% if not, set the up vector
if any(crossSimple(d,campos(haxes)-camtarget(haxes)))
camup(haxes,d)
validateScenelights(haxes)
updateScenelightPosition(haxes);
end
end
end
updateToolbar(hfig)
case 'togglescenelight'
if iscameraobj(haxes)
validateScenelights(haxes)
Udata = getUdata;
sl = Udata.scenelights;
ax = haxes;
if isempty(sl)
val = 1;
else
index = find([sl.ax]==ax);
val = ~sl(index).on;
end
if ~val & strcmp(Udata.mode, 'orbitscenelight')
Udata.mode = 'orbit';
setUdata(Udata)
updateToolbar(hfig)
end
updateScenelightOnOff(haxes,val);
updateScenelightPosition(haxes);
end
case 'setprojection'
if iscameraobj(haxes)
camproj(haxes,lower(varargin{2}));
end
case 'resetscenelight'
if iscameraobj(haxes)
resetScenelight(haxes);
end
case 'resetall'
h = [Udata.scenelights.h]; delete(h(ishandle(h)));
initUdata;
updateToolbar(hfig)
cameratoolbar2('resetcameraandscenelight');
case 'resetcameraandscenelight'
if iscameraobj(haxes)
resetCameraProps(haxes)
resetScenelight(haxes);
end
case 'resetcamera'
if iscameraobj(haxes)
resetCameraProps(haxes);
end
case 'resettarget'
if iscameraobj(haxes)
camtarget(haxes,'auto');
validateScenelights(haxes)
updateScenelightPosition(haxes);
end
case 'noreset'
r=cameratoolbar2('show');
case 'nomode'
Udata.mode = '';
restoreWindowCallbacks(hfig,Udata.wcb);
setUdata(Udata)
updateToolbar(hfig)
restoreWindowCursor(hfig,Udata.cursor);
removeContextMenu(hfig);
case 'init'
emptyUdata = isempty(Udata);
wcb = getWindowCallBacks(hfig);
cursor = getWindowCursor(hfig);
ctb = findall(hfig, 'tag', 'cameratoolbar');
if isempty(ctb)
r = createToolbar(hfig);
end
if ~emptyUdata
h = [Udata.scenelights.h]; delete(h(ishandle(h)));
end
initUdata;
Udata = getUdata;
if emptyUdata
Udata.wcb = wcb;
Udata.cursor = cursor;
end
setUdata(Udata)
updateToolbar(hfig)
case 'show'
set(Udata.mainToolbarHandle, 'visible', 'on');
case 'hide'
set(Udata.mainToolbarHandle, 'visible', 'off');
case 'toggle'
h = Udata.mainToolbarHandle;
newval = strcmp(get(h, 'visible'), 'off');
set(h, 'visible', bool2OnOff(newval))
case 'getvisible'
if isempty(Udata)
r = 0;
else
h = Udata.mainToolbarHandle;
r = strcmp(get(h, 'visible'), 'on');
end
case 'getmode'
if isempty(Udata)
r = '';
else
r = Udata.mode;
end
case 'getcoordsys'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -