From 451833e2188d33c208f5d81394af9ca3799b3789 Mon Sep 17 00:00:00 2001 From: Reinhard Kotucha Date: Sat, 25 Nov 2006 04:03:28 +0000 Subject: update movie15. git-svn-id: svn://tug.org/texlive/trunk@2519 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/movie15/movie15.sty | 1064 +++++++++++++---------- 1 file changed, 610 insertions(+), 454 deletions(-) (limited to 'Master/texmf-dist/tex/latex/movie15') diff --git a/Master/texmf-dist/tex/latex/movie15/movie15.sty b/Master/texmf-dist/tex/latex/movie15/movie15.sty index e71a6b6414f..bd4134da353 100644 --- a/Master/texmf-dist/tex/latex/movie15/movie15.sty +++ b/Master/texmf-dist/tex/latex/movie15/movie15.sty @@ -9,7 +9,7 @@ % \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{movie15}[2006/10/12] +\ProvidesPackage{movie15}[2006/11/21] \RequirePackage{keyval} \RequirePackage{ifthen} \RequirePackage{ifpdf} @@ -58,8 +58,24 @@ %for conditionals where \ifthenelse doesn't work \gdef\@MXV@if#1{\csname if#1\endcsname}% +\newboolean{@MXV@beamer} %set to true if beamer class has been loaded +\newboolean{@MXV@powerdot} %the same for \newboolean{@MXV@presentation} %used with presentation making package? \newboolean{@MXV@hide} %contents hidden on the current slide? +\@ifclassloaded{beamer}{% + \setboolean{@MXV@beamer}{true}% + \setboolean{@MXV@presentation}{true}% +}{% + \setboolean{@MXV@beamer}{false}% + \setboolean{@MXV@presentation}{false}% +} +\@ifclassloaded{powerdot}{% + \setboolean{@MXV@powerdot}{true}% + \setboolean{@MXV@presentation}{true}% +}{% + \setboolean{@MXV@powerdot}{false}% + \setboolean{@MXV@presentation}{false}% +} \ifthenelse{\boolean{@MXV@iiiDfeat}}{% \newcount\@MXV@iiidoncurpage%index of 3D annot on current page @@ -100,9 +116,9 @@ \gdef\@MXV@warning{}% of document \AtEndDocument{% \PackageWarningNoLine{movie15}{% - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\MessageBreak - @@ Rerun to get cross-references right! @@\MessageBreak - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}% + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\MessageBreak + @@ Rerun to get object references right! @@\MessageBreak + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}% }% }{}% }{}% @@ -230,6 +246,7 @@ \ifthenelse{\boolean{@MXV@iiiDfeat}}{% \setboolean{@MXV@iiid}{false}% \gdef\@MXV@aac{30}% aperture angle of camera + \gdef\@MXV@roll{0}% camera roll angle \gdef\@MXV@background{}% \gdef\@MXV@jscriptiiidfile{}% \gdef\@MXV@coo{0 0 0}% centre of orbit @@ -243,6 +260,7 @@ %would be noninteractive, i. e. would not respond to mouse events \setboolean{@MXV@iiidctrls}{true}% \gdef\@MXV@calc{}% camera aperture for coo and roo calculation + \setboolean{@MXV@iiidgetview}{false}% }{}% }% @@ -360,13 +378,15 @@ \newcount\@MXV@viewscount%counter for number of 3D views per inclusion \newboolean{@MXV@viewsprovided}%3d views file provided? \newboolean{@MXV@iiidctrls}% show controls? + \newboolean{@MXV@iiidgetview}% print current 3D settings? \newboolean{@MXV@defaultviewprovided}%default 3D view provided? %macro for building the transformation matrix - \def\@MXV@ciiwmatrix#1 #2 #3 #4 #5 #6 #7 {% + \def\@MXV@ciiwmatrix#1 #2 #3 #4 #5 #6 #7 #8 {% % #1,#2,#3 centre of orbit coordinates (coo) % #4,#5,#6 centre of orbit to camera direction vector (c2c) % #7 orbital radius (roo) + % #8 camera roll (roll) %view vector (opposite to c2c) \FPupn\@MXV@viewx{#4 neg}% \FPupn\@MXV@viewy{#5 neg}% @@ -379,44 +399,72 @@ \FPupn\@MXV@viewx{\@MXV@viewx{} \@MXV@modulo{} div}% \FPupn\@MXV@viewy{\@MXV@viewy{} \@MXV@modulo{} div}% \FPupn\@MXV@viewz{\@MXV@viewz{} \@MXV@modulo{} div}% - %rotation matrix + %camera roll + \FPupn\@MXV@sinroll{#8 180.0 div \FPpi{} mul sin}% + \FPupn\@MXV@cosroll{#8 180.0 div \FPpi{} mul cos}% + % + %top and bottom views + \FPupn\@MXV@leftx{-1.0}% + \FPupn\@MXV@lefty{0.0}% + \FPupn\@MXV@leftz{0.0}% + % \FPifneg\@MXV@viewz% top view - \xdef\@MXV@matrix{-1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 -1.0}% + %up-vector + \FPupn\@MXV@upx{0.0}% + \FPupn\@MXV@upy{1.0}% + \FPupn\@MXV@upz{0.0}% \else% bottom view - \xdef\@MXV@matrix{-1.0 0.0 0.0 0.0 -1.0 0.0 0.0 0.0 1.0}% + %up-vector + \FPupn\@MXV@upx{0.0}% + \FPupn\@MXV@upy{-1.0}% + \FPupn\@MXV@upz{0.0}% \fi% \FPupn\@MXV@sumxy{\@MXV@viewx{} abs \@MXV@viewy{} abs add}% \FPifeq\@MXV@sumxy{0}\else% other views than top and bottom - %up vector = up_world - (up_world dot view) view + %up-vector = up_world - (up_world dot view) view \FPupn\@MXV@upx{\@MXV@viewz{} \@MXV@viewx{} mul neg}% \FPupn\@MXV@upy{\@MXV@viewz{} \@MXV@viewy{} mul neg}% \FPupn\@MXV@upz{\@MXV@viewz{} \@MXV@viewz{} mul neg 1.0 add}% - %normalize up vector + %normalize up-vector \FPupn\@MXV@modulo{\@MXV@upx{} copy mul \@MXV@upy{} copy % mul + \@MXV@upz{} copy mul + 2 swap root}% \FPupn\@MXV@upx{\@MXV@upx{} \@MXV@modulo{} div}% \FPupn\@MXV@upy{\@MXV@upy{} \@MXV@modulo{} div}% \FPupn\@MXV@upz{\@MXV@upz{} \@MXV@modulo{} div}% %left vector = up x view - \FPupn\@MXV@leftx{\@MXV@viewy{} \@MXV@upz{} mul % - \@MXV@viewz{} \@MXV@upy{} mul sub}% - \FPupn\@MXV@lefty{\@MXV@viewz{} \@MXV@upx{} mul % - \@MXV@viewx{} \@MXV@upz{} mul sub}% - \FPupn\@MXV@leftz{\@MXV@viewx{} \@MXV@upy{} mul % - \@MXV@viewy{} \@MXV@upx{} mul sub}% + \FPupn\@MXV@leftx{\@MXV@viewz{} \@MXV@upy{} mul % + \@MXV@viewy{} \@MXV@upz{} mul sub}% + \FPupn\@MXV@lefty{\@MXV@viewx{} \@MXV@upz{} mul % + \@MXV@viewz{} \@MXV@upx{} mul sub}% + \FPupn\@MXV@leftz{\@MXV@viewy{} \@MXV@upx{} mul % + \@MXV@viewx{} \@MXV@upy{} mul sub}% %normalize left vector \FPupn\@MXV@modulo{\@MXV@leftx{} copy mul \@MXV@lefty{} % copy mul + \@MXV@leftz{} copy mul + 2 swap root}% \FPupn\@MXV@leftx{\@MXV@leftx{} \@MXV@modulo{} div}% \FPupn\@MXV@lefty{\@MXV@lefty{} \@MXV@modulo{} div}% \FPupn\@MXV@leftz{\@MXV@leftz{} \@MXV@modulo{} div}% - \xdef\@MXV@matrix{\@MXV@leftx\space\@MXV@lefty\space\@MXV@leftz\space% - \@MXV@upx\space\@MXV@upy\space\@MXV@upz\space% - \@MXV@viewx\space\@MXV@viewy\space\@MXV@viewz}% \fi% + %apply camera roll + \FPupn\@MXV@leftxprime{\@MXV@leftx{} \@MXV@cosroll{} mul \@MXV@upx{} \@MXV@sinroll{} mul +}% + \FPupn\@MXV@leftyprime{\@MXV@lefty{} \@MXV@cosroll{} mul \@MXV@upy{} \@MXV@sinroll{} mul +}% + \FPupn\@MXV@leftzprime{\@MXV@leftz{} \@MXV@cosroll{} mul \@MXV@upz{} \@MXV@sinroll{} mul +}% + \FPupn\@MXV@upxprime{\@MXV@upx{} \@MXV@cosroll{} mul \@MXV@leftx{} \@MXV@sinroll{} mul sub}% + \FPupn\@MXV@upyprime{\@MXV@upy{} \@MXV@cosroll{} mul \@MXV@lefty{} \@MXV@sinroll{} mul sub}% + \FPupn\@MXV@upzprime{\@MXV@upz{} \@MXV@cosroll{} mul \@MXV@leftz{} \@MXV@sinroll{} mul sub}% + \FPupn\@MXV@leftx{\@MXV@leftxprime}% + \FPupn\@MXV@lefty{\@MXV@leftyprime}% + \FPupn\@MXV@leftz{\@MXV@leftzprime}% + \FPupn\@MXV@upx{\@MXV@upxprime}% + \FPupn\@MXV@upy{\@MXV@upyprime}% + \FPupn\@MXV@upz{\@MXV@upzprime}% + %rotation matrix + \xdef\@MXV@matrix{\@MXV@leftx\space\@MXV@lefty\space\@MXV@leftz\space% + \@MXV@upx\space\@MXV@upy\space\@MXV@upz\space% + \@MXV@viewx\space\@MXV@viewy\space\@MXV@viewz}% %translation vector \FPupn\@MXV@roo{#7 abs}% - \FPiflt\@MXV@roo{0.001}\FPupn\@MXV@roo{0.001}\fi% + \FPifeq\@MXV@roo{0}\FPupn\@MXV@roo{0.000000000000000001}\fi% \FPupn\@MXV@transx{#1 \@MXV@roo{} \@MXV@viewx{} mul sub}% \FPupn\@MXV@transy{#2 \@MXV@roo{} \@MXV@viewy{} mul sub}% \FPupn\@MXV@transz{#3 \@MXV@roo{} \@MXV@viewz{} mul sub}% @@ -427,7 +475,7 @@ } %macro for parsing one line of 3D views file - \newcommand{\@MXV@parseline}[5][]{% + \newcommand{\@MXV@parseline}[6][]{% \xdef\@MXV@xname{#1}% name of the view (optional) \ifthenelse{\equal{#2}{}}{% \xdef\@MXV@coo{0 0 0}% @@ -445,9 +493,14 @@ \xdef\@MXV@roo{#4}% }% \ifthenelse{\equal{#5}{}}{% + \xdef\@MXV@roll{0}% + }{% + \xdef\@MXV@roll{#5}% + }% + \ifthenelse{\equal{#6}{}}{% \xdef\@MXV@aac{30}% }{% - \xdef\@MXV@aac{#5}% + \xdef\@MXV@aac{#6}% }% } @@ -457,7 +510,7 @@ \xdef\@MXV@varray{}% empty varray % %default view - \edef\@MXV@args{\@MXV@coo\space\@MXV@ctoc\space\@MXV@roo\space}% + \edef\@MXV@args{\@MXV@coo\space\@MXV@ctoc\space\@MXV@roo\space\@MXV@roll\space}% \expandafter\@MXV@ciiwmatrix\@MXV@args% build C2W matrix \xdef\@MXV@xname{Default}% \@MXV@viewobj% create pdf object of 3D view @@ -473,7 +526,7 @@ \read\@MXV@@viewsfile to \@MXV@inputline% \if\@MXV@inputline\relax\else% \expandafter\@MXV@parseline\@MXV@inputline% - \edef\@MXV@args{\@MXV@coo\space\@MXV@ctoc\space\@MXV@roo\space}% + \edef\@MXV@args{\@MXV@coo\space\@MXV@ctoc\space\@MXV@roo\space\@MXV@roll\space}% \expandafter\@MXV@ciiwmatrix\@MXV@args% build C2W matrix \global\advance\@MXV@viewscount by 1% \ifthenelse{\equal{\@MXV@xname}{}}{% @@ -568,7 +621,7 @@ \ifthenelse{\boolean{@MXV@inline}\AND\boolean{@MXV@externalviewer}% % since Reader 7.0.7, we cannot place a file attachment annot behind % the 3D annot :-( -% \OR\boolean{@MXV@attachment}% +% \OR\boolean{@MXV@attachment} }{% \pdfannot width #1 height #2 depth #3 {% /Subtype /FileAttachment% @@ -647,7 +700,7 @@ \else% \edef\@MXV@iiidstreamorref{\@MXV@iiidstream}% \fi% - %annotation object of subtype `3D'% + %annotation object of subtype `3D' \pdfannot width #1 height #2 depth #3 {% /Subtype/3D% /F 4% we cannot put F 5 here; bug in Reader; 3D annot would be @@ -788,7 +841,7 @@ % %insert FileAttachment annotation \ifthenelse{\boolean{@MXV@inline}\AND\boolean{@MXV@externalviewer}% -% \OR\boolean{@MXV@attachment}% +% \OR\boolean{@MXV@attachment} }{% \makebox[0pt][l]{% \pdfmark[\phantom{\@MXV@box{#1}{#2}{#3}}]{% @@ -1150,7 +1203,7 @@ }% % \if@MXV@externalviewer\else% - %new annotation object of subtype `Screen'% + %new annotation object of subtype `Screen' \pdfannot width #1 height #2 depth #3 {% /Subtype /Screen% /Border [0 0 0]% no border (PDF-1.1) @@ -1308,7 +1361,7 @@ \if@MXV@externalviewer% \@MXV@box{#1}{#2}{#3}% \else% - %new annotation object of subtype `Screen'% + %new annotation object of subtype `Screen' \pdfmark[\@MXV@box{#1}{#2}{#3}]{% pdfmark=/ANN,% Subtype=/Screen,% @@ -1572,25 +1625,20 @@ \savebox{\@MXV@textbox}{\makebox[\@MXV@width][c]{\usebox{\@MXV@textbox}}}% }% % - %find out if some presentation making package is being used - %and whether the contents should be hidden or not on the current slide - \setboolean{@MXV@presentation}{false}% + %find out whether the contents should be hidden or not (for presentations) \setboolean{@MXV@hide}{false}% - \ifx\ifpd@overlay\@undefined\relax% - \else% powerdot - \setboolean{@MXV@presentation}{true}% + \ifthenelse{\boolean{@MXV@powerdot}}{% \ifthenelse{\boolean{pd@overlay}}{}{% \ifthenelse{\pd@method=2}{}{% \setboolean{@MXV@hide}{true}% }% }% - \fi% - \ifx\ifbeamer@anotherslide\@undefined\relax\else% - \setboolean{@MXV@presentation}{true}% + }{}% + \ifthenelse{\boolean{@MXV@beamer}}{% \ifthenelse{\boolean{beamer@anotherslide}}{% \setboolean{@MXV@hide}{true}% }{}% - \fi% + }{}% % \ifthenelse{\boolean{@MXV@hide}}{% %insert whitespace instead of annot @@ -1631,19 +1679,19 @@ \def\@MXV@runattr{}% }{% \edef\@MXV@urlattr{% - \ifx\beamer@version\@undefined% - /Border [\@pdfborder]% - \else% + \if@MXV@beamer% /Border [1 1 1]% + \else% + /Border [\@pdfborder]% \fi% /C [\@urlbordercolor]% /H \@pdfhighlight% }% \edef\@MXV@runattr{% - \ifx\beamer@version\@undefined% - /Border [\@pdfborder]% - \else% + \if@MXV@beamer% /Border [1 1 1]% + \else% + /Border [\@pdfborder]% \fi% /C [\@runbordercolor]% /H \@pdfhighlight% @@ -2046,25 +2094,20 @@ \leavevmode% \savebox{\@MXV@textbox}{#3}% save text argument % - %find out if some presentation making package is being used - %and whether the contents should be hidden or not on the current slide - \setboolean{@MXV@presentation}{false}% + %find out whether the contents should be hidden or not (for presentations) \setboolean{@MXV@hide}{false}% - \ifx\ifpd@overlay\@undefined\relax% - \else% powerdot - \setboolean{@MXV@presentation}{true}% + \ifthenelse{\boolean{@MXV@powerdot}}{% \ifthenelse{\boolean{pd@overlay}}{}{% \ifthenelse{\pd@method=2}{}{% \setboolean{@MXV@hide}{true}% }% }% - \fi% - \ifx\ifbeamer@anotherslide\@undefined\relax\else% - \setboolean{@MXV@presentation}{true}% + }{}% + \ifthenelse{\boolean{@MXV@beamer}}{% \ifthenelse{\boolean{beamer@anotherslide}}{% \setboolean{@MXV@hide}{true}% }{}% - \fi% + }{}% % \ifthenelse{\boolean{@MXV@hide}}{% %put whitespace instead of link annot @@ -2130,436 +2173,535 @@ %else use the indexed view specified by option `3Dviewindex' \fi% % - %java script action + %create JavaScript (options 3Djscript, 3Dcalculate, 3Dgetview) \ifthenelse{\NOT\equal{\@MXV@jscriptiiidfile}{}% \OR\NOT\equal{\@MXV@calc}{}% + \OR\boolean{@MXV@iiidgetview}% }{% + \edef\@MXV@linkjscriptiiid{% + try{% + %fill hash (annot3D) with refs to Annot3D objects + annot3D["\@MXV@label"]=getAnnots3D(% + \@MXV@getlabelvalue{% + @MXV@annot\@MXV@getlabelvalue{@MXV@\@MXV@@label.annotid}.page% + }-1% + )[\@MXV@getlabelvalue{@MXV@\@MXV@@label.3Doncurpage}-1];% + annot3D["\@MXV@label"].activated=true;% + }catch(e){% + try{% + annot3D=new Array;% + annot3D["\@MXV@label"]=getAnnots3D(% + \@MXV@getlabelvalue{% + @MXV@annot\@MXV@getlabelvalue{@MXV@\@MXV@@label.annotid}.page% + }-1% + )[\@MXV@getlabelvalue{@MXV@\@MXV@@label.3Doncurpage}-1];% + annot3D["\@MXV@label"].activated=true;% + }catch(e){% + var spc=String.fromCharCode(32);% + app.alert("3D" + spc + "annotation" + spc + "could" + spc +% + "not" + spc + "be" + spc + "activated!");% + }% + }% + }% + \if@MXV@iiidgetview% + \edef\@MXV@linkjscriptiiid{% + \@MXV@linkjscriptiiid + try{ + %JavaScript to print the camera settings of the current view + var camera=annot3D["\@MXV@label"].context3D.scene.cameras.getByIndex(0);% + var coo=camera.targetPosition;% + var c2c=camera.position.subtract(coo);% + var roo=c2c.length;% + c2c.normalize();% + % + %assemble result string + %{ }{ }{}{} + var spc=String.fromCharCode(32);% + var res='{';% + var x = (Math.abs(coo.x) < 1e-18 ? 0 : coo.x);% + var y = (Math.abs(coo.y) < 1e-18 ? 0 : coo.y);% + var z = (Math.abs(coo.z) < 1e-18 ? 0 : coo.z);% + if(Math.sqrt(x*x + y*y + z*z) > 0){% + res+=util.printf('\%s' + spc + '\%s' + spc + '\%s',% + (Math.abs(x) < 1.001e-6 && Math.abs(x) > 0 ?% + util.printf('\%.18f', x): x),% + (Math.abs(y) < 1.001e-6 && Math.abs(y) > 0 ?% + util.printf('\%.18f', y): y),% + (Math.abs(z) < 1.001e-6 && Math.abs(z) > 0 ?% + util.printf('\%.18f', z): z)% + );% + }% + res+='}{';% + x = (Math.abs(c2c.x) < 1e-18 ? 0 : c2c.x);% + y = (Math.abs(c2c.y) < 1e-18 ? 0 : c2c.y);% + z = (Math.abs(c2c.z) < 1e-18 ? 0 : c2c.z);% + if(!(x==0 && y==-1 && z==0)){% + res+=util.printf('\%s' + spc + '\%s' + spc + '\%s',% + (Math.abs(x) < 1.001e-6 && Math.abs(x) > 0 ?% + util.printf('\%.18f', x): x),% + (Math.abs(y) < 1.001e-6 && Math.abs(y) > 0 ?% + util.printf('\%.18f', y): y),% + (Math.abs(z) < 1.001e-6 && Math.abs(z) > 0 ?% + util.printf('\%.18f', z): z)% + );% + }% + res+='}{';% + if(roo > 0.11e-17){% + res+=util.printf('\%s',% + (roo < 1.001e-6 ? util.printf('\%.18f', roo): roo)% + );% + }% + res+='}{';% + %determine the camera roll (camera.roll is bugged) + %camera up-vector from camera.up, the latter being the positional vector + %of the actual camera up-vector tip + var up = camera.up.subtract(camera.position);% + up.normalize();% + %find the camera up-vector up0, that corresponds to zero roll + %(Gram-Schmitt orthogonalisation) + var worldup=new annot3D["\@MXV@label"].context3D.Vector3();% + worldup.set(0,0,1);% + var out=c2c.scale(-1);% + var up0=worldup.subtract(out.scale(out.dot(worldup)));% + up0.normalize();% + var up0xup=up0.cross(up);% + var roll=0;% + if(up0xup.length>0){% + up0xup.normalize();% + var up0dotup=up.dot(up0);% + up0dotup=(Math.abs(up0dotup) > 1 ? Math.round(up0dotup) : up0dotup);% + %compute the angle between camera up and up0 vectors + roll=Math.acos(up0dotup)*180/Math.PI*out.dot(up0xup);% + }% + if(util.printf('\%.5f', roll)!=0){% + res+=util.printf('\%s', roll);% + }% + res+='}{';% + aac=camera.fov * 180/Math.PI;% + if(util.printf('\%.5f', aac)!=30){% + res+=util.printf('\%s',% + (Math.abs(aac) < 1.001e-6 ? util.printf('\%.18f', aac): aac)% + );% + }% + res+='}';% + %open pop-up displaying the result string + var settings={% + initialize: function(dialog) {% + dialog.load({% + "text": res% + });% + },% + description: {% + name: 'Current' + spc + '3D' + spc + 'Camera' + spc + 'Settings',% + elements: [% + {% + type: "static_text",% + name: 'Add' + spc + 'the' + spc + 'following' + spc + 'line' + spc +% + 'to' + spc + 'a' + spc + 'file' + spc + 'of' + spc +% + 'predefined' + spc + 'views.' + spc +% + '(See' + spc + 'option' + spc + "`3Dviews'!)"% + },% + {% + type: "edit_text",% + item_id: "text",% + alignment: "align_fill",% + readonly: false% + },% + {% + type: "ok",% + ok_name: "Close"% + }% + ]% + }% + };% + app.execDialog(settings);% + }catch(e){% + var spc=String.fromCharCode(32);% + app.alert("Error" + spc + "while" + spc + "executing" + spc +% + "`3Dgetview':" + spc + e);% + }% + }% + \fi% + \ifx\@MXV@calc\@empty\else% + \edef\@MXV@linkjscriptiiid{% + \@MXV@linkjscriptiiid + try{ + %constructor for doubly linked list + function List(){% + this.first_node=null;% + this.last_node=new Node(undefined);% + }% + List.prototype.push_back=function(x){% + var new_node=new Node(x);% + if(this.first_node==null){% + this.first_node=new_node;% + new_node.prev=null;% + }else{% + new_node.prev=this.last_node.prev;% + new_node.prev.next=new_node;% + }% + new_node.next=this.last_node;% + this.last_node.prev=new_node;% + };% + List.prototype.move_to_front=function(it){% + var node=it.get();% + if(node.next!=null && node.prev!=null){% + node.next.prev=node.prev;% + node.prev.next=node.next;% + node.prev=null;% + node.next=this.first_node;% + this.first_node.prev=node;% + this.first_node=node;% + }% + };% + List.prototype.begin=function(){% + var i=new Iterator();% + i.target=this.first_node;% + return(i);% + };% + List.prototype.end=function(){% + var i=new Iterator();% + i.target=this.last_node;% + return(i);% + };% + function Iterator(it){% + if( it!=undefined ){% + this.target=it.target;% + }else {% + this.target=null;% + }% + }% + Iterator.prototype.set=function(it){this.target=it.target;};% + Iterator.prototype.get=function(){return(this.target);};% + Iterator.prototype.deref=function(){return(this.target.data);};% + Iterator.prototype.incr=function(){% + if(this.target.next!=null){this.target=this.target.next;}% + };% + %constructor for node objects that populate the linked list + function Node(x){% + this.prev=null;% + this.next=null;% + this.data=x;% + }% + function sqr(r){return(r*r);}%helper function + %The following code borrows heavily from Bernd Gaertners `Miniball' software, + %originally written in C++, for computing the smallest enclosing ball of a + %set of points; see: http://www.inf.ethz.ch/personal/gaertner/miniball.html + function Basis(){% + this.m=0;% + this.q0=new Array(3);% + this.z=new Array(4);% + this.f=new Array(4);% + this.v=new Array(new Array(3), new Array(3), new Array(3), new Array(3));% + this.a=new Array(new Array(3), new Array(3), new Array(3), new Array(3));% + this.c=new Array(new Array(3), new Array(3), new Array(3), new Array(3));% + this.sqr_r=new Array(4);% + this.current_c=this.c[0];% + this.current_sqr_r=0;% + this.reset();% + }% + Basis.prototype.center=function(){return(this.current_c);};% + Basis.prototype.size=function(){return(this.m);};% + Basis.prototype.pop=function(){--this.m;};% + Basis.prototype.excess=function(p){% + var e=-this.current_sqr_r;% + for(var k=0;k<3;++k){% + e+=sqr(p[k]-this.current_c[k]);% + }% + return(e);% + };% + Basis.prototype.reset=function(){% + this.m=0;% + for(var j=0;j<3;++j){% + this.c[0][j]=0;% + }% + this.current_c=this.c[0];% + this.current_sqr_r=-1;% + };% + Basis.prototype.push=function(p){% + var i, j;% + var eps=1e-32;% + if(this.m==0){% + for(i=0;i<3;++i){% + this.q0[i]=p[i];% + }% + for(i=0;i<3;++i){% + this.c[0][i]=this.q0[i];% + }% + this.sqr_r[0]=0;% + }else {% + for(i=0;i<3;++i){% + this.v[this.m][i]=p[i]-this.q0[i];% + }% + for(i=1;i 0){% + if(this.B.push(j.deref())){% + this.mtf_mb(j);% + this.B.pop();% + if(this.support_end.get()==j.get()){% + this.support_end.incr();% + }% + this.L.move_to_front(j);% + }% + }% + }% + };% + Miniball.prototype.check_in=function(b){% + this.L.push_back(b);% + };% + Miniball.prototype.build=function(){% + this.B.reset();% + this.support_end.set(this.L.begin());% + this.mtf_mb(this.L.end());% + };% + Miniball.prototype.center=function(){% + return(this.B.center());% + };% + Miniball.prototype.radius=function(){% + return(Math.sqrt(this.B.current_sqr_r));% + };% + %create Miniball object + var mb=new Miniball();% + %aperture angle of the virtual camera + var aac=\@MXV@calc;% + %list of mesh nodes + var meshes=annot3D["\@MXV@label"].context3D.scene.meshes;% + %auxiliary vectors + var dir=new annot3D["\@MXV@label"].context3D.Vector3();% + var up=new annot3D["\@MXV@label"].context3D.Vector3();% + var corner=new annot3D["\@MXV@label"].context3D.Vector3();% + %auxiliary 4x4 matrix + var bbox4x4=new annot3D["\@MXV@label"].context3D.Matrix4x4();% + %iterate over all mesh nodes in the scene + for(i=0;i) seems + %to be bugged, therefore we must resort to the + %multiply() method using an auxiliary matrix + %which contains the local bounding box corner coordinates + % + %auxiliary matrix from bbox.min coordinates + bbox4x4.setView(bbox.min, dir, up);% + %transform to world coordinates + bbox4x4=trans.multiply(bbox4x4.transpose);% + %extract the transformed coordinates + corner.set(bbox4x4.transpose.translation);% + %check-in corner position into Miniball + mb.check_in(new Array(corner.x, corner.y, corner.z));% + %the same procedure with bbox.max + bbox4x4.setView(bbox.max, dir, up);% + bbox4x4=trans.multiply(bbox4x4.transpose);% + corner.set(bbox4x4.transpose.translation);% + mb.check_in(new Array(corner.x, corner.y, corner.z));% + %and with all remaining 6 bbox corners + corner.set(bbox.min.x, bbox.max.y, bbox.max.z);% + bbox4x4.setView(corner, dir, up);% + bbox4x4=trans.multiply(bbox4x4.transpose);% + corner.set(bbox4x4.transpose.translation);% + mb.check_in(new Array(corner.x, corner.y, corner.z));% + corner.set(bbox.min.x, bbox.min.y, bbox.max.z);% + bbox4x4.setView(corner, dir, up);% + bbox4x4=trans.multiply(bbox4x4.transpose);% + corner.set(bbox4x4.transpose.translation);% + mb.check_in(new Array(corner.x, corner.y, corner.z));% + corner.set(bbox.min.x, bbox.max.y, bbox.min.z);% + bbox4x4.setView(corner, dir, up);% + bbox4x4=trans.multiply(bbox4x4.transpose);% + corner.set(bbox4x4.transpose.translation);% + mb.check_in(new Array(corner.x, corner.y, corner.z));% + corner.set(bbox.max.x, bbox.min.y, bbox.min.z);% + bbox4x4.setView(corner, dir, up);% + bbox4x4=trans.multiply(bbox4x4.transpose);% + corner.set(bbox4x4.transpose.translation);% + mb.check_in(new Array(corner.x, corner.y, corner.z));% + corner.set(bbox.max.x, bbox.min.y, bbox.max.z);% + bbox4x4.setView(corner, dir, up);% + bbox4x4=trans.multiply(bbox4x4.transpose);% + corner.set(bbox4x4.transpose.translation);% + mb.check_in(new Array(corner.x, corner.y, corner.z));% + corner.set(bbox.max.x, bbox.max.y, bbox.min.z);% + bbox4x4.setView(corner, dir, up);% + bbox4x4=trans.multiply(bbox4x4.transpose);% + corner.set(bbox4x4.transpose.translation);% + mb.check_in(new Array(corner.x, corner.y, corner.z));% + }% + %compute the smallest enclosing bounding sphere + mb.build();% + %bounding sphere centre + var coo=new annot3D["\@MXV@label"].context3D.Vector3();% + coo.set((mb.center())[0], (mb.center())[1], (mb.center())[2]);% + %radius of orbit + var roo=mb.radius()/ Math.sin(aac * Math.PI/ 360.);% + %result string + var res='';% + var spc=String.fromCharCode(32);% + if(aac!=30){% + res+=util.printf('3Daac=\%s,' + spc,% + (Math.abs(aac) < 1.001e-6 && Math.abs(aac) > 0 ?% + util.printf('\%.18f', aac): aac)% + );% + }% + if(coo.length){% + res+=util.printf( '3Dcoo=\%s' + spc + '\%s' + spc + '\%s,'% + + spc,% + (Math.abs(coo.x) < 1.001e-6 && Math.abs(coo.x) > 0 ?% + util.printf('\%.18f', coo.x): coo.x),% + (Math.abs(coo.y) < 1.001e-6 && Math.abs(coo.y) > 0 ?% + util.printf('\%.18f', coo.y): coo.y),% + (Math.abs(coo.z) < 1.001e-6 && Math.abs(coo.z) > 0 ?% + util.printf('\%.18f', coo.z): coo.z)% + );% + }% + res+=util.printf(% + '3Droo=\%s,' + spc, (roo < 1.001e-6 ? util.printf('\%.18f', roo): roo) + );% + var settings={% + initialize: function(dialog){% + dialog.load({% + "text": res% + });% + },% + description: {% + name: '3D' + spc + 'Camera' + spc + 'Settings',% + elements: [% + {% + type: "static_text",% + name: 'Copy' + spc + 'and' + spc + 'paste' + spc +% + 'the' + spc + 'following' + spc + 'to' + spc +% + 'the' + spc + 'option' + spc + 'list' + spc +% + 'of' + spc + spc + '\string\\\string\\includemovie!'% + },% + {% + type: "edit_text",% + item_id: "text",% + alignment: "align_fill",% + readonly: false% + },% + {% + type: "ok",% + ok_name: "Close"% + }% + ]% + }% + };% + app.execDialog(settings);% + }catch(e){% + var spc=String.fromCharCode(32);% + app.alert("Error" + spc + "while" + spc + "executing" + spc +% + "`3Dcalculate':" + spc + e);% + }% + }% + \fi% + %create stream from user provided JavaScript file \ifx\@MXV@jscriptiiidfile\@empty\else% - \ifthenelse{% + \ifthenelse{% create only once \equal{\@MXV@getlabelvalue{\@MXV@jscriptiiidfile}}{undefined}% }{% \ifpdf% \pdfobj stream file {\@MXV@jscriptiiidfile}% \pdfrefobj\pdflastobj% - \edef\@MXV@jscriptiiid{/JS \the\pdflastobj\space 0 R}% + \edef\@MXV@userjscriptiiidstream{\the\pdflastobj\space 0 R}% \@MXV@newlabel{\@MXV@jscriptiiidfile}{\the\pdflastobj}% \else% \pdfmark{% pdfmark=/OBJ,% Raw={% - /_objdef {linkjscriptiiid\the\@MXV@links}% + /_objdef {linkuserjscriptiiid\the\@MXV@links}% /type/stream% }% }% \pdfmark{% pdfmark=/PUT,% Raw={% - {linkjscriptiiid\the\@MXV@links}% + {linkuserjscriptiiid\the\@MXV@links}% (\@MXV@jscriptiiidfile) (r) file% }% }% - \edef\@MXV@jscriptiiid{% - /JS {linkjscriptiiid\the\@MXV@links}% + \edef\@MXV@userjscriptiiidstream{% + {linkuserjscriptiiid\the\@MXV@links}% }% \@MXV@newlabel{\@MXV@jscriptiiidfile}% - {linkjscriptiiid\the\@MXV@links}% + {linkuserjscriptiiid\the\@MXV@links}% \fi% }{% \ifpdf% - \edef\@MXV@jscriptiiid{% - /JS \@MXV@getlabelvalue{\@MXV@jscriptiiidfile}\space 0 R% + \edef\@MXV@userjscriptiiidstream{% + \@MXV@getlabelvalue{\@MXV@jscriptiiidfile}\space 0 R% }% \else% - \edef\@MXV@jscriptiiid{% - /JS {\@MXV@getlabelvalue{\@MXV@jscriptiiidfile}}% + \edef\@MXV@userjscriptiiidstream{% + {\@MXV@getlabelvalue{\@MXV@jscriptiiidfile}}% }% \fi% }% \fi% \edef\@MXV@jscriptiiidaction{% /Next <<% - /S/JavaScript% fill hash (annot3D) with refs to Annot3D objects - /JS (% for use within the user provided script - try{% - annot3D["\@MXV@label"]=getAnnots3D(% - \@MXV@getlabelvalue{% - @MXV@annot\@MXV@getlabelvalue{@MXV@\@MXV@@label.annotid}.page% - }-1% - )[\@MXV@getlabelvalue{@MXV@\@MXV@@label.3Doncurpage}-1]; - annot3D["\@MXV@label"].activated=true; - }catch(e){% - try{% - annot3D=new Array; - annot3D["\@MXV@label"]=getAnnots3D(% - \@MXV@getlabelvalue{% - @MXV@annot\@MXV@getlabelvalue{@MXV@\@MXV@@label.annotid}.page% - }-1% - )[\@MXV@getlabelvalue{@MXV@\@MXV@@label.3Doncurpage}-1]; - annot3D["\@MXV@label"].activated=true; - }catch(e){% - var spc=String.fromCharCode(32); - app.alert("3D" + spc + "annotation" + spc + "could" + spc + - "not" + spc + "be" + spc + "activated!"); - }% - }% - )% - %JavaScript for calculating 3Droo and 3Dcoo settings for a given - %aperture angle - \ifx\@MXV@calc\@empty\else% + /S/JavaScript% + /JS (\@MXV@linkjscriptiiid)% + \ifx\@MXV@jscriptiiidfile\@empty\else% /Next <<% /S/JavaScript% - /JS (try{% - %constructor for doubly linked list - function List() { - this.first_node = null; - this.last_node = new Node(undefined); - } - List.prototype.push_back = function (x) { - var new_node = new Node(x); - if (this.first_node == null) { - this.first_node = new_node; - new_node.prev = null; - } else { - new_node.prev = this.last_node.prev; - new_node.prev.next = new_node; - } - new_node.next = this.last_node; - this.last_node.prev = new_node; - }; - List.prototype.move_to_front = function (it) { - var node = it.get(); - if (node.next != null && node.prev != null) { - node.next.prev = node.prev; - node.prev.next = node.next; - node.prev = null; - node.next = this.first_node; - this.first_node.prev = node; - this.first_node = node; - } - }; - List.prototype.begin = function () { - var i = new Iterator(); - i.target = this.first_node; - return i; - }; - List.prototype.end = function () { - var i = new Iterator(); - i.target = this.last_node; - return i; - }; - function Iterator (it) { - if ( it != undefined ) { - this.target = it.target; - } else { - this.target = null; - } - } - Iterator.prototype.set = function (it) {this.target = it.target;}; - Iterator.prototype.get = function () {return this.target;}; - Iterator.prototype.deref = function () {return this.target.data;}; - Iterator.prototype.incr = function () { - if (this.target.next != null) {this.target = this.target.next;} - }; - %constructor for node objects that populate the linked list - function Node (x) { - this.prev=null; - this.next=null; - this.data=x; - } - function sqr (r) {return r*r;} %helper function - %The following code borrows heavily from Bernd Gaertners `Miniball' software, - %originally written in C++, for computing the smallest enclosing ball of a - %set of points; see: http://www.inf.ethz.ch/personal/gaertner/miniball.html - function Basis () { - this.m=0; - this.q0 = new Array(3); - this.z = new Array(4); - this.f = new Array(4); - this.v = new Array(new Array(3), new Array(3), new Array(3), new Array(3)); - this.a = new Array(new Array(3), new Array(3), new Array(3), new Array(3)); - this.c = new Array(new Array(3), new Array(3), new Array(3), new Array(3)); - this.sqr_r = new Array(4); - this.current_c = this.c[0]; - this.current_sqr_r=0; - this.reset(); - } - Basis.prototype.center = function () {return this.current_c;}; - Basis.prototype.size = function () {return this.m;}; - Basis.prototype.pop = function () {--this.m;}; - Basis.prototype.excess = function (p) { - var e = -this.current_sqr_r; - for (var k=0; k<3; ++k) { - e += sqr(p[k]-this.current_c[k]); - } - return e; - }; - Basis.prototype.reset = function () { - this.m = 0; - for (var j=0; j<3; ++j) { - this.c[0][j]=0; - } - this.current_c = this.c[0]; - this.current_sqr_r = -1; - }; - Basis.prototype.push = function (p) { - var i, j; - var eps=1e-32; - if (this.m==0) { - for (i=0; i<3; ++i) { - this.q0[i]=p[i]; - } - for (i=0; i<3; ++i) { - this.c[0][i]=this.q0[i]; - } - this.sqr_r[0]=0; - } else { - for (i=0; i<3; ++i) { - this.v[this.m][i] = p[i]-this.q0[i]; - } - for (i=1; i 0) { - if (this.B.push(j.deref())) { - this.mtf_mb(j); - this.B.pop(); - if (this.support_end.get() == j.get()) { - this.support_end.incr(); - } - this.L.move_to_front(j); - } - } - } - }; - Miniball.prototype.check_in = function (b) { - this.L.push_back(b); - }; - Miniball.prototype.build = function () { - this.B.reset(); - this.support_end.set(this.L.begin()); - this.mtf_mb(this.L.end()); - }; - Miniball.prototype.center = function () { - return this.B.center(); - }; - Miniball.prototype.radius = function () { - return Math.sqrt(this.B.current_sqr_r); - }; - % - %create Miniball object - var mb = new Miniball(); - % - %aperture angle of the virtual camera - var aac = \@MXV@calc; - % - %list of mesh nodes - var meshes = annot3D["\@MXV@label"].context3D.scene.meshes; - % - %auxiliary vectors - var dir = new annot3D["\@MXV@label"].context3D.Vector3(); - var up = new annot3D["\@MXV@label"].context3D.Vector3(); - var corner = new annot3D["\@MXV@label"].context3D.Vector3(); - % - %auxiliary 4x4 matrix - var bbox4x4 = new annot3D["\@MXV@label"].context3D.Matrix4x4(); - % - %iterate over all mesh nodes in the scene - for(i=0; i) seems - %to be bugged, therefore we must resort to the - %multiply() method using an auxiliary matrix - %which contains the local bounding box corner coordinates - % - %auxiliary matrix from bbox.min coordinates - bbox4x4.setView(bbox.min, dir, up); - % - %transform to world coordinates - bbox4x4 = trans.multiply(bbox4x4.transpose); - % - %extract the transformed coordinates - corner.set(bbox4x4.transpose.translation); - % - %check-in corner position into Miniball - mb.check_in(new Array(corner.x, corner.y, corner.z)); - % - %the same procedure with bbox.max - bbox4x4.setView(bbox.max, dir, up); - bbox4x4 = trans.multiply(bbox4x4.transpose); - corner.set(bbox4x4.transpose.translation); - mb.check_in(new Array(corner.x, corner.y, corner.z)); - % - %and with all remaining 6 bbox corners - corner.set(bbox.min.x, bbox.max.y, bbox.max.z); - bbox4x4.setView(corner, dir, up); - bbox4x4 = trans.multiply(bbox4x4.transpose); - corner.set(bbox4x4.transpose.translation); - mb.check_in(new Array(corner.x, corner.y, corner.z)); - % - corner.set(bbox.min.x, bbox.min.y, bbox.max.z); - bbox4x4.setView(corner, dir, up); - bbox4x4 = trans.multiply(bbox4x4.transpose); - corner.set(bbox4x4.transpose.translation); - mb.check_in(new Array(corner.x, corner.y, corner.z)); - % - corner.set(bbox.min.x, bbox.max.y, bbox.min.z); - bbox4x4.setView(corner, dir, up); - bbox4x4 = trans.multiply(bbox4x4.transpose); - corner.set(bbox4x4.transpose.translation); - mb.check_in(new Array(corner.x, corner.y, corner.z)); - % - corner.set(bbox.max.x, bbox.min.y, bbox.min.z); - bbox4x4.setView(corner, dir, up); - bbox4x4 = trans.multiply(bbox4x4.transpose); - corner.set(bbox4x4.transpose.translation); - mb.check_in(new Array(corner.x, corner.y, corner.z)); - % - corner.set(bbox.max.x, bbox.min.y, bbox.max.z); - bbox4x4.setView(corner, dir, up); - bbox4x4 = trans.multiply(bbox4x4.transpose); - corner.set(bbox4x4.transpose.translation); - mb.check_in(new Array(corner.x, corner.y, corner.z)); - % - corner.set(bbox.max.x, bbox.max.y, bbox.min.z); - bbox4x4.setView(corner, dir, up); - bbox4x4 = trans.multiply(bbox4x4.transpose); - corner.set(bbox4x4.transpose.translation); - mb.check_in(new Array(corner.x, corner.y, corner.z)); - }% - % - %compute the smallest enclosing bounding sphere - mb.build(); - % - %bounding sphere centre - var coo = new annot3D["\@MXV@label"].context3D.Vector3(); - coo.set((mb.center())[0], (mb.center())[1], (mb.center())[2]); - % - %radius of orbit - var roo = mb.radius()/ Math.sin(aac * Math.PI / 360.); - % - %assemble result string - var res = ''; - var spc=String.fromCharCode(32); - if(aac != 30){% - res += util.printf('3Daac=\%s,' + spc, % - (Math.abs(aac) < 1.001e-6 && Math.abs(aac) > 0 ? % - util.printf('\%.18f', aac): aac), 32% - ); - }% - if(coo.length){% - res += util.printf( '3Dcoo=\%s' + spc + '\%s' + spc + '\%s,' - + spc, % - (Math.abs(coo.x) < 1.001e-6 && Math.abs(coo.x) > 0 ? % - util.printf('\%.18f', coo.x): coo.x), % - (Math.abs(coo.y) < 1.001e-6 && Math.abs(coo.y) > 0 ? % - util.printf('\%.18f', coo.y): coo.y), % - (Math.abs(coo.z) < 1.001e-6 && Math.abs(coo.z) > 0 ? % - util.printf('\%.18f', coo.z): coo.z)% - ); - }% - res += '3Droo=' + roo + ','; - % - %open pop-up displaying the result string - var settings = {% - initialize: function(dialog) {% - dialog.load({% - "text": res% - }); - }, % - description: {% - name: '3D' + spc + 'Camera' + spc + 'Settings', % - elements: [% - {% - type: "static_text", % - name: 'Copy' + spc + 'and' + spc + 'paste' + spc + - 'the' + spc + 'following' + spc + 'to' + spc + - 'the' + spc + 'option' + spc + 'list' + spc + - 'of' + spc + '\string\\\string\\includemovie!'% - }, - {% - type: "edit_text", % - item_id: "text", % - alignment: "align_fill", % - readonly: false% - }, % - {% - type: "ok", % - ok_name: "Close"% - }% - ]% - }% - }; - app.execDialog(settings); - }catch(e){})% - \fi% - \ifx\@MXV@jscriptiiidfile\@empty\else% - /Next <<% - /S/JavaScript% - \@MXV@jscriptiiid% user provided script - >>% - \fi% - \ifx\@MXV@calc\@empty\else% + /JS \@MXV@userjscriptiiidstream% user provided script >>% \fi% >>% @@ -2781,10 +2923,10 @@ \def\@MXV@linkattr{}% }{% \edef\@MXV@linkattr{% - \ifx\beamer@version\@undefined% - /Border [\@pdfborder]% - \else% + \if@MXV@beamer% /Border [1 1 1]% + \else% + /Border [\@pdfborder]% \fi% /C [\@linkbordercolor]% /H \@pdfhighlight% @@ -3085,6 +3227,12 @@ \setboolean{@MXV@defaultviewprovided}{true}% }{\@MXV@neediiiD}% } +\define@key{movie15}{3Droll}{% + \ifthenelse{\boolean{@MXV@iiiDfeat}}{% + \def\@MXV@roll{#1}% + \setboolean{@MXV@defaultviewprovided}{true}% + }{\@MXV@neediiiD}% +} \define@key{movie15}{3Dviews}{% \ifthenelse{\boolean{@MXV@iiiDfeat}}{% \IfFileExists{#1}{% @@ -3097,10 +3245,6 @@ }% }{\@MXV@neediiiD}% } -\define@key{movie15}{3Dcalculate}[30]{% - %calculates optimal 3D settings for roo and coo for a given aac - \gdef\@MXV@calc{#1}% -} %options for \movieref command \define@key{movie15}{play}[true]{% \setboolean{@MXV@linkplay}{#1}% @@ -3178,6 +3322,18 @@ \setboolean{@MXV@defaultviewprovided}{false}% }{\@MXV@neediiiD}% } +\define@key{movie15}{3Dcalculate}[30]{% + %calculates optimal 3D settings for roo and coo for a given aac + \ifthenelse{\boolean{@MXV@iiiDfeat}}{% + \gdef\@MXV@calc{#1}% + }{\@MXV@neediiiD}% +} +\define@key{movie15}{3Dgetview}[true]{% + %print current 3D camera settings + \ifthenelse{\boolean{@MXV@iiiDfeat}}{% + \setboolean{@MXV@iiidgetview}{#1}% + }{\@MXV@neediiiD}% +} %compatibility macros \providecommand\movie[3][]{% -- cgit v1.2.3