diff options
author | Karl Berry <karl@freefriends.org> | 2012-03-28 23:03:12 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2012-03-28 23:03:12 +0000 |
commit | 6d8118c3d435067d6970edfdcd831a4141654dcc (patch) | |
tree | c33ec1f62724fd4a6aa6ad06b8c5197fe49db5e1 /Master/texmf-dist/tex/latex/media9 | |
parent | e54b7d07dfb4f3b812d1e90a7b56fe7f0fb37ac6 (diff) |
install media9
git-svn-id: svn://tug.org/texlive/trunk@25769 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/media9')
-rw-r--r-- | Master/texmf-dist/tex/latex/media9/javascript/3Dmenu.js | 885 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/media9/javascript/3Dspintool.js | 31 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/media9/javascript/animation.js | 118 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/media9/javascript/asylabels.js | 106 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/media9/media9.sty | 1996 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/media9/players/APlayer.mxml | 143 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/media9/players/APlayer.swf | bin | 0 -> 320911 bytes | |||
-rw-r--r-- | Master/texmf-dist/tex/latex/media9/players/VPlayer.mxml | 93 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/media9/players/VPlayer.swf | bin | 0 -> 440128 bytes |
9 files changed, 3372 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/media9/javascript/3Dmenu.js b/Master/texmf-dist/tex/latex/media9/javascript/3Dmenu.js new file mode 100644 index 00000000000..b6c82a22876 --- /dev/null +++ b/Master/texmf-dist/tex/latex/media9/javascript/3Dmenu.js @@ -0,0 +1,885 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// (C) 2012, Alexander Grahn +// +// 3Dmenu.js +// +// version 20120301 +// +//////////////////////////////////////////////////////////////////////////////// +// +// 3D JavaScript used by media9.sty +// +// Extended functionality of the (right click) context menu of 3D annotations. +// +// 1.) Adds the following items to the 3D context menu: +// +// * `Generate Default View' +// +// Finds good default camera settings, returned as options for use with +// the \includemedia command. +// +// * `Get Current View' +// +// Determines camera, cross section and part settings of the current view, +// returned as `VIEW' section that can be copied into a views file of +// additional views. The views file is inserted using the `3Dviews' option +// of \includemedia. +// +// * `Cross Section' +// +// Toggle switch to add or remove a cross section into or from the current +// view. The cross section can be moved in the x, y, z directions using x, +// y, z and X, Y, Z keys on the keyboard and be tilted against and spun +// around the upright Z axis using the Up/Down and Left/Right arrow keys. +// +// 2.) Enables manipulation of position and orientation of indiviual parts in +// the 3D scene. Parts which have been selected with the mouse can be +// moved around and rotated like the cross section as described above, as +// well as scaled using the s and S keys. +// +// This work may be distributed and/or modified under the +// conditions of the LaTeX Project Public License, either version 1.3 +// of this license or (at your option) any later version. +// The latest version of this license is in +// http://www.latex-project.org/lppl.txt +// and version 1.3 or later is part of all distributions of LaTeX +// version 2005/12/01 or later. +// +// This work has the LPPL maintenance status `maintained'. +// +// The Current Maintainer of this work is A. Grahn. +// +// The 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 +// +//////////////////////////////////////////////////////////////////////////////// +//host.console.show(); + +//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 + +//Miniball algorithm by B. Gaertner +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<this.m;++i){ + this.a[this.m][i]=0; + for(j=0;j<3;++j){ + this.a[this.m][i]+=this.v[i][j]*this.v[this.m][j]; + } + this.a[this.m][i]*=(2/this.z[i]); + } + for(i=1;i<this.m;++i){ + for(j=0;j<3;++j){ + this.v[this.m][j]-=this.a[this.m][i]*this.v[i][j]; + } + } + this.z[this.m]=0; + for(j=0;j<3;++j){ + this.z[this.m]+=sqr(this.v[this.m][j]); + } + this.z[this.m]*=2; + if(this.z[this.m]<eps*this.current_sqr_r) return(false); + var e=-this.sqr_r[this.m-1]; + for(i=0;i<3;++i){ + e+=sqr(p[i]-this.c[this.m-1][i]); + } + this.f[this.m]=e/this.z[this.m]; + for(i=0;i<3;++i){ + this.c[this.m][i]=this.c[this.m-1][i]+this.f[this.m]*this.v[this.m][i]; + } + this.sqr_r[this.m]=this.sqr_r[this.m-1]+e*this.f[this.m]/2; + } + this.current_c=this.c[this.m]; + this.current_sqr_r=this.sqr_r[this.m]; + ++this.m; + return(true); +}; +function Miniball(){ + this.L=new List(); + this.B=new Basis(); + this.support_end=new Iterator(); +} +Miniball.prototype.mtf_mb=function(it){ + var i=new Iterator(it); + this.support_end.set(this.L.begin()); + if((this.B.size())==4) return; + for(var k=new Iterator(this.L.begin());k.get()!=i.get();){ + var j=new Iterator(k); + k.incr(); + if(this.B.excess(j.deref()) > 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)); +}; + +//functions called by menu items +function calc3Dopts () { + //create Miniball object + var mb=new Miniball(); + //auxiliary vector + var corner=new Vector3(); + //iterate over all visible mesh nodes in the scene + for(i=0;i<scene.meshes.count;i++){ + var mesh=scene.meshes.getByIndex(i); + if(!mesh.visible) continue; + //local to parent transformation matrix + var trans=mesh.transform; + //build local to world transformation matrix by recursively + //multiplying the parent's transf. matrix on the right + var parent=mesh.parent; + while(parent.transform){ + trans=trans.multiply(parent.transform); + parent=parent.parent; + } + //get the bbox of the mesh (local coordinates) + var bbox=mesh.computeBoundingBox(); + //transform the local bounding box corner coordinates to + //world coordinates for bounding sphere determination + //BBox.min + corner.set(bbox.min); + corner.set(trans.transformPosition(corner)); + mb.check_in(new Array(corner.x, corner.y, corner.z)); + //BBox.max + corner.set(bbox.max); + corner.set(trans.transformPosition(corner)); + mb.check_in(new Array(corner.x, corner.y, corner.z)); + //remaining six BBox corners + corner.set(bbox.min.x, bbox.max.y, bbox.max.z); + corner.set(trans.transformPosition(corner)); + mb.check_in(new Array(corner.x, corner.y, corner.z)); + corner.set(bbox.min.x, bbox.min.y, bbox.max.z); + corner.set(trans.transformPosition(corner)); + mb.check_in(new Array(corner.x, corner.y, corner.z)); + corner.set(bbox.min.x, bbox.max.y, bbox.min.z); + corner.set(trans.transformPosition(corner)); + mb.check_in(new Array(corner.x, corner.y, corner.z)); + corner.set(bbox.max.x, bbox.min.y, bbox.min.z); + corner.set(trans.transformPosition(corner)); + mb.check_in(new Array(corner.x, corner.y, corner.z)); + corner.set(bbox.max.x, bbox.min.y, bbox.max.z); + corner.set(trans.transformPosition(corner)); + mb.check_in(new Array(corner.x, corner.y, corner.z)); + corner.set(bbox.max.x, bbox.max.y, bbox.min.z); + corner.set(trans.transformPosition(corner)); + mb.check_in(new Array(corner.x, corner.y, corner.z)); + } + //compute the smallest enclosing bounding sphere + mb.build(); + // + //current camera settings + // + var camera=scene.cameras.getByIndex(0); + var res=''; //initialize result string + //aperture angle of the virtual camera (perspective projection) *or* + //orthographic scale (orthographic projection) + if(camera.projectionType==camera.TYPE_PERSPECTIVE){ + var aac=camera.fov*180/Math.PI; + if(host.util.printf('%.4f', aac)!=30) + res+=host.util.printf('\n3Daac=%s,', aac); + }else{ + camera.viewPlaneSize=2.*mb.radius(); + res+=host.util.printf('\n3Dortho=%s,', 1./camera.viewPlaneSize); + } + //camera roll + var roll = camera.roll*180/Math.PI; + if(host.util.printf('%.4f', roll)!=0) + res+=host.util.printf('\n3Droll=%s,',roll); + //target to camera vector + var c2c=new Vector3(); + c2c.set(camera.position); + c2c.subtractInPlace(camera.targetPosition); + c2c.normalize(); + var x=(Math.abs(c2c.x) < 1e-12 ? 0 : c2c.x); + var y=(Math.abs(c2c.y) < 1e-12 ? 0 : c2c.y); + var z=(Math.abs(c2c.z) < 1e-12 ? 0 : c2c.z); + if(!(x==0 && y==-1 && z==0)) + res+=host.util.printf('\n3Dc2c=%s %s %s,', x, y, z); + // + //new camera settings + // + //bounding sphere centre --> new camera target + var coo=new Vector3(); + coo.set((mb.center())[0], (mb.center())[1], (mb.center())[2]); + coo.x = (Math.abs(coo.x) < 1e-12 ? 0 : coo.x); + coo.y = (Math.abs(coo.y) < 1e-12 ? 0 : coo.y); + coo.z = (Math.abs(coo.z) < 1e-12 ? 0 : coo.z); + if(coo.length) + res+=host.util.printf('\n3Dcoo=%s %s %s,', coo.x, coo.y, coo.z); + //radius of orbit + if(camera.projectionType==camera.TYPE_PERSPECTIVE){ + var roo=mb.radius()/ Math.sin(aac * Math.PI/ 360.); + }else{ + //orthographic projection + var roo=mb.radius(); + } + res+=host.util.printf('\n3Droo=%s,', roo); + //update camera settings in the viewer + var currol=camera.roll; + camera.targetPosition.set(coo); + camera.position.set(coo.add(c2c.scale(roo))); + camera.roll=currol; + //determine background colour + rgb=scene.background.getColor(); + if(!(rgb.r==1 && rgb.g==1 && rgb.b==1)) + res+=host.util.printf('\n3Dbg=%s %s %s,', rgb.r, rgb.g, rgb.b); + //determine lighting scheme + switch(scene.lightScheme){ + case scene.LIGHT_MODE_FILE: + curlights='Artwork';break; + case scene.LIGHT_MODE_NONE: + curlights='None';break; + case scene.LIGHT_MODE_WHITE: + curlights='White';break; + case scene.LIGHT_MODE_DAY: + curlights='Day';break; + case scene.LIGHT_MODE_NIGHT: + curlights='Night';break; + case scene.LIGHT_MODE_BRIGHT: + curlights='Hard';break; + case scene.LIGHT_MODE_RGB: + curlights='Primary';break; + case scene.LIGHT_MODE_BLUE: + curlights='Blue';break; + case scene.LIGHT_MODE_RED: + curlights='Red';break; + case scene.LIGHT_MODE_CUBE: + curlights='Cube';break; + case scene.LIGHT_MODE_CAD: + curlights='CAD';break; + case scene.LIGHT_MODE_HEADLAMP: + curlights='Headlamp';break; + } + if(curlights!='Artwork') + res+=host.util.printf('\n3Dlights=%s,', curlights); + //determine global render mode + switch(scene.renderMode){ + case scene.RENDER_MODE_BOUNDING_BOX: + currender='BoundingBox';break; + case scene.RENDER_MODE_TRANSPARENT_BOUNDING_BOX: + currender='TransparentBoundingBox';break; + case scene.RENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE: + currender='TransparentBoundingBoxOutline';break; + case scene.RENDER_MODE_VERTICES: + currender='Vertices';break; + case scene.RENDER_MODE_SHADED_VERTICES: + currender='ShadedVertices';break; + case scene.RENDER_MODE_WIREFRAME: + currender='Wireframe';break; + case scene.RENDER_MODE_SHADED_WIREFRAME: + currender='ShadedWireframe';break; + case scene.RENDER_MODE_SOLID: + currender='Solid';break; + case scene.RENDER_MODE_TRANSPARENT: + currender='Transparent';break; + case scene.RENDER_MODE_SOLID_WIREFRAME: + currender='SolidWireframe';break; + case scene.RENDER_MODE_TRANSPARENT_WIREFRAME: + currender='TransparentWireframe';break; + case scene.RENDER_MODE_ILLUSTRATION: + currender='Illustration';break; + case scene.RENDER_MODE_SOLID_OUTLINE: + currender='SolidOutline';break; + case scene.RENDER_MODE_SHADED_ILLUSTRATION: + currender='ShadedIllustration';break; + case scene.RENDER_MODE_HIDDEN_WIREFRAME: + currender='HiddenWireframe';break; + } + if(currender!='Solid') + res+=host.util.printf('\n3Drender=%s,', currender); + //write result string to the console + host.console.show(); +// host.console.clear(); + host.console.println('%%\n%% Copy and paste the following text to the\n'+ + '%% option list of \\includemedia!\n%%' + res + '\n'); +} + +function get3Dview () { + var camera=scene.cameras.getByIndex(0); + var coo=camera.targetPosition; + var c2c=camera.position.subtract(coo); + var roo=c2c.length; + c2c.normalize(); + var res='VIEW%=insert optional name here\n'; + var x = (Math.abs(coo.x) < 1e-12 ? 0 : coo.x); + var y = (Math.abs(coo.y) < 1e-12 ? 0 : coo.y); + var z = (Math.abs(coo.z) < 1e-12 ? 0 : coo.z); + if(!(x==0 && y==0 && z==0)) + res+=host.util.printf(' COO=%s %s %s\n', coo.x, coo.y, coo.z); + x = (Math.abs(c2c.x) < 1e-12 ? 0 : c2c.x); + y = (Math.abs(c2c.y) < 1e-12 ? 0 : c2c.y); + z = (Math.abs(c2c.z) < 1e-12 ? 0 : c2c.z); + if(!(x==0 && y==-1 && z==0)) + res+=host.util.printf(' C2C=%s %s %s\n', x, y, z); + if(roo > 0.11e-17) + res+=host.util.printf(' ROO=%s\n', roo); + var roll = camera.roll*180/Math.PI; + if(host.util.printf('%.4f', roll)!=0) + res+=host.util.printf(' ROLL=%s\n', roll); + if(camera.projectionType==camera.TYPE_PERSPECTIVE){ + var aac=camera.fov * 180/Math.PI; + if(host.util.printf('%.4f', aac)!=30) + res+=host.util.printf(' AAC=%s\n', aac); + }else{ + if(host.util.printf('%.4f', camera.viewPlaneSize)!=1) + res+=host.util.printf(' ORTHO=%s\n', 1./camera.viewPlaneSize); + } + rgb=scene.background.getColor(); + if(!(rgb.r==1 && rgb.g==1 && rgb.b==1)) + res+=host.util.printf(' BGCOLOR=%s %s %s\n', rgb.r, rgb.g, rgb.b); + switch(scene.lightScheme){ + case scene.LIGHT_MODE_FILE: + curlights='Artwork';break; + case scene.LIGHT_MODE_NONE: + curlights='None';break; + case scene.LIGHT_MODE_WHITE: + curlights='White';break; + case scene.LIGHT_MODE_DAY: + curlights='Day';break; + case scene.LIGHT_MODE_NIGHT: + curlights='Night';break; + case scene.LIGHT_MODE_BRIGHT: + curlights='Hard';break; + case scene.LIGHT_MODE_RGB: + curlights='Primary';break; + case scene.LIGHT_MODE_BLUE: + curlights='Blue';break; + case scene.LIGHT_MODE_RED: + curlights='Red';break; + case scene.LIGHT_MODE_CUBE: + curlights='Cube';break; + case scene.LIGHT_MODE_CAD: + curlights='CAD';break; + case scene.LIGHT_MODE_HEADLAMP: + curlights='Headlamp';break; + } + if(curlights!='Artwork') + res+=' LIGHTS='+curlights+'\n'; + switch(scene.renderMode){ + case scene.RENDER_MODE_BOUNDING_BOX: + defaultrender='BoundingBox';break; + case scene.RENDER_MODE_TRANSPARENT_BOUNDING_BOX: + defaultrender='TransparentBoundingBox';break; + case scene.RENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE: + defaultrender='TransparentBoundingBoxOutline';break; + case scene.RENDER_MODE_VERTICES: + defaultrender='Vertices';break; + case scene.RENDER_MODE_SHADED_VERTICES: + defaultrender='ShadedVertices';break; + case scene.RENDER_MODE_WIREFRAME: + defaultrender='Wireframe';break; + case scene.RENDER_MODE_SHADED_WIREFRAME: + defaultrender='ShadedWireframe';break; + case scene.RENDER_MODE_SOLID: + defaultrender='Solid';break; + case scene.RENDER_MODE_TRANSPARENT: + defaultrender='Transparent';break; + case scene.RENDER_MODE_SOLID_WIREFRAME: + defaultrender='SolidWireframe';break; + case scene.RENDER_MODE_TRANSPARENT_WIREFRAME: + defaultrender='TransparentWireframe';break; + case scene.RENDER_MODE_ILLUSTRATION: + defaultrender='Illustration';break; + case scene.RENDER_MODE_SOLID_OUTLINE: + defaultrender='SolidOutline';break; + case scene.RENDER_MODE_SHADED_ILLUSTRATION: + defaultrender='ShadedIllustration';break; + case scene.RENDER_MODE_HIDDEN_WIREFRAME: + defaultrender='HiddenWireframe';break; + } + if(defaultrender!='Solid') + res+=' RENDERMODE='+defaultrender+'\n'; + for(var i=0;i<scene.meshes.count;i++){ + var mesh=scene.meshes.getByIndex(i); + var meshUTFName = ''; + for (var j=0; j<mesh.name.length; j++) { + var theUnicode = mesh.name.charCodeAt(j).toString(16); + while (theUnicode.length<4) theUnicode = '0' + theUnicode; + meshUTFName += theUnicode; + } + var end=mesh.name.lastIndexOf('.'); + if(end>0) var meshUserName=mesh.name.substr(0,end); + else var meshUserName=mesh.name; + respart=' PART='+meshUserName+'\n'; + respart+=' UTF16NAME='+meshUTFName+'\n'; + defaultvals=true; + if(!mesh.visible){ + respart+=' VISIBLE=false\n'; + defaultvals=false; + } + if(mesh.opacity<1.0){ + respart+=' OPACITY='+mesh.opacity+'\n'; + defaultvals=false; + } + currender=defaultrender; + switch(mesh.renderMode){ + case scene.RENDER_MODE_BOUNDING_BOX: + currender='BoundingBox';break; + case scene.RENDER_MODE_TRANSPARENT_BOUNDING_BOX: + currender='TransparentBoundingBox';break; + case scene.RENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE: + currender='TransparentBoundingBoxOutline';break; + case scene.RENDER_MODE_VERTICES: + currender='Vertices';break; + case scene.RENDER_MODE_SHADED_VERTICES: + currender='ShadedVertices';break; + case scene.RENDER_MODE_WIREFRAME: + currender='Wireframe';break; + case scene.RENDER_MODE_SHADED_WIREFRAME: + currender='ShadedWireframe';break; + case scene.RENDER_MODE_SOLID: + currender='Solid';break; + case scene.RENDER_MODE_TRANSPARENT: + currender='Transparent';break; + case scene.RENDER_MODE_SOLID_WIREFRAME: + currender='SolidWireframe';break; + case scene.RENDER_MODE_TRANSPARENT_WIREFRAME: + currender='TransparentWireframe';break; + case scene.RENDER_MODE_ILLUSTRATION: + currender='Illustration';break; + case scene.RENDER_MODE_SOLID_OUTLINE: + currender='SolidOutline';break; + case scene.RENDER_MODE_SHADED_ILLUSTRATION: + currender='ShadedIllustration';break; + case scene.RENDER_MODE_HIDDEN_WIREFRAME: + currender='HiddenWireframe';break; + //case scene.RENDER_MODE_DEFAULT: + // currender='Default';break; + } + if(currender!=defaultrender){ + respart+=' RENDERMODE='+currender+'\n'; + defaultvals=false; + } + if(!mesh.transform.isEqual(origtrans[mesh.name])){ + var lvec=mesh.transform.transformDirection(new Vector3(1,0,0)); + var uvec=mesh.transform.transformDirection(new Vector3(0,1,0)); + var vvec=mesh.transform.transformDirection(new Vector3(0,0,1)); + respart+=' TRANSFORM=' + +(Math.abs(lvec.x) < 1e-12 ? 0 : lvec.x)+' ' + +(Math.abs(lvec.y) < 1e-12 ? 0 : lvec.y)+' ' + +(Math.abs(lvec.z) < 1e-12 ? 0 : lvec.z)+' ' + +(Math.abs(uvec.x) < 1e-12 ? 0 : uvec.x)+' ' + +(Math.abs(uvec.y) < 1e-12 ? 0 : uvec.y)+' ' + +(Math.abs(uvec.z) < 1e-12 ? 0 : uvec.z)+' ' + +(Math.abs(vvec.x) < 1e-12 ? 0 : vvec.x)+' ' + +(Math.abs(vvec.y) < 1e-12 ? 0 : vvec.y)+' ' + +(Math.abs(vvec.z) < 1e-12 ? 0 : vvec.z)+' ' + +(Math.abs(mesh.transform.translation.x) < 1e-12 ? 0 : mesh.transform.translation.x)+' ' + +(Math.abs(mesh.transform.translation.y) < 1e-12 ? 0 : mesh.transform.translation.y)+' ' + +(Math.abs(mesh.transform.translation.z) < 1e-12 ? 0 : mesh.transform.translation.z)+'\n'; + defaultvals=false; + } + respart+=' END\n'; + if(!defaultvals) res+=respart; + } + + //detect existing Clipping Plane (3DCrossSection) + var clip=null; + try { + clip=scene.nodes.getByName("Clipping Plane"); + }catch(e){ + var ndcnt=scene.nodes.count; + clip=scene.createClippingPlane(); + if(ndcnt!=scene.nodes.count){ + clip.remove(); + clip=null; + } + } + if(clip){ + var centre=clip.transform.translation; + var normal=clip.transform.transformDirection(new Vector3(0,0,1)); + res+=' CROSSSECT\n'; + var x = (Math.abs(centre.x) < 1e-12 ? 0 : centre.x); + var y = (Math.abs(centre.y) < 1e-12 ? 0 : centre.y); + var z = (Math.abs(centre.z) < 1e-12 ? 0 : centre.z); + if(!(x==0 && y==0 && z==0)) + res+=host.util.printf(' CENTER=%s %s %s\n', x, y, z); + var x = (Math.abs(normal.x) < 1e-12 ? 0 : normal.x); + var y = (Math.abs(normal.y) < 1e-12 ? 0 : normal.y); + var z = (Math.abs(normal.z) < 1e-12 ? 0 : normal.z); + if(!(x==1 && y==0 && z==0)) + res+=host.util.printf(' NORMAL=%s %s %s\n', x, y, z); + res+=' END\n'; + } + res+='END\n'; + host.console.show(); +// host.console.clear(); + host.console.println('%%\n%% Add the following VIEW section to a file of\n'+ + '%% predefined views (See option "3Dviews"!).\n%%\n' + + '%% The view may be given a name after VIEW=...\n' + + '%% (Remove \'%\' in front of \'=\'.)\n%%'); + host.console.println(res + '\n'); +} + +//add items to 3D context menu +runtime.addCustomMenuItem("dfltview", "Generate Default View", "default", 0); +runtime.addCustomMenuItem("currview", "Get Current View", "default", 0); +runtime.addCustomMenuItem("csection", "Cross Section", "checked", 0); + +//menu event handlers +menuEventHandler = new MenuEventHandler(); +menuEventHandler.onEvent = function(e) { + switch(e.menuItemName){ + case "dfltview": calc3Dopts(); break; + case "currview": get3Dview(); break; + case "csection": + addremoveClipPlane(e.menuItemChecked); + break; + } +}; +runtime.addEventHandler(menuEventHandler); + +//global variable taking reference to currently selected mesh node; +var mshSelected=null; +selectionEventHandler=new SelectionEventHandler(); +selectionEventHandler.onEvent=function(e){ + if(e.selected && e.node.constructor.name=="Mesh"){ + mshSelected=e.node; + }else{ + mshSelected=null; + } +} +runtime.addEventHandler(selectionEventHandler); + +cameraEventHandler=new CameraEventHandler(); +cameraEventHandler.onEvent=function(e){ + //store current transformation matrices of all mesh nodes in the scene + var curtrans=getCurTrans(); + //detect existing clipping plane (cross section) + var ndcnt=scene.nodes.count; + var clip=scene.createClippingPlane(); + if(ndcnt!=scene.nodes.count){ + clip.remove(); + runtime.removeCustomMenuItem("csection"); + runtime.addCustomMenuItem("csection", "Cross Section", "checked", 0); + } else { + runtime.removeCustomMenuItem("csection"); + runtime.addCustomMenuItem("csection", "Cross Section", "checked", 1); + } + //restore previous position of mesh nodes + restoreTrans(curtrans); +} +runtime.addEventHandler(cameraEventHandler); + +//key event handler for moving, spinning and tilting objects +keyEventHandler=new KeyEventHandler(); +keyEventHandler.onEvent=function(e){ + var target=null; + var backtrans=new Matrix4x4(); + if(mshSelected){ + target=mshSelected; + var trans=target.transform; + var parent=target.parent; + while(parent.transform){ + //build local to world transformation matrix + trans.multiplyInPlace(parent.transform); + //also build world to local back-transformation matrix + backtrans.multiplyInPlace(parent.transform.inverse.transpose); + parent=parent.parent; + } + backtrans.transposeInPlace(); + }else{ + try { + target=scene.nodes.getByName("Clipping Plane"); + }catch(e){ + var ndcnt=scene.nodes.count; + target=scene.createClippingPlane(); + if(ndcnt!=scene.nodes.count){ + target.remove(); + target=null; + } + } + } + if(!target) return; + switch(e.characterCode){ + case 30://tilt up + tiltTarget(target, -Math.PI/900); + break; + case 31://tilt down + tiltTarget(target, Math.PI/900); + break; + case 28://spin right + spinTarget(target, -Math.PI/900); + break; + case 29://spin left + spinTarget(target, Math.PI/900); + break; + case 120: //x + translateTarget(target, new Vector3(1,0,0), e); + break; + case 121: //y + translateTarget(target, new Vector3(0,1,0), e); + break; + case 122: //z + translateTarget(target, new Vector3(0,0,1), e); + break; + case 88: //shift + x + translateTarget(target, new Vector3(-1,0,0), e); + break; + case 89: //shift + y + translateTarget(target, new Vector3(0,-1,0), e); + break; + case 90: //shift + z + translateTarget(target, new Vector3(0,0,-1), e); + break; + case 115: //s + scaleTarget(target, 1, e); + break; + case 83: //shift + s + scaleTarget(target, -1, e); + break; + } + if(mshSelected) + target.transform.multiplyInPlace(backtrans); +} +runtime.addEventHandler(keyEventHandler); + +function tiltTarget(t,a){ + var centre=new Vector3(); + if(mshSelected) { + centre.set(t.transform.transformPosition(t.computeBoundingBox().center)); + }else{ + centre.set(t.transform.translation); + } + var rotVec=t.transform.transformDirection(new Vector3(0,1,0)); + rotVec.normalize(); + t.transform.translateInPlace(centre.scale(-1)); + t.transform.rotateAboutVectorInPlace(a, rotVec); + t.transform.translateInPlace(centre); +} + +function spinTarget(t,a){ + var centre=new Vector3(); + var rotVec=new Vector3(0,0,1); + if(mshSelected) { + centre.set(t.transform.transformPosition(t.computeBoundingBox().center)); + rotVec.set(t.transform.transformDirection(rotVec)); + rotVec.normalize(); + }else{ + centre.set(t.transform.translation); + } + t.transform.translateInPlace(centre.scale(-1)); + t.transform.rotateAboutVectorInPlace(a, rotVec); + t.transform.translateInPlace(centre); +} + +//translates object by amount calculated based on Canvas size +function translateTarget(t, d, e){ + var cam=scene.cameras.getByIndex(0); + if(cam.projectionType==cam.TYPE_PERSPECTIVE){ + var scale=Math.tan(cam.fov/2) + *cam.targetPosition.subtract(cam.position).length + /Math.min(e.canvasPixelWidth,e.canvasPixelHeight); + }else{ + var scale=cam.viewPlaneSize/2 + /Math.min(e.canvasPixelWidth,e.canvasPixelHeight); + } + t.transform.translateInPlace(d.scale(scale)); +} + +//scales object by amount calculated based on Canvas size +function scaleTarget(t, d, e){ + if(mshSelected) { + var bbox=t.computeBoundingBox(); + var diag=new Vector3(bbox.max.x, bbox.max.y, bbox.max.z); + diag.subtractInPlace(bbox.min); + var dlen=diag.length; + + var cam=scene.cameras.getByIndex(0); + if(cam.projectionType==cam.TYPE_PERSPECTIVE){ + var scale=Math.tan(cam.fov/2) + *cam.targetPosition.subtract(cam.position).length + /dlen + /Math.min(e.canvasPixelWidth,e.canvasPixelHeight); + }else{ + var scale=cam.viewPlaneSize/2 + /dlen + /Math.min(e.canvasPixelWidth,e.canvasPixelHeight); + } + var centre=new Vector3(); + centre.set(t.transform.transformPosition(t.computeBoundingBox().center)); + t.transform.translateInPlace(centre.scale(-1)); + t.transform.scaleInPlace(1+d*scale); + t.transform.translateInPlace(centre); + } +} + +function addremoveClipPlane(chk) { + var clip=scene.createClippingPlane(); + if(chk){ + //add Clipping Plane and place its center either into the camera target + //position or into the centre of the currently selected mesh node + var centre=new Vector3(); + if(mshSelected){ + //local to parent transformation matrix + var trans=mshSelected.transform; + //build local to world transformation matrix by recursively + //multiplying the parent's transf. matrix on the right + var parent=mshSelected.parent; + while(parent.transform){ + trans=trans.multiply(parent.transform); + parent=parent.parent; + } + //get the centre of the mesh (local coordinates) + centre.set(mshSelected.computeBoundingBox().center); + //transform the local coordinates to world coords + centre.set(trans.transformPosition(centre)); + mshSelected=null; + }else{ + centre.set(scene.cameras.getByIndex(0).targetPosition); + } + clip.transform.setView( + new Vector3(0,0,0), new Vector3(1,0,0), new Vector3(0,1,0)); + clip.transform.translateInPlace(centre); + }else{ + clip.remove(); + } +} + +//function to store current transformation matrix of all mesh nodes in the scene +function getCurTrans() { + var nc=scene.meshes.count; + var tA=new Array(nc); + for(var i=0; i<nc; i++){ + var cm=scene.meshes.getByIndex(i); + tA[cm.name]=new Matrix4x4(cm.transform); + } + return tA; +} + +//function to restore transformation matrices given as arg +function restoreTrans(tA) { + for(var i=0; i<tA.length; i++){ + var msh=scene.meshes.getByIndex(i); + msh.transform.set(tA[msh.name]); + } +} + +//store original transformation matrix of all mesh nodes in the scene +var origtrans=getCurTrans(); + +//set initial state of "Cross Section" menu entry +cameraEventHandler.onEvent(1); + +//host.console.clear(); diff --git a/Master/texmf-dist/tex/latex/media9/javascript/3Dspintool.js b/Master/texmf-dist/tex/latex/media9/javascript/3Dspintool.js new file mode 100644 index 00000000000..ed348d37bec --- /dev/null +++ b/Master/texmf-dist/tex/latex/media9/javascript/3Dspintool.js @@ -0,0 +1,31 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// (C) 2012, Alexander Grahn +// +// 3Dspintool.js +// +// version 20120301 +// +//////////////////////////////////////////////////////////////////////////////// +// +// 3D JavaScript to be used with media9.sty (option `add3Djscript') +// +// enables the Spin tool (also accessible via 3D toolbar or context menu) +// upon activation of the 3D scene; the scene then rotates around the upright +// axis while dragging with the mouse +// +// This work may be distributed and/or modified under the +// conditions of the LaTeX Project Public License, either version 1.3 +// of this license or (at your option) any later version. +// The latest version of this license is in +// http://www.latex-project.org/lppl.txt +// and version 1.3 or later is part of all distributions of LaTeX +// version 2005/12/01 or later. +// +// This work has the LPPL maintenance status `maintained'. +// +// The Current Maintainer of this work is A. Grahn. +// +//////////////////////////////////////////////////////////////////////////////// + +runtime.setCurrentTool(runtime.TOOL_NAME_SPIN); diff --git a/Master/texmf-dist/tex/latex/media9/javascript/animation.js b/Master/texmf-dist/tex/latex/media9/javascript/animation.js new file mode 100644 index 00000000000..c09ac17d58d --- /dev/null +++ b/Master/texmf-dist/tex/latex/media9/javascript/animation.js @@ -0,0 +1,118 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// (C) 2012, Alexander Grahn +// +// animation.js +// +// version 20120301 +// +//////////////////////////////////////////////////////////////////////////////// +// +// JavaScript for use with `add3DJScript' option of \includemedia +// +// * Activates keyframe animation embedded in the u3d file. +// * Arrow keys `Down', `Up' can be used for speeding up and +// slowing down a running animation, key `Home' for reverting +// to the default speed. +// +// * Adjustable parameters: +var rate = 1; // 1 --> use original speed as default +var palindrome = true; // true --> play forth and back +// +// This work may be distributed and/or modified under the +// conditions of the LaTeX Project Public License, either version 1.3 +// of this license or (at your option) any later version. +// The latest version of this license is in +// http://www.latex-project.org/lppl.txt +// and version 1.3 or later is part of all distributions of LaTeX +// version 2005/12/01 or later. +// +// This work has the LPPL maintenance status `maintained'. +// +// The Current Maintainer of this work is A. Grahn. +// +//////////////////////////////////////////////////////////////////////////////// + +//get the first animation in the scene +var myAnim = scene.animations.getByIndex(0); +myAnim.wallTime = 0; +myAnim.speed = 1; +myAnim.myLength = myAnim.endTime - myAnim.startTime; +scene.activateAnimation(myAnim); + +//method to set animation speed +myAnim.setSpeed = function (speed) { + speed = Math.abs(speed); + this.wallTime /= speed/this.speed; //correct the walltime + this.speed = speed; +}; + +//method to change animation speed by a factor +myAnim.changeSpeed = function (mult) { + this.wallTime /= mult; //correct the walltime + this.speed *= mult; +}; + +//set default speed +myAnim.setSpeed(rate); + +//menu items +runtime.addCustomMenuItem("faster", "Faster (Key Up)", "default", 0); +runtime.addCustomMenuItem("slower", "Slower (Key Down)", "default", 0); +runtime.addCustomMenuItem("default", "Default Speed (Key Home)", "default", 0); + +//menu handler to control speed +menuEventHandler = new MenuEventHandler(); +menuEventHandler.onEvent = function(e) { + if (e.menuItemName == "faster") { + myAnim.changeSpeed(1.25); + } + else if (e.menuItemName == "slower") { + myAnim.changeSpeed(1/1.25); + } + else if (e.menuItemName == "default") { + myAnim.setSpeed(rate); + } +}; +runtime.addEventHandler(menuEventHandler); + +//key handler to control speed +keyEventHandler = new KeyEventHandler(); +keyEventHandler.onKeyDown = true; +keyEventHandler.onEvent = function(e) { + switch(e.characterCode) { + case 30: //key up + myAnim.changeSpeed(1.05); + break; + + case 31: //key down + myAnim.changeSpeed(1/1.05); + break; + + case 4: //key home + myAnim.setSpeed(rate); + break; + + case 1: //key end + myAnim.setSpeed(rate); + break; + } +}; +runtime.addEventHandler(keyEventHandler); + +//run the animation using a TimeEventHandler +myTimer = new TimeEventHandler(); +myTimer.onTimeChange = true; +myTimer.onEvent = function(e) { + myAnim.wallTime += e.deltaTime; + if (palindrome == true) { + myAnim.currentTime = + myAnim.startTime + + myAnim.myLength/2 + * (1 - Math.cos(Math.PI * myAnim.speed/myAnim.myLength * myAnim.wallTime)); + } else { + myAnim.currentTime = myAnim.startTime + + (myAnim.speed * myAnim.wallTime % myAnim.myLength); + } +}; +runtime.addEventHandler(myTimer); diff --git a/Master/texmf-dist/tex/latex/media9/javascript/asylabels.js b/Master/texmf-dist/tex/latex/media9/javascript/asylabels.js new file mode 100644 index 00000000000..dfe1899d5f5 --- /dev/null +++ b/Master/texmf-dist/tex/latex/media9/javascript/asylabels.js @@ -0,0 +1,106 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// (C) 2012, Alexander Grahn +// +// asylabels.js +// +// version 20120301 +// +//////////////////////////////////////////////////////////////////////////////// +// +// 3D JavaScript to be used with media9.sty (option `add3Djscript') for +// Asymptote generated PRC files +// +// adds billboard behaviour to text labels in Asymptote PRC files for improved +// visibility, they always face the camera while dragging the 3d object with the +// mouse. +// +// +// This work may be distributed and/or modified under the +// conditions of the LaTeX Project Public License, either version 1.3 +// of this license or (at your option) any later version. +// The latest version of this license is in +// http://www.latex-project.org/lppl.txt +// and version 1.3 or later is part of all distributions of LaTeX +// version 2005/12/01 or later. +// +// This work has the LPPL maintenance status `maintained'. +// +// The Current Maintainer of this work is A. Grahn. +// +//////////////////////////////////////////////////////////////////////////////// + +//recursive function which computes the lower left BBox corner of a text +//label; it marches through all sibling mesh nodes the label is composed of; +//the returned Vector3 object will become the pivot point of the label +function nextCenter(msh){ + //compute local-to-world transf. matrix of current mesh node + var trans=new Matrix4x4(msh.transform); + var parent=msh.parent; + while(parent.transform){ + trans.multiplyInPlace(parent.transform); + parent=parent.parent; + } + + //min BBox corner of current mesh node + var min=new Vector3(); + min.set(msh.computeBoundingBox().min); + min.set(trans.transformPosition(min)); + + //get min BBox corner closest to origin (0,0,0) + if(msh.nextSibling){ + var nextmin=nextCenter(msh.nextSibling); + return(min.length < nextmin.length ? min : nextmin); + }else{ + return(min); + } +} + +//find all text labels in the scene and determine pivoting points +var zero=new Vector3(0,0,0); +var nodes=scene.nodes; +var center=new Array(); +var index=new Array(); +for(var i=0; i<nodes.count; i++){ + var node=nodes.getByIndex(i); + var name=node.name; + var end=name.lastIndexOf(".")-1; + if(end > 0){ + if(name.charAt(end) == "\001"){ + var start=name.lastIndexOf("-")+1; + if(end-start > 0) { + index.push(i); + center.push(nextCenter(node.firstChild)); + node.name=name.substr(0,start-1); + } + } + } +} + +var camera=scene.cameras.getByIndex(0); + +//event handler to maintain upright position of text labels +billboardHandler=new RenderEventHandler(); +billboardHandler.onEvent=function(event) +{ + var position=camera.position; + var direction=position.subtract(camera.targetPosition); + var up=camera.up.subtract(position); + + for(var i=0; i<index.length; i++){ + var node=nodes.getByIndex(index[i]); + var R=Matrix4x4(); + R.setView(zero,direction,up); + var c=center[i]; + var T=node.transform; + T.setIdentity(); + T.translateInPlace(c.scale(-1)); + T.multiplyInPlace(R); + T.translateInPlace(c); + } + + runtime.refresh(); +} +runtime.addEventHandler(billboardHandler); + +runtime.refresh(); diff --git a/Master/texmf-dist/tex/latex/media9/media9.sty b/Master/texmf-dist/tex/latex/media9/media9.sty new file mode 100644 index 00000000000..c47d1df7f60 --- /dev/null +++ b/Master/texmf-dist/tex/latex/media9/media9.sty @@ -0,0 +1,1996 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% media9.sty +% +% multimedia inclusion package +% +% Copyright 2012 Alexander Grahn +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% This package implements Adobe-Reader 9 and X compatible RichMedia +% annotation for multimedia (Flash & 3D) inclusion according to: +% +% Adobe Supplement to ISO 32000, BaseVersion 1.7, ExtensionLevel 3 +% +% Supported workflows: +% +% pdflatex, lualatex +% (lua)latex-->dvips-->ps2pdf/Distiller +% latex-->dvipdfmx +% xelatex +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is A. Grahn. + +\RequirePackage{expl3} +\RequirePackage{xparse} +\RequirePackage{l3keys2e} +\RequirePackage{ifpdf} + +\def\g@mix@date@tl{2012/03/16} +\def\g@mix@version@tl{0.2} +\ProvidesExplPackage{media9}{\g@mix@date@tl}{\g@mix@version@tl} +{acrobat-9 compatible media} + +\tl_gset:Nx\g_mix_date_tl{\g@mix@date@tl} +\tl_gset:Nx\g_mix_version_tl{\g@mix@version@tl} + +\cs_if_exist:NTF\msg_set:nnnn{ + \msg_set:nnnn{media9}{support~outdated}{ + Support~package~#1~too~old. + }{ + Please~install~an~up~to~date~version~of~#1.\\ + Loading~media9~will~abort! + } +}{ + \PackageError{media9}{Support~package~expl3~too~old.}{ + Please~install~an~up~to~date~version~of~expl3.\\ + Loading~media9~will~abort! + } + \tex_endinput:D +} +\@ifpackagelater{expl3}{2011/09/08}{}{ + \msg_error:nnx{media9}{support~outdated}{l3kernel} + \tex_endinput:D +} +\@ifpackagelater{xparse}{2011/09/08}{}{ + \msg_error:nnx{media9}{support~outdated}{l3packages} + \tex_endinput:D +} +\@ifpackagelater{l3keys2e}{2011/09/08}{}{ + \msg_error:nnx{media9}{support~outdated}{l3packages} + \tex_endinput:D +} + +%testing for PDF output +\bool_new:N\g_mix_pdfoutput_bool +\bool_gset_false:N\g_mix_pdfoutput_bool +%\cs_if_exist:NT\pdfoutput{ +% \int_compare:nT{\pdfoutput>0}{\bool_gset_true:N\g_mix_pdfoutput_bool} +%} +\ifpdf \bool_gset_true:N\g_mix_pdfoutput_bool \fi + +%pdfTeX version check +\pdftex_if_engine:T{ + \int_compare:nT{\pdftexversion<130}{ + \msg_interrupt:xxx{media9~error}{pdfTeX,~version~>=~1.30~required.}{} + } +} + +%package options + +%unknown package option error message +\msg_set:nnnn{media9}{unknown~package~option}{Unknown~package~option~`#1'.}{ + Package option~'#1'~is~not~known~by~media9:\\ + perhaps~it~is~spelled~incorrectly. +} + +\bool_new:N\g_mix_dvipdfmx_bool +\bool_new:N\g_mix_pkgdraft_bool +\tl_gset:Nn\g_mix_pkgact_tl{/XA} +\tl_gset:Nn\g_mix_pkgdeact_tl{/XD} +\tl_gset:Nn\g_mix_pkgtransp_tl{false} +\tl_gset:Nn\g_mix_pkgcontextclick_tl{false} +\tl_gset:Nn\g_mix_pkgplaycnt_tl{-1} +\tl_gset:Nn\g_mix_pkgplayspd_tl{1} +\tl_gset:Nn\g_mix_pkgplaytpe_tl{None} +\tl_gset:Nn\g_mix_pkgtools_tl{false} +\tl_gset:Nn\g_mix_pkgnav_tl{false} +\tl_gset:Nn\g_mix_pkgopt_bg_tl{} +\tl_gset:Nn\g_mix_pkgopt_ls_tl{} +\tl_gset:Nn\g_mix_pkgopt_rm_tl{} +\bool_new:N\g_mix_pkgiiidcalc_bool +\keys_define:nn{media9}{ + dvipdfmx .bool_gset:N = \g_mix_dvipdfmx_bool, + xetex .bool_gset:N = \g_mix_dvipdfmx_bool, + + draft .choice:, + draft / true .code:n = {\bool_gset_true:N\g_mix_pkgdraft_bool}, + draft / false .code:n = {\bool_gset_false:N\g_mix_pkgdraft_bool}, + draft .default:n = {true}, + + final .choice:, + final / true .code:n = {\bool_gset_false:N\g_mix_pkgdraft_bool}, + final / false .code:n = {\bool_gset_true:N\g_mix_pkgdraft_bool}, + final .default:n = {true}, + + activate .choice:, + activate / pagevisible .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/PV}}, + activate / pageopen .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/PO}}, + activate / onclick .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/XA}}, + + deactivate .choice:, + deactivate / pageinvisible .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/PI}}, + deactivate / pageclose .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/PC}}, + deactivate / onclick .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/XD}}, + + transparent .choice_code:n = { + \tl_gset:Nx\g_mix_pkgtransp_tl{\l_keys_choice_tl}}, + transparent .generate_choices:n = {true,false}, + transparent .default:n = {true}, + + passcontext .choice_code:n = {\tl_gset:Nx\g_mix_pkgcontextclick_tl{ + \l_keys_choice_tl}}, + passcontext .generate_choices:n = {true,false}, + passcontext .default:n = {true}, + + %3D specific options + 3Dplaytype .choice:, + 3Dplaytype / none .code:n = {\tl_gset:Nn\g_mix_pkgplaytpe_tl{None}}, + 3Dplaytype / linear .code:n = {\tl_gset:Nn\g_mix_pkgplaytpe_tl{Linear}}, + 3Dplaytype / oscillating .code:n = { + \tl_gset:Nn\g_mix_pkgplaytpe_tl{Oscillating}}, + + 3Dplaycount .code:n = {\tl_gset:Nn\g_mix_pkgplaycnt_tl{ + \exp_after:wN\int_value:w \dim_eval:w#1sp\dim_eval_end:}}, + 3Dplaycount .value_required:, + + 3Dplayspeed .tl_gset_x:N = \g_mix_pkgplayspd_tl, + 3Dplayspeed .value_required:, + + 3Dtoolbar .choice_code:n = {\tl_gset:Nx\g_mix_pkgtools_tl{\l_keys_choice_tl}}, + 3Dtoolbar .generate_choices:n = {true,false}, + 3Dtoolbar .default:n = {true}, + + 3Dnavpane .choice_code:n = {\tl_gset:Nx\g_mix_pkgnav_tl{\l_keys_choice_tl}}, + 3Dnavpane .generate_choices:n = {true,false}, + 3Dnavpane .default:n = {true}, + + 3Dmenu .bool_gset:N = \g_mix_pkgiiidcalc_bool, + + 3Dbg .code:n = { + \tl_gset:Nx\g_mix_pkgopt_bg_tl{ + /BG<</Subtype/SC/CS/DeviceRGB/C[#1]/EA~true>>} + }, + 3Dbg .value_required:, + + 3Dlights .code:n = { + \tl_gset:Nx\g_mix_pkgopt_ls_tl{/LS<</Subtype/#1>>} + }, + 3Dlights .value_required:, + + 3Drender .code:n = { + \tl_gset:Nx\g_mix_pkgopt_rm_tl{/RM<</Subtype/#1>>} + }, + 3Drender .value_required:, + + unknown .code:n = { + \msg_error:nnx{media9}{unknown~package~option}{\exp_not:V\l_keys_key_tl} + }, +} +\ProcessKeysOptions{media9} +\xetex_if_engine:T{\bool_gset_true:N\g_mix_dvipdfmx_bool} + +\AtBeginDocument{ + \@ifpackageloaded{babel}{}{\msg_error:nnx{media9}{missing~package}{babel}} +} + +\box_new:N\l_mix_poster_box +\dim_new:N\g_mix_wd_dim +\dim_new:N\g_mix_ht_dim +\dim_new:N\g_mix_dp_dim + +\int_new:N\g_mix_rmcnt_int +\int_new:N\l_mix_viewcnt_int %counter for 3D views per annot + +\bool_new:N\g_mix_url_bool +\bool_new:N\l_mix_url_bool +\bool_new:N\g_mix_iiidcalc_bool + +%missing package error message +%example usage: +% \msg_error:nnxx{media9}{missing~package}{graphicx}{[dvipdfmx]} +% \msg_error:nnx{media9}{missing~package}{graphicx} +\msg_set:nnn{media9}{missing~package}{ + Package~`#1'~has~not~been~loaded~yet.\\ + Put~the~line\\ + ~~\string\usepackage#2{#1}\\ + to~the~preamble~of~your~document. +} + +%file not found error message +%example usage: +% \msg_error:nnxx{media9}{file~not~found}{myfile.swf} +\msg_set:nnnn{media9}{file~not~found}{ + Loine~\msg_line_number: :~ + File~`#1'~not~found.}{Make~sure~file~`#1'~exists~and~is~readable!} + +\pdftex_if_engine:TF{ + %\pdfmdfivesum is used for hashing object references of embedded files + \cs_new:Nn\mix_filemdfivesum:n{\pdfmdfivesum~file~{#1}} + \cs_new:Nn\mix_filesize:n{\pdffilesize{#1}} + \cs_new:Nn\mix_filedump:nnn{\pdffiledump~offset~#1~length~#2~{#3}} + \cs_new:Nn\mix_unescapehex:n{(\pdfunescapehex{#1})} +}{ + \luatex_if_engine:TF{ + \RequirePackage{pdftexcmds} + \cs_new:Nn\mix_filemdfivesum:n{\pdf@filemdfivesum{#1}} + \cs_new:Nn\mix_filesize:n{\pdf@filesize{#1}} + \cs_new:Nn\mix_filedump:nnn{\pdf@filedump{#1}{#2}{#3}} + \cs_new:Nn\mix_unescapehex:n{<#1>} + }{ + \cs_new:Nn\mix_filemdfivesum:n{#1} + } +} + +%reset various variables for every new media inclusion +\cs_new:Nn\mix_reset:{ + \tl_gset:Nx\g_mix_label_tl{rm.\int_use:N\g_mix_rmcnt_int} + \tl_gset:Nn\g_mix_flashvars_tl{} + \tl_gset:Nn\g_mix_assets_tl{} + \tl_gset:Nn\g_mix_configurations_tl{} + \tl_gset_eq:NN\g_mix_act_tl\g_mix_pkgact_tl + \tl_gset_eq:NN\g_mix_deact_tl\g_mix_pkgdeact_tl + \bool_gset_false:N\g_mix_url_bool + \box_clear:N\l_mix_poster_box + \tl_set:Nn\l_mix_scripts_tl{} + \bool_gset_eq:NN\g_mix_usrdraft_bool\g_mix_pkgdraft_bool + \seq_gclear:N\g_mix_res_seq + \seq_gclear:N\g_mix_script_seq + \int_gzero:N\g_mix_resizeflag_int + \tl_gset:Nn\g_mix_scalearg_tl{1.0} + \tl_gset:Nn\g_mix_wdarg_tl{\width} + \tl_gset:Nn\g_mix_htarg_tl{\height} + \tl_gset:Nn\g_mix_dparg_tl{\depth} + \tl_gset_eq:NN\g_mix_transp_tl\g_mix_pkgtransp_tl + \tl_gset_eq:NN\g_mix_contextclick_tl\g_mix_pkgcontextclick_tl + + %3D specific settings + \bool_gset_false:N\g_mix_opt_iiidview_bool + \bool_gset_eq:NN\g_mix_iiidcalc_bool\g_mix_pkgiiidcalc_bool + + \tl_gset_eq:NN\g_mix_playcnt_tl\g_mix_pkgplaycnt_tl + \tl_gset_eq:NN\g_mix_playspd_tl\g_mix_pkgplayspd_tl + \tl_gset_eq:NN\g_mix_playtpe_tl\g_mix_pkgplaytpe_tl + \tl_gset_eq:NN\g_mix_tools_tl\g_mix_pkgtools_tl + \tl_gset_eq:NN\g_mix_nav_tl\g_mix_pkgnav_tl + + \tl_gset_eq:NN\g_mix_opt_bg_tl\g_mix_pkgopt_bg_tl + \tl_gset_eq:NN\g_mix_opt_ls_tl\g_mix_pkgopt_ls_tl + \tl_gset_eq:NN\g_mix_opt_rm_tl\g_mix_pkgopt_rm_tl + \tl_gset:Nn\g_mix_opt_coo_tl{0~0~0} + \tl_gset:Nn\g_mix_opt_ctoc_tl{0~-1~0} + \tl_gset:Nn\g_mix_opt_ciiw_tl{} + \fp_gset:Nn\g_mix_opt_roo_fp{1e-8} + \fp_gset:Nn\g_mix_opt_aac_fp{30} + \fp_gset:Nn\g_mix_opt_oscale_fp{1} + \fp_gset:Nn\g_mix_opt_roll_fp{0} + + \bool_set_false:N\l_mix_roo_bool + \bool_gset_false:N\g_mix_opt_ciiw_bool + \bool_gset_false:N\g_mix_opt_iiidortho_bool + + \tl_set:Nn\l_mix_iiidviewarray_tl{} + \tl_gset:Nn\g_mix_vfile_tl{} +} + +%3D settings to be reset before creating an additional view +\cs_new:Nn\mix_iiidreset:{ + \tl_set:Nn\l_mix_bg_tl{} + \tl_set:Nn\l_mix_ls_tl{} + \tl_set:Nn\l_mix_rm_tl{} + \tl_set:Nn\l_mix_coo_tl{0~0~0} + \tl_set:Nn\l_mix_ctoc_tl{0~-1~0} + \tl_set:Nn\l_mix_ciiw_tl{} + + \fp_set:Nn\l_mix_roo_fp{1e-8} + \fp_set:Nn\l_mix_aac_fp{30} + \fp_set:Nn\l_mix_oscale_fp{1} + \fp_set:Nn\l_mix_roll_fp{0} + + \bool_set_false:N\l_mix_roo_bool + \bool_set_false:N\l_mix_ciiw_bool + \bool_set_false:N\l_mix_iiidortho_bool + + \tl_set:Nn\l_mix_naarray_tl{} %array of node dicts + \tl_set:Nn\l_mix_saarray_tl{} %array of crosssect dicts +} + +%wrong image resource for 3D +\msg_set:nnn{media9}{wrong~image~resource}{ + Image~resource~file\\~~'#1'\\has~wrong~type.\\\\ + In~3D~context,~driver~#2~only~accepts~files~of~type\\#3\\ + as~image~resources. +} + +%commands for creating PDF objects, annots etc. +\bool_if:NTF\g_mix_pdfoutput_bool{ + %helper func to remove `0 R' part from pdf obj reference + \cs_new:Npn\mix_reftonum:w #1~0~R {#1} + \cs_new:Nn\mix_pdfobj:nnn{ + % #1:objref; if empty, a new object number will be reserved + % #2:type of object (dict|array|stream|fstream) + % #3:content (key-value, file, string); may be empty + \tl_set:Nn\l_mix_usenum_tl{} + \tl_if_blank:oTF{#1}{ + \pdfobj~reserveobjnum + \tl_set:Nx\l_mix_usenum_tl{useobjnum~\the\pdflastobj} + }{ + \tl_set:Nx\l_mix_usenum_tl{useobjnum~\exp_after:wN \mix_reftonum:w #1} + } + \tl_if_blank:oF{#3}{ + \prg_case_str:nnn{#2}{ + {dict}{\immediate\pdfobj~\l_mix_usenum_tl~{<<#3>>}} + {array}{\immediate\pdfobj~\l_mix_usenum_tl~{[#3]}} + {stream}{\immediate\pdfobj~\l_mix_usenum_tl~stream~{#3}} + {fstream}{\immediate\pdfobj~\l_mix_usenum_tl~stream~file~{#3}} + }{} + } + \tl_gset:Nx\g_mix_pdflastobj_tl{\int_use:c{pdflastobj}~0~R} + } + + \cs_new:Nn\mix_pdfannot:nnnn{ + % #1:width, #2:height, #3:depth, #4:content (key-value) + \immediate\pdfannot~width~#1~height~#2~depth~#3 {#4} + \tl_gset:Nx\g_mix_pdflastann_tl{\int_use:c{pdflastannot}~0~R} + } + + \cs_new:Nn\mix_pdfxform:n{%#1:savebox number + \immediate\pdfxform~resources~{\the\pdfpageresources}~#1 + \tl_gset:Nx\g_mix_pdflastxform_tl{\int_use:c{pdflastxform}~0~R} + } + + \cs_new:Nn\mix_pdfximage:n{%#1:bitmap file name + \bool_if:nF{ + \str_if_eq_p:Vn\l_mix_ext_tl{png} + ||\str_if_eq_p:Vn\l_mix_ext_tl{jpg} + ||\str_if_eq_p:Vn\l_mix_ext_tl{jpeg} + ||\str_if_eq_p:Vn\l_mix_ext_tl{jbig2} + ||\str_if_eq_p:Vn\l_mix_ext_tl{jb2} + }{ + \msg_error:nnxxx{media9}{wrong~image~resource}{#1}{pdftex}{ + png,~jpeg~and~jbig2 + } + } + \immediate\pdfximage{#1} + \tl_gset:Nx\g_mix_pdflastximage_tl{\int_use:c{pdflastximage}~0~R} + } + + \cs_new:Nn\mix_ndname:n{%#1:HEX encoded string + %converted to binary UTF16BE using \pdfunescapehex (pdfTeX only) + \tl_set:Nn\l_mix_ndname_tl{\mix_unescapehex:n{#1}} + } +}{ + \int_new:N\g_mix_obj_int % object ID + \bool_if:NTF\g_mix_dvipdfmx_bool{ %dvipdfmx/XeTeX + \cs_new:Nn\mix_pdfobj:nnn{ + % #1:objref; if empty, a new object number will be reserved + % #2:type of object (dict|array|stream|fstream) + % #3:content (key-value, file, string); may be empty + \tl_set:Nn\l_mix_usenum_tl{} + \tl_if_blank:oTF{#1}{ + \prg_case_str:nnn{#2}{ + {dict}{\special{pdf:obj~@mix@obj\int_use:N\g_mix_obj_int\space<<>>}} + {array}{\special{pdf:obj~@mix@obj\int_use:N\g_mix_obj_int\space[]}} + {stream}{\special{pdf:stream~@mix@obj\int_use:N\g_mix_obj_int\space(#3)}} + {fstream}{ + \message{<#3>} + \special{pdf:fstream~@mix@obj\int_use:N\g_mix_obj_int\space(#3)} + } + }{} + \tl_set:Nx\l_mix_usenum_tl{@mix@obj\int_use:N\g_mix_obj_int} + \int_gincr:N\g_mix_obj_int + }{ + \tl_set:Nx\l_mix_usenum_tl{#1} + } + \tl_if_blank:oF{#3}{ + \prg_case_str:nnn{#2}{ + {dict}{\special{pdf:put~\l_mix_usenum_tl\space<<#3>>}} + {array}{\special{pdf:put~\l_mix_usenum_tl\space#3}} + }{} + } + \tl_gset:Nx\g_mix_pdflastobj_tl{\l_mix_usenum_tl} + } + + \cs_new:Nn\mix_pdfannot:nnnn{ + % #1:width, #2:height, #3:depth, #4:content (key-value) + \special{pdf:ann~@mix@obj\int_use:N\g_mix_obj_int\space + width~#1\space + height~#2\space + depth~#3~<<#4>> + } + \tl_gset:Nx\g_mix_pdflastann_tl{@mix@obj\int_use:N\g_mix_obj_int} + \int_gincr:N\g_mix_obj_int + } + + \cs_new:Nn\mix_pdfxform:n{%#1:savebox number + \special{pdf:bxobj~@mix@obj\int_use:N\g_mix_obj_int\space + width\space\dim_eval:n{\box_wd:N #1}\space + height\space\dim_eval:n{\box_ht:N #1}\space + depth\space\dim_eval:n{\box_dp:N #1} + } + \begin{picture}(0,0)\put(0,0){\box_use:N #1}\end{picture} + \special{pdf:exobj} + \tl_gset:Nx\g_mix_pdflastxform_tl{@mix@obj\int_use:N\g_mix_obj_int} + \int_gincr:N\g_mix_obj_int + } + + \cs_new:Nn\mix_pdfximage:n{%#1:bitmap file name + \bool_if:nF{ + \str_if_eq_p:Vn\l_mix_ext_tl{png} + ||\str_if_eq_p:Vn\l_mix_ext_tl{jpg} + ||\str_if_eq_p:Vn\l_mix_ext_tl{jpeg} + }{ + \msg_error:nnxxx{media9}{wrong~image~resource}{#1}{dvipdfmx/xetex}{ + png~and~jpeg + } + } + \special{pdf:image~@mix@obj\int_use:N\g_mix_obj_int\space + %move initial display off the page + matrix~0.000001~0~0~0.000001~-1000000~-1000000~(#1)} + \tl_gset:Nx\g_mix_pdflastximage_tl{@mix@obj\int_use:N\g_mix_obj_int} + \int_gincr:N\g_mix_obj_int + } + + \cs_new:Nn\mix_ndname:n{%#1:HEX encoded UTF16BE string + \tl_set:Nn\l_mix_ndname_tl{<#1>} + } + }{ + % dvips + \bool_new:N\g_mix_powerdot_bool %to cope with some powerdot oddity + \@ifclassloaded{powerdot}{\bool_gset_true:N\g_mix_powerdot_bool}{} + + %define `?pdfmark' operator as in file hdvips.def from package `hyperref' + \AtBeginDvi{ + \cs_if_exist:NF\pdfmark{ + \special{!~ + systemdict~/pdfmark~known + { + userdict~/?pdfmark~systemdict~/exec~get~put + }{ + userdict~/?pdfmark~systemdict~/pop~get~put~ + userdict~/pdfmark~systemdict~/cleartomark~get~put + } + ifelse~ + } + } + } + + \cs_new:Nn\mix_pdfobj:nnn{ + % #1:objref; if empty, a new object number will be reserved + % #2:type of object (dict|array|stream|fstream) + % #3:content (key-value, file, string); may be empty + \tl_set:Nn\l_mix_usenum_tl{} + \tl_if_blank:oTF{#1}{ + \special{ps:~mark~/_objdef~{mix@obj\int_use:N\g_mix_obj_int}~/type + \prg_case_str:nnn{#2}{ + {dict}{/dict} + {array}{/array} + {stream}{/stream} + {fstream}{/stream} + }{}~ + /OBJ~pdfmark~ + } + \tl_set:Nx\l_mix_usenum_tl{{mix@obj\int_use:N\g_mix_obj_int}} + \int_gincr:N\g_mix_obj_int + }{ + \tl_set:Nx\l_mix_usenum_tl{#1} + } + \tl_if_blank:oF{#3}{ + \prg_case_str:nnn{#2}{ + {dict}{\special{ps:~mark~\l_mix_usenum_tl~<<#3>>/PUT~pdfmark~}} + {array}{ + \special{ps:~mark~\l_mix_usenum_tl~0~[#3]/PUTINTERVAL~pdfmark~} + } + {stream}{\special{ps:~mark~\l_mix_usenum_tl~(#3)/PUT~pdfmark~}} +% {fstream}{ +% \special{ps:~ +% mark~\l_mix_usenum_tl~{(#3)~(r)~file}?pdfmark~/PUT~pdfmark~ +% } +% } + {fstream}{ + \tl_set:Nn\l_mix_offset_tl{0} + \tl_set:Nx\l_mix_fsize_tl{\mix_filesize:n{#3}} + \message{<#3} + %embed file in chunks of 32768 Bytes into PS as chunks of + %65536 Bytes of HEX code + \bool_while_do:nn{ + \int_compare_p:n{\l_mix_offset_tl<\l_mix_fsize_tl} + }{ + \special{ps:~ + mark~ + \l_mix_usenum_tl~ + (\mix_filedump:nnn{\l_mix_offset_tl}{32767}{#3})~ + /ASCIIHexDecode~filter~/PUT~ + pdfmark~ + } + \tl_set:Nx\l_mix_offset_tl{\int_eval:n{\l_mix_offset_tl+32767}} + \message{.} + } + \message{>} + \special{ps:~ + mark~\l_mix_usenum_tl~/CLOSE~pdfmark~ + } + } + }{} + } + \tl_gset:Nx\g_mix_pdflastobj_tl{\l_mix_usenum_tl} + } + + \cs_new:Nn\mix_pdfannot:nnnn{ + \hbox_set:Nn\l_tmpa_box{ + \box_move_down:nn{#3}{ + \hbox_to_zero:n{ + \special{ps:~currentpoint~/mix@lly~exch~def~/mix@llx~exch~def} + } + } + \skip_horizontal:n{#1} + \box_move_up:nn{#2}{ + \hbox_to_zero:n{ + \special{ps:~currentpoint~/mix@ury~exch~def~/mix@urx~exch~def} + } + } + } + \box_set_wd:Nn\l_tmpa_box{\c_zero_dim} + \box_set_ht:Nn\l_tmpa_box{\c_zero_dim} + \box_set_dp:Nn\l_tmpa_box{\c_zero_dim} + \box_use_clear:N\l_tmpa_box + \special{ps:~ + mark~ + /_objdef~{mix@obj\int_use:N\g_mix_obj_int} + /Rect~[mix@llx~mix@lly~mix@urx~mix@ury] + #4~ + /ANN~pdfmark~ + } + \tl_gset:Nx\g_mix_pdflastann_tl{{mix@obj\int_use:N\g_mix_obj_int}} + \int_gincr:N\g_mix_obj_int + } + + \cs_new:Nn\mix_pdfxform:n{%#1:savebox number + %mark bbox of box#1 + \hbox_set:Nn\l_tmpa_box{ + \box_move_down:nn{\box_dp:N #1}{ + \hbox_to_zero:n{ + \special{ps:~currentpoint~/mix@lly~exch~def~/mix@llx~exch~def} + } + } + \skip_horizontal:n{\box_wd:N #1} + \box_move_up:nn{\box_ht:N #1}{ + \hbox_to_zero:n{ + \special{ps:~currentpoint~/mix@ury~exch~def~/mix@urx~exch~def} + } + } + } + \box_set_wd:Nn\l_tmpa_box{\c_zero_dim} + \box_set_ht:Nn\l_tmpa_box{\c_zero_dim} + \box_set_dp:Nn\l_tmpa_box{\c_zero_dim} + \box_use_clear:N\l_tmpa_box + %define some length values in current PS coordinate units + \hbox_set:Nn\l_tmpa_box{ + \special{ps:~currentpoint~/origin@y~exch~def~/origin@x~exch~def} + \skip_horizontal:n{72.27pt} + \box_move_up:nn{72.27pt}{ + \hbox_to_zero:n{ + \special{ps:~ + currentpoint~origin@y~exch~sub~/one@inch@y~exch~def~ + origin@x~sub~/one@inch@x~exch~def + } + } + } + } + \box_set_wd:Nn\l_tmpa_box{\c_zero_dim} + \box_set_ht:Nn\l_tmpa_box{\c_zero_dim} + \box_use_clear:N\l_tmpa_box + \special{ps:~ + gsave~ + %translate graphics to upper left page corner + \bool_if:NF\g_mix_powerdot_bool{ + { + mix@llx~neg~mix@ury~neg~translate~ + one@inch@x~DVImag~div~neg~one@inch@y~DVImag~div~neg~translate + }?pdfmark~ + } + %distill graphics into XObject + mark~ + /_objdef~{mix@obj\int_use:N\g_mix_obj_int} + /BBox~[mix@llx~mix@lly~mix@urx~mix@ury] + /BP~pdfmark~ + { + isls{%landscape mode (powerdot, geometry /w landscape option) + /mix@dxdy~{ + mix@urx~mix@llx~sub~abs~ + mix@ury~mix@lly~sub~abs~div + }~bind~def + /mix@dydx~{1~mix@dxdy~div}~bind~def + /mix@cx~{mix@urx~mix@llx~add~2~div}~bind~def + /mix@cy~{mix@ury~mix@lly~add~2~div}~bind~def + % graphics needs to be rescaled for some reason ... + [mix@dxdy~0~0~mix@dydx~1~mix@dxdy~sub~mix@cx~mul~ + 1~mix@dydx~sub~mix@cy~mul]~concat + %... rotated by 270 degrees ... + [0~-1~1~0~mix@cx~mix@cy~sub~mix@cx~mix@cy~add]~concat + %... and flipped around vertical axis + [-1~0~0~1~mix@llx~mix@urx~add~0]~concat + }{% flip around horizontal axis in portrait mode + [1~0~0~-1~0~mix@lly~mix@ury~add]~concat + }ifelse + }?pdfmark~ + } + \begin{picture}(0,0)\put(0,0){\box_use:N #1}\end{picture} + \special{ps:~mark~/EP~pdfmark~grestore} + \tl_gset:Nx\g_mix_pdflastxform_tl{{mix@obj\int_use:N\g_mix_obj_int}} + \int_gincr:N\g_mix_obj_int + } + + %Image XObject + \cs_new:Nn\mix_pdfximage:n{%#1:bitmap file name + \bool_if:nF{ + \str_if_eq_p:Vn\l_mix_ext_tl{ps} + ||\str_if_eq_p:Vn\l_mix_ext_tl{eps} + }{ + \msg_error:nnxxx{media9}{wrong~image~resource}{#1}{dvips}{ + Postscript~(ps/eps)~with~bitmapped~content + } + } + \special{ps:~ + mark~/_objdef~{mix@obj\int_use:N\g_mix_obj_int}~/NI~pdfmark~ + } + \special{psfile=#1~hsize=0~vsize=0} + \special{ps:~ + { + 0~0~1~[1~0~0~1~0~0]~{}~image~%empty dummy, in case #1 is not + }?pdfmark~ %a valid image file + } + \tl_gset:Nx\g_mix_pdflastximage_tl{{mix@obj\int_use:N\g_mix_obj_int}} + \int_gincr:N\g_mix_obj_int + } + + %3DNode name + \cs_new:Nn\mix_ndname:n{%#1:HEX encoded unicode string + \special{ps:~ + /mix@unicode~65535~string~def~ + (#1)~/ASCIIHexDecode~filter~mix@unicode~readstring~pop~ + /mix@unicode~exch~def~ + } + %converted to binary UTF16BE by ps2pdf + \tl_set:Nn\l_mix_ndname_tl{mix@unicode} + } + } +} + +\cs_new:Nn\mix_embedasset:n{ %#1 file name or url + \filename@parse{#1} + \tl_set:Nx\l_mix_ext_tl{\filename@ext} + \tl_replace_all:Nnn\l_mix_ext_tl{A}{a} + \tl_replace_all:Nnn\l_mix_ext_tl{B}{b} + \tl_replace_all:Nnn\l_mix_ext_tl{C}{c} + \tl_replace_all:Nnn\l_mix_ext_tl{D}{d} + \tl_replace_all:Nnn\l_mix_ext_tl{E}{e} + \tl_replace_all:Nnn\l_mix_ext_tl{F}{f} + \tl_replace_all:Nnn\l_mix_ext_tl{G}{g} + \tl_replace_all:Nnn\l_mix_ext_tl{H}{h} + \tl_replace_all:Nnn\l_mix_ext_tl{I}{i} + \tl_replace_all:Nnn\l_mix_ext_tl{J}{j} + \tl_replace_all:Nnn\l_mix_ext_tl{K}{k} + \tl_replace_all:Nnn\l_mix_ext_tl{L}{l} + \tl_replace_all:Nnn\l_mix_ext_tl{M}{m} + \tl_replace_all:Nnn\l_mix_ext_tl{N}{n} + \tl_replace_all:Nnn\l_mix_ext_tl{O}{o} + \tl_replace_all:Nnn\l_mix_ext_tl{P}{p} + \tl_replace_all:Nnn\l_mix_ext_tl{Q}{q} + \tl_replace_all:Nnn\l_mix_ext_tl{R}{r} + \tl_replace_all:Nnn\l_mix_ext_tl{S}{s} + \tl_replace_all:Nnn\l_mix_ext_tl{T}{t} + \tl_replace_all:Nnn\l_mix_ext_tl{U}{u} + \tl_replace_all:Nnn\l_mix_ext_tl{V}{v} + \tl_replace_all:Nnn\l_mix_ext_tl{W}{w} + \tl_replace_all:Nnn\l_mix_ext_tl{X}{x} + \tl_replace_all:Nnn\l_mix_ext_tl{Y}{y} + \tl_replace_all:Nnn\l_mix_ext_tl{Z}{z} + \bool_if:NTF\l_mix_url_bool{ + \cs_if_exist:cF{url_#1}{ + \mix_pdfobj:nnn{}{dict}{/FS/URL/F(#1)} + \tl_gset:cx{url_#1}{\g_mix_pdflastobj_tl}% + } + %every new url should be added to assets tree of the current annot + \cs_if_exist:cF{url_\int_use:c{g_mix_rmcnt_int}_#1}{ + \tl_gput_right:Nx\g_mix_assets_tl{~(#1)~\tl_use:c{url_#1}} + \tl_new:c{url_\int_use:c{g_mix_rmcnt_int}_#1} + } + \tl_gset:Nx\g_mix_lastasset_tl{\tl_use:c{url_#1}} + }{ + \file_if_exist:nTF{#1}{ + \file_add_path:nN{#1}\l_mix_file_tl + }{ + \msg_error:nnxx{media9}{file~not~found}{#1} + } + \bool_if:nTF{ + %in 3D context, image resources must be embedded as Image XObjects, not + %files + \g_mix_iiid_bool && ( + \str_if_eq_p:Vn\l_mix_ext_tl{jpg} + || \str_if_eq_p:Vn\l_mix_ext_tl{jpeg} + || \str_if_eq_p:Vn\l_mix_ext_tl{png} + || \str_if_eq_p:Vn\l_mix_ext_tl{jbig2} + || \str_if_eq_p:Vn\l_mix_ext_tl{jb2} + || \str_if_eq_p:Vn\l_mix_ext_tl{ps} + || \str_if_eq_p:Vn\l_mix_ext_tl{eps} + ) + }{ + %create Image XObject for bitmaps in 3D context + \cs_if_exist:cF{fileXimg_\mix_filemdfivesum:n{\l_mix_file_tl}}{ + \mix_pdfximage:n{\l_mix_file_tl} + \tl_gset:cx{fileXimg_\mix_filemdfivesum:n{\l_mix_file_tl}}{ + \g_mix_pdflastximage_tl + } + } + %fake FileSpec + \tl_gset:cx{fileSpec_#1}{\tl_use:c{ + fileXimg_\mix_filemdfivesum:n{\l_mix_file_tl}} + } + }{ + %remaining file types in 3D context and any file type in case of Flash + %context will be embedded as fstreams; + %create embedded file stream for every new file + \cs_if_exist:cF{fileEmb_\mix_filemdfivesum:n{\l_mix_file_tl}}{ + \mix_pdfobj:nnn{}{fstream}{\l_mix_file_tl} + \tl_gset:cx{fileEmb_\mix_filemdfivesum:n{\l_mix_file_tl}}{ + \g_mix_pdflastobj_tl + } + } + %every new file name not yet seen should get a new FileSpec dictionary + \cs_if_exist:cF{fileSpec_#1}{ + \mix_pdfobj:nnn{}{dict}{ + /Type/Filespec + /F~(#1) + /UF~(#1) + /EF~<</F~\tl_use:c{fileEmb_\mix_filemdfivesum:n{\l_mix_file_tl}}>> + } + \tl_gset:cx{fileSpec_#1}{\g_mix_pdflastobj_tl} + } + } + %add FileSpec to assets tree of current annot + \cs_if_exist:cF{fileAsset_\int_use:c{g_mix_rmcnt_int}_#1}{ + \tl_gput_right:Nx\g_mix_assets_tl{ + ~(#1)~\tl_use:c{fileSpec_#1} + } + \tl_new:c{fileAsset_\int_use:c{g_mix_rmcnt_int}_#1} + } + \tl_gset:Nx\g_mix_lastasset_tl{ + \tl_use:c{fileSpec_#1} + } + } +} + +\cs_new:Nn\mix_draftbox:n{ %#1 text string to be shown in the draft box centre + \hbox_overlap_right:n{ + \hbox_to_wd:nn{\l_mix_wd_tl}{ + \vrule~height~\l_mix_ht_tl~depth~\l_mix_dp_tl\hss + \vrule + } + } + \box_move_down:nn{\l_mix_dp_tl}{ + \hbox_to_wd:nn{\l_mix_wd_tl}{ + \vbox_to_ht:nn{\l_mix_tt_tl}{ + \hrule~width~\l_mix_wd_tl\vss + \hbox_to_wd:nn{\l_mix_wd_tl}{\ttfamily{\tiny#1}\hss}\vss + \hrule + } + } + } +} + +%calculates widget dimensions from natural ones, taking resizing options +%into account +\int_new:N\g_mix_resizeflag_int% resizing flags according to options given +\cs_new:Nn\mix_scale:n{% #1 box number + %natural dimensions \width, \height, \depth, \totalheight + \tl_set:Nn\width {\box_wd:N#1} + \tl_set:Nn\height{\box_ht:N#1} + \tl_set:Nn\depth {\box_dp:N#1} + \tl_set:Nn\totalheight{(\height+\depth)} + \tl_set:Nx\l_mix_wd_tl{\dim_eval:n{\g_mix_wdarg_tl}} + \tl_set:Nx\l_mix_ht_tl{\dim_eval:n{\g_mix_htarg_tl}} + \tl_set:Nx\l_mix_dp_tl{\dim_eval:n{\g_mix_dparg_tl}} + \tl_set:Nx\l_mix_tt_tl{\dim_eval:n{\g_mix_htarg_tl+\g_mix_dparg_tl}} + %resize unspecified dimensions to keep aspect ratio + \bool_if:nF{ + % original poster box must be two dimensional + \dim_compare_p:n{\width=\c_zero_dim} + ||\dim_compare_p:n{\totalheight=\c_zero_dim} + }{ + \prg_case_int:nnn{\g_mix_resizeflag_int}{ + {\c_zero}{}{\c_seven}{} + {\c_four}{ + \tl_set:Nx\l_mix_ht_tl{ + \dim_eval:n{\height*\dim_ratio:nn{\l_mix_wd_tl}{\width}} + } + \tl_set:Nx\l_mix_dp_tl{ + \dim_eval:n{\depth*\dim_ratio:nn{\l_mix_wd_tl}{\width}} + } + } + {\c_five}{% resize height only if original height!=0 + \dim_compare:nT{\height!=\c_zero_dim}{ + \tl_set:Nx\l_mix_ht_tl{ + \dim_eval:n{ + \totalheight*\dim_ratio:nn{\l_mix_wd_tl}{\width}-\l_mix_dp_tl + } + } + } + } + {\c_six}{% resize depth only if original depth!=0 + \dim_compare:nT{\depth!=\c_zero_dim}{ + \tl_set:Nx\l_mix_dp_tl{ + \dim_eval:n{ + \totalheight*\dim_ratio:nn{\l_mix_wd_tl}{\width}-\l_mix_ht_tl + } + } + } + } + }{ % 1, 2, 3 + \tl_set:Nx\l_mix_wd_tl{ + \dim_eval:n{\width*\dim_ratio:nn{\l_mix_tt_tl}{\totalheight}} + } + } + } + %apply scaling factor + \dim_set:Nn\l_tmpa_dim{\l_mix_wd_tl} + \tl_set:Nx\l_mix_wd_tl{\dim_eval:n{\g_mix_scalearg_tl\l_tmpa_dim}} + \dim_set:Nn\l_tmpa_dim{\l_mix_ht_tl} + \tl_set:Nx\l_mix_ht_tl{\dim_eval:n{\g_mix_scalearg_tl\l_tmpa_dim}} + \dim_set:Nn\l_tmpa_dim{\l_mix_dp_tl} + \tl_set:Nx\l_mix_dp_tl{\dim_eval:n{\g_mix_scalearg_tl\l_tmpa_dim}} + \tl_set:Nx\l_mix_tt_tl{\dim_eval:n{\l_mix_ht_tl+\l_mix_dp_tl}} +} + +\bool_new:N\g_mix_iiid_bool +\int_new:N\l_mix_lineno_int + +\NewDocumentCommand\addmediapath{m}{\file_path_include:n{#1/}} + +\NewDocumentCommand\includemedia{omm}{%#1 options, #2 text/image #3 media file + \group_begin: + \leavevmode + \mix_reset: + \cs_if_exist:NT\Ginput@path{\cs_set_eq:NN\input@path\Ginput@path} + \hbox_set:Nn\l_mix_poster_box{#2} + \mix@uribegin %treat URI characters correctly + \keys_set:nn{media9/user}{#1} + \mix@uriend + \mix_scale:n{\l_mix_poster_box} + \dim_compare:nT{\width=\c_zero_dim} + {\box_set_wd:Nn\l_mix_poster_box{1pt}} + \dim_compare:nT{\totalheight=\c_zero_dim} + {\box_set_ht:Nn\l_mix_poster_box{1pt}} + \bool_if:NTF\g_mix_usrdraft_bool{ + \mix_draftbox:n{\tl_to_str:n{#3}} + }{ + \mix_pdfxform:n{\l_mix_poster_box} + %embed main asset + \group_begin: + \bool_set_eq:NN\l_mix_url_bool\g_mix_url_bool + \mix@uribegin + \mix_embedasset:n{#3} + \bool_gset:Nn\g_mix_iiid_bool{ %test on 3D file type + \str_if_eq_p:Vn\l_mix_ext_tl{prc}||\str_if_eq_p:Vn\l_mix_ext_tl{u3d} + } + \tl_gset:Nx\g_mix_mainasset_tl{~\g_mix_lastasset_tl} + \mix@uriend + \group_end: + %secondary assets (added by addresource) + \seq_map_function:NN\g_mix_res_seq\mix_embedasset:n + \seq_map_inline:Nn\g_mix_script_seq{ + \mix_embedasset:n{##1} + \tl_put_right:Nx\l_mix_scripts_tl{~\g_mix_lastasset_tl} + } + %attach 3D calculation script + \bool_if:nT{\g_mix_iiid_bool && \g_mix_iiidcalc_bool}{ + \mix_embedasset:n{3Dmenu.js} + \tl_put_left:Nx\l_mix_scripts_tl{~\g_mix_lastasset_tl} + } + %create 3D views from file (option 3Dviews) + \bool_if:nT{\g_mix_iiid_bool && !(\tl_if_blank_p:V\g_mix_vfile_tl)}{ + \tl_set:Nn\l_mix_level_tl{\c_minus_one} + \int_zero:N\l_mix_viewcnt_int + \int_zero:N\l_mix_lineno_int + \ior_open:Nn\l_mix_vfile_stream{\g_mix_vfile_tl} + + \group_begin: + \endlinechar=\c_minus_one + \ior_gto:NN\l_mix_vfile_stream\g_mix_inputline_tl + \group_end: + \bool_until_do:nn{\ior_if_eof_p:N\l_mix_vfile_stream}{ + \int_incr:N\l_mix_lineno_int + %process input line + \tl_if_blank:VF\g_mix_inputline_tl{ + \tl_set:Nx\l_mix_args_tl{{media9/views}{\g_mix_inputline_tl}} + \exp_after:wN\keys_set:nn\l_mix_args_tl + } + \group_begin: + \endlinechar=\c_minus_one + \ior_gto:NN\l_mix_vfile_stream\g_mix_inputline_tl + \group_end: + } + + \ior_close:N\l_mix_vfile_stream + } + \bool_if:nT{ %create default 3D view if required + \g_mix_iiid_bool && + (\g_mix_opt_iiidview_bool || \tl_if_blank_p:V\l_mix_iiidviewarray_tl) + }{ + \tl_set_eq:NN\l_mix_bg_tl\g_mix_opt_bg_tl + \tl_set_eq:NN\l_mix_ls_tl\g_mix_opt_ls_tl + \tl_set_eq:NN\l_mix_rm_tl\g_mix_opt_rm_tl + \tl_set_eq:NN\l_mix_coo_tl\g_mix_opt_coo_tl + \tl_set_eq:NN\l_mix_ctoc_tl\g_mix_opt_ctoc_tl + \tl_set_eq:NN\l_mix_ciiw_tl\g_mix_opt_ciiw_tl + + \fp_set_eq:NN\l_mix_roo_fp\g_mix_opt_roo_fp + \fp_set_eq:NN\l_mix_aac_fp\g_mix_opt_aac_fp + \fp_set_eq:NN\l_mix_oscale_fp\g_mix_opt_oscale_fp + \fp_set_eq:NN\l_mix_roll_fp\g_mix_opt_roll_fp + + \bool_set_eq:NN\l_mix_ciiw_bool\g_mix_opt_ciiw_bool + \bool_set_eq:NN\l_mix_iiidortho_bool\g_mix_opt_iiidortho_bool + \tl_set:Nn\l_mix_naarray_tl{} + + \bool_if:NF\l_mix_ciiw_bool{ + \tl_set:Nx\l_mix_args_tl{\l_mix_coo_tl\space\l_mix_ctoc_tl\space} + \exp_after:wN\mix_calc_ciiw:w\l_mix_args_tl\q_stop + } + + \tl_set:Nn\l_mix_naarray_tl{} + \tl_set:Nn\l_mix_saarray_tl{} + + \mix_view:n{Default} + \tl_set:Nx\l_mix_dfltview_tl{\g_mix_pdflastobj_tl} + + } + \mix_pdfobj:nnn{}{dict}{ + /Subtype/\bool_if:NTF\g_mix_iiid_bool{3D}{Flash} + /Asset~\g_mix_mainasset_tl + \bool_if:NF\g_mix_iiid_bool{ + /Params~<< + /Binding/Background + \tl_if_blank:VF\g_mix_flashvars_tl{ + /FlashVars~(\g_mix_flashvars_tl) + } + >> + } + } + \mix_pdfobj:nnn{}{dict}{/Instances~[\g_mix_pdflastobj_tl]}% + \mix_pdfobj:nnn{}{dict}{ + /Assets~<</Names~[\g_mix_assets_tl]>> + /Configurations~[\g_mix_pdflastobj_tl] + \bool_if:nT{ + \g_mix_iiid_bool && !(\tl_if_empty_p:V\l_mix_iiidviewarray_tl) + }{ + /Views~[\l_mix_iiidviewarray_tl] + } + } + \tl_set:Nx\l_mix_content_tl{\g_mix_pdflastobj_tl} + \bool_if:nT{ + \g_mix_iiid_bool && \str_if_eq_p:Vn\g_mix_playtpe_tl{Oscillating} + }{ + \tl_gset:Nx\g_mix_playcnt_tl{\int_eval:n{\g_mix_playcnt_tl*2}} + } + \mix_pdfobj:nnn{}{dict}{ + /Activation~<< + /Condition\g_mix_act_tl + \bool_if:nT{ + \g_mix_iiid_bool && + !(\str_if_eq_p:Vn\g_mix_playtpe_tl{None}) + }{%seems to work only with 3D content + /Animation~<< + /Subtype/\g_mix_playtpe_tl + /PlayCount~\g_mix_playcnt_tl + /Speed~\g_mix_playspd_tl + >> + } + \bool_if:nT{ + \g_mix_iiid_bool && ( + \g_mix_opt_iiidview_bool || \tl_if_blank_p:V\l_mix_iiidviewarray_tl + ) + }{/View~\l_mix_dfltview_tl} + /Presentation~<< + /Transparent~\g_mix_transp_tl + /Style/Embedded + \bool_if:NTF\g_mix_iiid_bool{ + /Toolbar~\g_mix_tools_tl + /NavigationPane~\g_mix_nav_tl + }{ + /PassContextClick~\g_mix_contextclick_tl + } + >> + \tl_if_blank:VF\l_mix_scripts_tl{/Scripts~[\l_mix_scripts_tl]} + >> + /Deactivation~<</Condition\g_mix_deact_tl>> + } + \tl_set:Nx\l_mix_settings_tl{\g_mix_pdflastobj_tl} + \mix_pdfannot:nnnn{\l_mix_wd_tl}{\l_mix_ht_tl}{\l_mix_dp_tl}{ + /Subtype/RichMedia + /F~4 + /BS~<</W~0/S/S>> + /Contents~(media~embedded~by~media9~[\g_mix_version_tl~(\g_mix_date_tl)]) + /NM~(\g_mix_label_tl) + /AP~<</N~\g_mix_pdflastxform_tl>> + /RichMediaSettings~\l_mix_settings_tl + /RichMediaContent~\l_mix_content_tl + } + \hbox_to_wd:nn{\l_mix_wd_tl}{ + \vrule~width~\c_zero_dim~height~\l_mix_ht_tl~depth~\l_mix_dp_tl\hss + } + \int_gincr:N\g_mix_rmcnt_int + } + \group_end: +} + +\ExplSyntaxOff +\def\mix@uribegin{% + %make sure special characters in URIs (RFC 3986) are used unmodified + \begingroup% + \defineshorthand{:}{\detokenize{:}}% + \defineshorthand{/}{\detokenize{/}}% + \defineshorthand{?}{\detokenize{?}}% + \defineshorthand{[}{\detokenize{[}}% + \defineshorthand{]}{\detokenize{]}}% + \defineshorthand{@}{\detokenize{@}}% + \defineshorthand{!}{\detokenize{!}}% + \defineshorthand{$}{\detokenize{$}}% + \defineshorthand{&}{\detokenize{&}}% + \defineshorthand{'}{\detokenize{'}}% + \defineshorthand{(}{\detokenize{(}}% + \defineshorthand{)}{\detokenize{)}}% + \defineshorthand{*}{\detokenize{*}}% + \defineshorthand{+}{\detokenize{+}}% + \defineshorthand{,}{\detokenize{,}}% + \defineshorthand{;}{\detokenize{;}}% + \defineshorthand{=}{\detokenize{=}}% + \defineshorthand{-}{\detokenize{-}}% + \defineshorthand{.}{\detokenize{.}}% + \defineshorthand{_}{\detokenize{_}}% + \defineshorthand{~}{\detokenize{~}}% + \def\%{\string\%}% + \def\#{\string\#}% +} +\def\mix@uriend{\endgroup}% +\ExplSyntaxOn + +% macro to format a real number in tl variable +% * to show at most 9 places after `.' +% * trailing zeros removed +\cs_new:Nn\mix_format_num:N{ + \tl_set:Nx#1{\exp_after:wN\mix_format_num:w#1\q_stop} +} +\cs_new:Npn\mix_format_num:w#1.#2\q_stop{ + #1.\exp_after:wN\mix_trim_places:w#2000000000\q_stop +} +\cs_new:Npn\mix_trim_places:w#1#2#3#4#5#6#7#8#9\q_stop{ + \mix_trim_zeros:f{\exp_after:wN\tl_head:w#9\q_stop#8#7#6#5#4#3#2#1} +} +\cs_new:Nn\mix_trim_zeros:n{ + \exp_after:wN\mix_trim_zeros:w#1\q_stop +} +\cs_generate_variant:Nn\mix_trim_zeros:n{f} +\cs_new:Npn\mix_trim_zeros:w#1#2\q_stop{ + \str_if_eq:nnTF{#1}{0}{ + \int_compare:nNnTF{\tl_length:n{#2}}>{\c_one}{ + \exp_after:wN\mix_trim_zeros:w#2\q_stop + }{#2} + }{ + \tl_reverse:n{#2}#1 + } +} + +%macro for building the C2W transformation matrix +\cs_new:Npn\mix_calc_ciiw:w#1~#2~#3~#4~#5~#6\q_stop{ + % #1,#2,#3 centre of orbit coordinates (coo) + % #4,#5,#6 centre of orbit to camera direction vector (c2c) + %view vector (opposite to c2c) + \fp_set:Nn\l_mix_viewx_fp{#4} + \fp_set:Nn\l_mix_viewy_fp{#5} + \fp_set:Nn\l_mix_viewz_fp{#6} + \fp_neg:N\l_mix_viewx_fp + \fp_neg:N\l_mix_viewy_fp + \fp_neg:N\l_mix_viewz_fp + + %normalize view vector + \fp_set:Nn\l_mix_temp_fp{#4} + \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp} + \fp_set_eq:NN\l_mix_mag_fp\l_mix_temp_fp + \fp_set:Nn\l_mix_temp_fp{#5} + \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp} + \fp_add:Nn\l_mix_mag_fp{\l_mix_temp_fp} + \fp_set:Nn\l_mix_temp_fp{#6} + \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp} + \fp_add:Nn\l_mix_mag_fp{\l_mix_temp_fp} + \fp_pow:Nn\l_mix_mag_fp{0.5} + \fp_div:Nn\l_mix_viewx_fp{\l_mix_mag_fp} + \fp_div:Nn\l_mix_viewy_fp{\l_mix_mag_fp} + \fp_div:Nn\l_mix_viewz_fp{\l_mix_mag_fp} + + %camera roll + \fp_set_eq:NN\l_mix_temp_fp\l_mix_roll_fp + \fp_div:Nn\l_mix_temp_fp{180} + \fp_mul:Nn\l_mix_temp_fp{\c_pi_fp} + \fp_sin:Nn\l_mix_sinroll_fp{\l_mix_temp_fp} + \fp_cos:Nn\l_mix_cosroll_fp{\l_mix_temp_fp} + + %top and bottom views + \fp_set:Nn\l_mix_leftx_fp{-1.0} + \fp_set:Nn\l_mix_lefty_fp{0.0} + \fp_set:Nn\l_mix_leftz_fp{0.0} + \fp_compare:nNnTF\l_mix_viewz_fp<\c_zero_fp{% top view + %up-vector + \fp_set:Nn\l_mix_upx_fp{0.0} + \fp_set:Nn\l_mix_upy_fp{1.0} + \fp_set:Nn\l_mix_upz_fp{0.0} + }{% bottom view + %up-vector + \fp_set:Nn\l_mix_upx_fp{0.0}% + \fp_set:Nn\l_mix_upy_fp{-1.0}% + \fp_set:Nn\l_mix_upz_fp{0.0}% + } + \fp_set_eq:NN\l_mix_temp_fp\l_mix_viewx_fp + \fp_abs:N\l_mix_temp_fp + \fp_set_eq:NN\l_mix_sumxy_fp\l_mix_temp_fp + \fp_set_eq:NN\l_mix_temp_fp\l_mix_viewy_fp + \fp_abs:N\l_mix_temp_fp + \fp_add:Nn\l_mix_sumxy_fp{\l_mix_temp_fp} + \fp_if_zero:NF\l_mix_sumxy_fp{% other views than top and bottom + %up-vector = up_world - (up_world dot view) view + \fp_set_eq:NN\l_mix_upx_fp\l_mix_viewz_fp + \fp_mul:Nn\l_mix_upx_fp{\l_mix_viewx_fp} + \fp_neg:N\l_mix_upx_fp + \fp_set_eq:NN\l_mix_upy_fp\l_mix_viewz_fp + \fp_mul:Nn\l_mix_upy_fp{\l_mix_viewy_fp} + \fp_neg:N\l_mix_upy_fp + \fp_set_eq:NN\l_mix_upz_fp\l_mix_viewz_fp + \fp_mul:Nn\l_mix_upz_fp{\l_mix_viewz_fp} + \fp_neg:N\l_mix_upz_fp + \fp_add:Nn\l_mix_upz_fp{1.0} + %normalize up-vector + \fp_set_eq:NN\l_mix_temp_fp\l_mix_upx_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp} + \fp_set_eq:NN\l_mix_mag_fp\l_mix_temp_fp + \fp_set_eq:NN\l_mix_temp_fp\l_mix_upy_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp} + \fp_add:Nn\l_mix_mag_fp{\l_mix_temp_fp} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_upz_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp} + \fp_add:Nn\l_mix_mag_fp{\l_mix_temp_fp} + \fp_pow:Nn\l_mix_mag_fp{0.5} + \fp_div:Nn\l_mix_upx_fp{\l_mix_mag_fp} + \fp_div:Nn\l_mix_upy_fp{\l_mix_mag_fp} + \fp_div:Nn\l_mix_upz_fp{\l_mix_mag_fp} + %left vector = up x view + \fp_set_eq:NN\l_mix_leftx_fp\l_mix_viewz_fp + \fp_mul:Nn\l_mix_leftx_fp{\l_mix_upy_fp} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_viewy_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_upz_fp} + \fp_sub:Nn\l_mix_leftx_fp{\l_mix_temp_fp} + \fp_set_eq:NN\l_mix_lefty_fp\l_mix_viewx_fp + \fp_mul:Nn\l_mix_lefty_fp{\l_mix_upz_fp} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_viewz_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_upx_fp} + \fp_sub:Nn\l_mix_lefty_fp{\l_mix_temp_fp} + \fp_set_eq:NN\l_mix_leftz_fp\l_mix_viewy_fp + \fp_mul:Nn\l_mix_leftz_fp{\l_mix_upx_fp} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_viewx_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_upy_fp} + \fp_sub:Nn\l_mix_leftz_fp{\l_mix_temp_fp} + %normalize left vector + \fp_set_eq:NN\l_mix_temp_fp\l_mix_leftx_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp} + \fp_set_eq:NN\l_mix_mag_fp\l_mix_temp_fp + \fp_set_eq:NN\l_mix_temp_fp\l_mix_lefty_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp} + \fp_add:Nn\l_mix_mag_fp{\l_mix_temp_fp} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_leftz_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp} + \fp_add:Nn\l_mix_mag_fp{\l_mix_temp_fp} + \fp_pow:Nn\l_mix_mag_fp{0.5} + \fp_div:Nn\l_mix_leftx_fp{\l_mix_mag_fp} + \fp_div:Nn\l_mix_lefty_fp{\l_mix_mag_fp} + \fp_div:Nn\l_mix_leftz_fp{\l_mix_mag_fp} + } + + %apply camera roll + \fp_set_eq:NN\l_mix_leftxprime_fp\l_mix_leftx_fp + \fp_mul:Nn\l_mix_leftxprime_fp{\l_mix_cosroll_fp} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_upx_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_sinroll_fp} + \fp_add:Nn\l_mix_leftxprime_fp{\l_mix_temp_fp} + \fp_set_eq:NN\l_mix_leftyprime_fp\l_mix_lefty_fp + \fp_mul:Nn\l_mix_leftyprime_fp{\l_mix_cosroll_fp} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_upy_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_sinroll_fp} + \fp_add:Nn\l_mix_leftyprime_fp{\l_mix_temp_fp} + \fp_set_eq:NN\l_mix_leftzprime_fp\l_mix_leftz_fp + \fp_mul:Nn\l_mix_leftzprime_fp{\l_mix_cosroll_fp} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_upz_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_sinroll_fp} + \fp_add:Nn\l_mix_leftzprime_fp{\l_mix_temp_fp} + + \fp_set_eq:NN\l_mix_upxprime_fp\l_mix_upx_fp + \fp_mul:Nn\l_mix_upxprime_fp{\l_mix_cosroll_fp} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_leftx_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_sinroll_fp} + \fp_sub:Nn\l_mix_upxprime_fp{\l_mix_temp_fp} + \fp_set_eq:NN\l_mix_upyprime_fp\l_mix_upy_fp + \fp_mul:Nn\l_mix_upyprime_fp{\l_mix_cosroll_fp} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_lefty_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_sinroll_fp} + \fp_sub:Nn\l_mix_upyprime_fp{\l_mix_temp_fp} + \fp_set_eq:NN\l_mix_upzprime_fp\l_mix_upz_fp + \fp_mul:Nn\l_mix_upzprime_fp{\l_mix_cosroll_fp} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_leftz_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_sinroll_fp} + \fp_sub:Nn\l_mix_upzprime_fp{\l_mix_temp_fp} + + \fp_set_eq:NN\l_mix_leftx_fp\l_mix_leftxprime_fp + \fp_set_eq:NN\l_mix_lefty_fp\l_mix_leftyprime_fp + \fp_set_eq:NN\l_mix_leftz_fp\l_mix_leftzprime_fp + \fp_set_eq:NN\l_mix_upx_fp\l_mix_upxprime_fp + \fp_set_eq:NN\l_mix_upy_fp\l_mix_upyprime_fp + \fp_set_eq:NN\l_mix_upz_fp\l_mix_upzprime_fp + + %translation vector + \fp_set:Nn\l_mix_transx_fp{#1} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_roo_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_viewx_fp} + \fp_sub:Nn\l_mix_transx_fp{\l_mix_temp_fp} + \fp_set:Nn\l_mix_transy_fp{#2} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_roo_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_viewy_fp} + \fp_sub:Nn\l_mix_transy_fp{\l_mix_temp_fp} + \fp_set:Nn\l_mix_transz_fp{#3} + \fp_set_eq:NN\l_mix_temp_fp\l_mix_roo_fp + \fp_mul:Nn\l_mix_temp_fp{\l_mix_viewz_fp} + \fp_sub:Nn\l_mix_transz_fp{\l_mix_temp_fp} + + %format elements of transformation matrix + \tl_set:Nx\l_mix_leftx_tl {\fp_use:N\l_mix_leftx_fp } + \tl_set:Nx\l_mix_lefty_tl {\fp_use:N\l_mix_lefty_fp } + \tl_set:Nx\l_mix_leftz_tl {\fp_use:N\l_mix_leftz_fp } + \tl_set:Nx\l_mix_upx_tl {\fp_use:N\l_mix_upx_fp } + \tl_set:Nx\l_mix_upy_tl {\fp_use:N\l_mix_upy_fp } + \tl_set:Nx\l_mix_upz_tl {\fp_use:N\l_mix_upz_fp } + \tl_set:Nx\l_mix_viewx_tl {\fp_use:N\l_mix_viewx_fp } + \tl_set:Nx\l_mix_viewy_tl {\fp_use:N\l_mix_viewy_fp } + \tl_set:Nx\l_mix_viewz_tl {\fp_use:N\l_mix_viewz_fp } + \tl_set:Nx\l_mix_transx_tl{\fp_use:N\l_mix_transx_fp} + \tl_set:Nx\l_mix_transy_tl{\fp_use:N\l_mix_transy_fp} + \tl_set:Nx\l_mix_transz_tl{\fp_use:N\l_mix_transz_fp} + \mix_format_num:N\l_mix_leftx_tl + \mix_format_num:N\l_mix_lefty_tl + \mix_format_num:N\l_mix_leftz_tl + \mix_format_num:N\l_mix_upx_tl + \mix_format_num:N\l_mix_upy_tl + \mix_format_num:N\l_mix_upz_tl + \mix_format_num:N\l_mix_viewx_tl + \mix_format_num:N\l_mix_viewy_tl + \mix_format_num:N\l_mix_viewz_tl + \mix_format_num:N\l_mix_transx_tl + \mix_format_num:N\l_mix_transy_tl + \mix_format_num:N\l_mix_transz_tl + + %concat elements to matrix + \tl_set:Nx\l_mix_ciiw_tl{ + \l_mix_leftx_tl \space + \l_mix_lefty_tl \space + \l_mix_leftz_tl \space + \l_mix_upx_tl \space + \l_mix_upy_tl \space + \l_mix_upz_tl \space + \l_mix_viewx_tl \space + \l_mix_viewy_tl \space + \l_mix_viewz_tl \space + \l_mix_transx_tl\space + \l_mix_transy_tl\space + \l_mix_transz_tl + } +} + +% 3D view object +\cs_new:Nn\mix_view:n{ + \tl_set:Nx\l_mix_oscale_tl{\fp_use:N\l_mix_oscale_fp} + \mix_format_num:N\l_mix_oscale_tl + \tl_set:Nx\l_mix_aac_tl{\fp_use:N\l_mix_aac_fp} + \mix_format_num:N\l_mix_aac_tl + \tl_set:Nx\l_mix_roo_tl{\fp_use:N\l_mix_roo_fp} + \mix_format_num:N\l_mix_roo_tl + \mix_pdfobj:nnn{}{dict}{ + /MS/M + /P<< + \bool_if:NTF\l_mix_iiidortho_bool{ + /Subtype/O/OS~\l_mix_oscale_tl/OB/Min + }{ + /Subtype/P/FOV~\l_mix_aac_tl/PS/Min + } + >> + /C2W~[\l_mix_ciiw_tl] + /CO~\l_mix_roo_tl + /NR~true/NA~[\l_mix_naarray_tl] + /SA~[\l_mix_saarray_tl] + \l_mix_bg_tl\l_mix_ls_tl\l_mix_rm_tl + /XN~(#1) + } +} + +%document command options + +\msg_set:nnnn{media9}{unknown~option}{ + Line~\msg_line_number: :~Unknown~option~`#1'. +}{ + Option~'#1'~is~not~known~by~media9:\\ + perhaps~it~is~spelled~incorrectly. +} + +\msg_set:nnn{media9}{same~label}{ + Line~\msg_line_number: :~Label~`#1'~multiply~defined. +} +\msg_set:nnn{media9}{multiple~labels}{\\ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\\ + @@~There~were~multiply-defined~labels!~@@\\ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +} + +\bool_new:N\g_mix_usrdraft_bool +\bool_new:N\g_mix_opt_iiidview_bool +\bool_new:N\l_mix_roo_bool +\bool_new:N\g_mix_opt_ciiw_bool +\bool_new:N\g_mix_opt_iiidortho_bool +\bool_new:N\l_mix_ciiw_bool +\bool_new:N\l_mix_iiidortho_bool + +\seq_new:N\g_mix_res_seq +\seq_new:N\g_mix_script_seq +\keys_define:nn{media9/user}{ + %user override automatic label + label .code:n = { + \tl_gset:Nx\g_mix_label_tl{rm.#1} + \cs_if_exist:cTF{rm.#1}{ + \msg_warning:nnx{media9}{same~label}{#1} + \cs_if_exist:NF\g_mix_samelabel_tl{ + \tl_new:N\g_mix_samelabel_tl + \AtEndDocument{\msg_warning:nn{media9}{multiple~labels}} + } + }{ + \tl_new:c{rm.#1} + } + }, + label .value_required:, + + width .code:n = { + \tl_gset:Nn\g_mix_wdarg_tl{#1} + \int_gadd:Nn\g_mix_resizeflag_int{\c_four} + }, + width .value_required:, + + height .code:n = { + \tl_gset:Nn\g_mix_htarg_tl{#1} + \int_gadd:Nn\g_mix_resizeflag_int{\c_two} + }, + height .value_required:, + + depth .code:n = { + \tl_gset:Nn\g_mix_dparg_tl{#1} + \int_gadd:Nn\g_mix_resizeflag_int{\c_one} + }, + depth .value_required:, + + scale .code:n = {\tl_gset:Nx\g_mix_scalearg_tl{#1}}, + scale .value_required:, + + url .bool_gset:N = \g_mix_url_bool, + + addresource .code:n = {\seq_gput_right:Nn\g_mix_res_seq{#1}}, + addresource .value_required:, + + add3Djscript .code:n = {\seq_gput_right:Nn\g_mix_script_seq{#1}}, + add3Djscript .value_required:, + + flashvars .tl_gset_x:N = \g_mix_flashvars_tl, + flashvars .value_required:, + + activate .choice:, + activate / pagevisible .code:n = {\tl_gset:Nn\g_mix_act_tl{/PV}}, + activate / pageopen .code:n = {\tl_gset:Nn\g_mix_act_tl{/PO}}, + activate / onclick .code:n = {\tl_gset:Nn\g_mix_act_tl{/XA}}, + + deactivate .choice:, + deactivate / pageinvisible .code:n = {\tl_gset:Nn\g_mix_act_tl{/PI}}, + deactivate / pageclose .code:n = {\tl_gset:Nn\g_mix_act_tl{/PC}}, + deactivate / onclick .code:n = {\tl_gset:Nn\g_mix_act_tl{/XD}}, + + draft .choice:, + draft / true .code:n = {\bool_gset_true:N\g_mix_usrdraft_bool}, + draft / false .code:n = {\bool_gset_false:N\g_mix_usrdraft_bool}, + draft .default:n = {true}, + + final .choice:, + final / true .code:n = {\bool_gset_false:N\g_mix_usrdraft_bool}, + final / false .code:n = {\bool_gset_true:N\g_mix_usrdraft_bool}, + final .default:n = {true}, + + transparent .choice_code:n = {\tl_gset:Nx\g_mix_transp_tl{\l_keys_choice_tl}}, + transparent .generate_choices:n = {true,false}, + transparent .default:n = {true}, + + passcontext .choice_code:n = {\tl_gset:Nx\g_mix_contextclick_tl{ + \l_keys_choice_tl}}, + passcontext .generate_choices:n = {true,false}, + passcontext .default:n = {true}, + + %3D specific options + 3Dplaytype .choice:, + 3Dplaytype / none .code:n = {\tl_gset:Nn\g_mix_playtpe_tl{None}}, + 3Dplaytype / linear .code:n = {\tl_gset:Nn\g_mix_playtpe_tl{Linear}}, + 3Dplaytype / oscillating .code:n = { + \tl_gset:Nn\g_mix_playtpe_tl{Oscillating}}, + + 3Dplaycount .code:n = {\tl_gset:Nn\g_mix_playcnt_tl{ + \exp_after:wN\int_value:w \dim_eval:w#1sp\dim_eval_end:}}, + 3Dplaycount .value_required:, + + 3Dplayspeed .tl_gset_x:N = \g_mix_playspd_tl, + 3Dplayspeed .value_required:, + + 3Dtoolbar .choice_code:n = {\tl_gset:Nx\g_mix_tools_tl{\l_keys_choice_tl}}, + 3Dtoolbar .generate_choices:n = {true,false}, + 3Dtoolbar .default:n = {true}, + + 3Dnavpane .choice_code:n = {\tl_gset:Nx\g_mix_nav_tl{\l_keys_choice_tl}}, + 3Dnavpane .generate_choices:n = {true,false}, + 3Dnavpane .default:n = {true}, + + 3Dcoo .code:n = {\tl_gset:Nn\g_mix_opt_coo_tl{#1} + \bool_gset_true:N\g_mix_opt_iiidview_bool}, + 3Dcoo .value_required:, + + 3Dc2c .code:n = {\tl_gset:Nn\g_mix_opt_ctoc_tl{#1} + \bool_gset_true:N\g_mix_opt_iiidview_bool}, + 3Dc2c .value_required:, + + 3Dc2w .code:n = { + \tl_gset:Nx\g_mix_opt_ciiw_tl{#1} + \bool_gset_true:N\g_mix_opt_iiidview_bool + \bool_gset_true:N\g_mix_opt_ciiw_bool + }, + 3Dc2w .value_required:, + + 3Droo .code:n = { + \fp_gset:Nn\g_mix_opt_roo_fp{#1} + \fp_abs:N\g_mix_opt_roo_fp + \fp_if_zero:NT\g_mix_opt_roo_fp{\fp_set:Nn\g_mix_opt_roo_fp{1e-8}} + \bool_gset_true:N\g_mix_opt_iiidview_bool + \bool_set_true:N\l_mix_roo_bool + }, + 3Droo .value_required:, + + 3Daac .code:n = {\fp_gset:Nn\g_mix_opt_aac_fp{#1} + \bool_gset_true:N\g_mix_opt_iiidview_bool}, + 3Daac .value_required:, + + 3Dortho .code:n = { + \bool_gset_true:N\g_mix_opt_iiidview_bool + \bool_gset_true:N\g_mix_opt_iiidortho_bool + \fp_compare:nNnF#1=\c_zero{ + \fp_gset:Nn\g_mix_opt_oscale_fp{#1} + \bool_if:NF\l_mix_roo_bool{ + \fp_set:Nn\l_mix_temp_fp{1} + \fp_div:Nn\l_mix_temp_fp{#1} + \fp_div:Nn\l_mix_temp_fp{2} + \fp_gset_eq:NN\g_mix_opt_roo_fp\l_mix_temp_fp + } + } + }, + 3Dortho .default:n = {1}, + + 3Droll .code:n = {\fp_gset:Nn\g_mix_opt_roll_fp{#1} + \bool_gset_true:N\g_mix_opt_iiidview_bool}, + 3Droll .value_required:, + + 3Dmenu .bool_gset:N = \g_mix_iiidcalc_bool, + + 3Dbg .code:n = { + \tl_gset:Nx\g_mix_opt_bg_tl{/BG<</Subtype/SC/CS/DeviceRGB/C[#1]/EA~true>>} + }, + 3Dbg .value_required:, + + 3Dlights .code:n = { + \tl_gset:Nx\g_mix_opt_ls_tl{/LS<</Subtype/#1>>} + }, + 3Dlights .value_required:, + + 3Drender .code:n = { + \tl_gset:Nx\g_mix_opt_rm_tl{/RM<</Subtype/#1>>} + }, + 3Drender .value_required:, + + 3Dviews .code:n = { + \file_if_exist:nTF{#1}{ + \file_add_path:nN{#1}\l_mix_temp_tl + \tl_gset_eq:NN\g_mix_vfile_tl\l_mix_temp_tl + }{ + \msg_error:nnxx{media9}{file~not~found}{#1} + } + }, + 3Dviews .value_required:, + + unknown .code:n = { + \msg_error:nnx{media9}{unknown~option}{\exp_not:V\l_keys_key_tl} + }, +} + +%3D views file parsing + +%messages related to 3D views file parsing +\msg_set:nnn{media9}{nested~view}{ + File~#1,~line~#2:\\ + A~VIEW~section~cannot~be~nested~into~another~section. +} + +\msg_set:nnn{media9}{key~not~allowed}{ + File~#1,~line~#2:\\ + Key~`#3'~not~allowed~here;~must~go~into~#4~section. +} + +\msg_set:nnn{media9}{section~not~allowed}{ + File~#1,~line~#2:\\ + #3~not~allowed~here;~must~be~a~sub-section~of~a~#4~section. +} + +\msg_set:nnn{media9}{missing~part~name}{ + File~#1,~line~#2:\\ + You~must~provide~a~valid~PART~name~(PART=<part name>),~as~displayed\\ + in~the~model~tree~of~the~3D~object~(go~to~`View'->`Navigation~Panels'\\ + ->`Model~Tree'~in~Adobe~Reader). +} + +\msg_set:nnn{media9}{missing~utf16~name}{ + File~#1,~line~#2:\\ + You~must~provide~a~valid~hex~encoded~part~name~(UTF16NAME=<part~name\\ + as~hex~encoded~UTF-16~string>).~Enable~`3Dmenu'~option~and~choose\\ + `Get~Current~View'~from~3D~context~menu~to~generate~correct~views~file\\ + entries. +} + +\msg_set:nnn{media9}{too~many~cross~sections}{ + File~#1,~line~#2:\\ + Adobe~Reader~supports~only~one~cross~section~per~3D~view.\\ + I~am~ignoring~this~CROSSSECT. +} + +\msg_set:nnn{media9}{no~end~here}{ + File~#1,~line~#2:\\ + There~is~nothing~to~END~here. +} + +\cs_new:Npn\mix_parse_vect:w#1~#2~#3\q_stop{ + \fp_set:Nn\l_mix_x_fp{#1} + \fp_set:Nn\l_mix_y_fp{#2} + \fp_set:Nn\l_mix_z_fp{#3} +} + +\cs_new:Nn\mix_arcsin:Nnnn{ + %#1 result (rad), #2 argument, #3 current term no., #4 total number of + %terms + \int_compare:nTF{#3==\c_zero}{ + \fp_set:Nn\l_mix_tmpa_fp{1.0} + \fp_set:Nn\l_mix_tmpb_fp{1.0} + \fp_set:Nn\l_mix_tmpc_fp{1.0} + \fp_set:Nn\l_mix_tmpd_fp{#2} + + \fp_set:Nn#1{#2} + }{ + \fp_mul:Nn\l_mix_tmpa_fp{\int_eval:n{2*#3-1}} + \fp_mul:Nn\l_mix_tmpb_fp{\int_eval:n{2*#3}} + \fp_set:Nn\l_mix_tmpc_fp{\int_eval:n{2*#3+1}} + \fp_mul:Nn\l_mix_tmpd_fp{#2} + \fp_mul:Nn\l_mix_tmpd_fp{#2} + + \fp_set_eq:NN\l_mix_tmpe_fp\l_mix_tmpd_fp + \fp_mul:Nn\l_mix_tmpe_fp{\l_mix_tmpa_fp} + \fp_div:Nn\l_mix_tmpe_fp{\l_mix_tmpb_fp} + \fp_div:Nn\l_mix_tmpe_fp{\l_mix_tmpc_fp} + + \fp_add:Nn#1{\l_mix_tmpe_fp} + } + \int_compare:nF{#3==#4}{ + \mix_arcsin:Nnnn#1{#2}{\int_eval:n{#3+1}}{#4} + } +} + +\cs_new:Nn\mix_angfromxy:Nnn{ %#1 result (deg), #2 x, #3 y + %#1 result, #2 x, #3 y + \fp_set:Nn\l_mix_tmpa_fp{#2}\fp_mul:Nn\l_mix_tmpa_fp{#2} + \fp_set:Nn\l_mix_tmpb_fp{#3}\fp_mul:Nn\l_mix_tmpb_fp{#3} + \fp_add:Nn\l_mix_tmpa_fp\l_mix_tmpb_fp + \fp_pow:Nn\l_mix_tmpa_fp{0.5} + \fp_set:Nn\l_mix_asinarg_fp{#3} + \fp_div:Nn\l_mix_asinarg_fp\l_mix_tmpa_fp + \fp_set:Nn\l_mix_acosarg_fp{#2} + \fp_div:Nn\l_mix_acosarg_fp\l_mix_tmpa_fp + \fp_set:Nn\l_mix_halfsqrttwo_fp{2} + \fp_pow:Nn\l_mix_halfsqrttwo_fp{0.5} + \fp_div:Nn\l_mix_halfsqrttwo_fp{2} + \mix_arcsin:Nnnn\l_mix_arcsin_fp{\l_mix_asinarg_fp}{0}{10} + \mix_arcsin:Nnnn\l_mix_arccos_fp{\l_mix_acosarg_fp}{0}{10} + \fp_abs:N\l_mix_asinarg_fp + %determine quadrant + \fp_compare:nTF{#2>=\c_zero_fp}{ + \fp_compare:nTF{#3>=\c_zero_fp}{ %I + \fp_compare:nNnTF\l_mix_asinarg_fp<\l_mix_halfsqrttwo_fp{ + \fp_set_eq:NN#1\l_mix_arcsin_fp + }{ + \fp_set:Nn#1{\c_pi_fp}\fp_div:Nn#1{2} + \fp_sub:Nn#1\l_mix_arccos_fp + } + }{ %IV + \fp_compare:nNnTF\l_mix_asinarg_fp<\l_mix_halfsqrttwo_fp{ + \fp_set_eq:NN#1\l_mix_arcsin_fp + }{ + \fp_set:Nn#1{\c_pi_fp}\fp_div:Nn#1{2} + \fp_sub:Nn#1\l_mix_arccos_fp + \fp_neg:N#1 + } + } + }{ + \fp_compare:nTF{#3>=\c_zero_fp}{ %II + \fp_compare:nNnTF\l_mix_asinarg_fp<\l_mix_halfsqrttwo_fp{ + \fp_set:Nn#1{\c_pi_fp} + \fp_sub:Nn#1\l_mix_arcsin_fp + }{ + \fp_set:Nn#1{\c_pi_fp}\fp_div:Nn#1{2} + \fp_sub:Nn#1\l_mix_arccos_fp + } + }{ %III + \fp_compare:nNnTF\l_mix_asinarg_fp<\l_mix_halfsqrttwo_fp{ + \fp_set:Nn#1{-\c_pi_fp} + \fp_sub:Nn#1\l_mix_arcsin_fp + }{ + \fp_set:Nn#1{\c_pi_fp}\fp_div:Nn#1{2} + \fp_sub:Nn#1\l_mix_arccos_fp + \fp_neg:N#1 + } + } + } + \fp_mul:Nn#1{180}\fp_div:Nn#1{\c_pi_fp} +} + +\bool_new:N\l_mix_blankndname_bool + +%keys for parsing the 3D views file +\keys_define:nn{media9/views}{ + VIEW .code:n = { + \int_compare:nF{\l_mix_level_tl<\c_zero}{ + \msg_error:nnxx{media9}{nested~view} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int} + } + \tl_set:Nn\l_mix_level_tl{\c_zero} + \tl_set:Nn\l_mix_cscount_tl{\c_zero} + \tl_set:Nx\l_mix_xname_tl{#1}%optional name of the view + %reset 3D settings to defaults + \mix_iiidreset: + }, + VIEW .default:n = {}, + + COO .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_zero}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{COO}{a~VIEW} + } + \tl_set:Nx\l_mix_coo_tl{#1} + }, + COO .value_required:, + + C2C .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_zero}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{C2C}{a~VIEW} + } + \tl_set:Nx\l_mix_ctoc_tl{#1} + }, + C2C .value_required:, + + C2W .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_zero}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{C2W}{a~VIEW} + } + \tl_set:Nx\l_mix_ciiw_tl{#1} + \bool_set_true:N\l_mix_ciiw_bool + }, + C2W .value_required:, + + ROO .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_zero}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{ROO}{a~VIEW} + } + \fp_set:Nn\l_mix_roo_fp{#1} + \fp_abs:N\l_mix_roo_fp + \fp_if_zero:NT\l_mix_roo_fp{\fp_set:Nn\l_mix_roo_fp{1e-8}} + \bool_set_true:N\l_mix_roo_bool + }, + ROO .value_required:, + + AAC .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_zero}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{AAC}{a~VIEW} + } + \fp_set:Nn\l_mix_aac_fp{#1} + }, + AAC .value_required:, + + ORTHO .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_zero}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{ORTHO}{a~VIEW} + } + \bool_set_true:N\l_mix_iiidortho_bool + \fp_compare:nNnF#1=\c_zero{ + \fp_set:Nn\l_mix_oscale_fp{#1} + \bool_if:NF\l_mix_roo_bool{ + \fp_set:Nn\l_mix_temp_fp{1} + \fp_div:Nn\l_mix_temp_fp{#1} + \fp_div:Nn\l_mix_temp_fp{2} + \fp_set_eq:NN\l_mix_roo_fp\l_mix_temp_fp + } + } + }, + ORTHO .default:n = {1}, + + ROLL .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_zero}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{ROLL}{a~VIEW} + } + \fp_set:Nn\l_mix_roll_fp{#1} + }, + ROLL .value_required:, + + BGCOLOR .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_zero}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{BGCOLOR}{a~VIEW} + } + \tl_set:Nx\l_mix_bg_tl{/BG<</CS/DeviceRGB/C[#1]/EA~true>>} + }, + BGCOLOR .value_required:, + + LIGHTS .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_zero}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{LIGHTS}{a~VIEW} + } + \tl_set:Nx\l_mix_ls_tl{/LS<</Subtype/#1>>} + }, + LIGHTS .value_required:, + + RENDERMODE .code:n = { + \bool_if:nF{ + \int_compare_p:n{\l_mix_level_tl=\c_zero} || + \int_compare_p:n{\l_mix_level_tl=\c_one} + }{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int} + {RENDERMODE}{a~VIEW~or~a~PART} + } + \int_compare:nT{\l_mix_level_tl=\c_zero}{ + \tl_set:Nx\l_mix_rm_tl{/RM<</Subtype/#1>>} + } + \int_compare:nT{\l_mix_level_tl=\c_one}{ + \tl_set:Nx\l_mix_ndrm_tl{/RM<</Subtype/#1>>} %part (=node) render mode + } + }, + RENDERMODE .value_required:, + + PART .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_zero}{ + \msg_error:nnxxxx{media9}{section~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{PART}{VIEW} + } + \bool_set_true:N\l_mix_blankndname_bool + \bool_set:Nn\l_mix_blankndname_bool{\tl_if_blank_p:o{#1}} + \tl_set:Nn\l_mix_level_tl{\c_one} + \tl_set:Nn\l_mix_ndname_tl{(#1)} %part (=node) name + \tl_set_eq:NN\l_mix_partlineno_int\l_mix_lineno_int + %default part settings + \tl_set:Nn\l_mix_ndop_tl{} %opacity + \tl_set:Nn\l_mix_ndvi_tl{} %visibility + \tl_set:Nn\l_mix_ndrm_tl{} %render mode + \tl_set:Nn\l_mix_ndtrans_tl{}%transformation matrix + }, + PART .default:n = {}, + + UTF16NAME .code:n = { %part (=node) name, UTF16, HEX encoded + \int_compare:nF{\l_mix_level_tl=\c_one}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{UTF16NAME}{PART} + } + \tl_if_blank:oT{#1}{ + \msg_error:nnxx{media9}{missing~utf16~name} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int} + } + \bool_set_false:N\l_mix_blankndname_bool + \mix_ndname:n{feff#1} + }, + UTFNAME .default:n = {}, + + OPACITY .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_one}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{OPACITY}{PART} + } + \tl_set:Nx\l_mix_ndop_tl{/O~#1} + }, + OPACITY .value_required:, + + VISIBLE .choice_code:n = { + \int_compare:nF{\l_mix_level_tl=\c_one}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{VISIBLE}{PART} + } + \tl_set:Nx\l_mix_ndvi_tl{/V~\l_keys_choice_tl} + }, + VISIBLE .generate_choices:n = {true,false}, + VISIBLE .default:n = {true}, + + TRANSFORM .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_one}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{TRANSLATE}{PART} + } + \seq_set_split:Nnn\l_mix_args_seq{~}{#1} + \seq_map_inline:Nn\l_mix_args_seq{ + \fp_set:Nn\l_mix_tmpa_fp{##1} + \tl_set:Nx\l_mix_tmpa_tl{\fp_use:N\l_mix_tmpa_fp} + \mix_format_num:N\l_mix_tmpa_tl + \tl_put_right:Nx\l_mix_ndtrans_tl{~\l_mix_tmpa_tl} + } + }, + TRANSFORM .value_required:, + + CROSSSECT .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_zero}{ + \msg_error:nnxxxx{media9}{section~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{CROSSSECT}{VIEW} + } + \int_compare:nT{\l_mix_cscount_tl>\c_zero}{ + \msg_warning:nnxx{media9}{too~many~cross~sections} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int} + } + \tl_set:Nn\l_mix_level_tl{\c_two} + %default part settings + \tl_set:Nn\l_mix_cscentre_tl{0~0~0} %centre of clipping plane + \tl_set:Nn\l_mix_csorient_tl{null~0~0} %orientation of plane + }, + CROSSSECT .value_forbidden:, + + CENTER .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_two}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{CENTER}{CROSSSECT} + } + \tl_set:Nx\l_mix_args_tl{#1\space} + \exp_after:wN\mix_parse_vect:w\l_mix_args_tl\q_stop + \tl_set:Nx\l_mix_x_tl{\fp_use:N\l_mix_x_fp} + \mix_format_num:N\l_mix_x_tl + \tl_set:Nx\l_mix_y_tl{\fp_use:N\l_mix_y_fp} + \mix_format_num:N\l_mix_y_tl + \tl_set:Nx\l_mix_z_tl{\fp_use:N\l_mix_z_fp} + \mix_format_num:N\l_mix_z_tl + \tl_set:Nx\l_mix_cscentre_tl{ + \l_mix_x_tl\space + \l_mix_y_tl\space + \l_mix_z_tl + } + }, + CENTER .value_required:, + + NORMAL .code:n = { + \int_compare:nF{\l_mix_level_tl=\c_two}{ + \msg_error:nnxxxx{media9}{key~not~allowed} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{NORMAL}{CROSSSECT} + } + \tl_set:Nx\l_mix_args_tl{#1\space} + \exp_after:wN\mix_parse_vect:w\l_mix_args_tl\q_stop + \fp_set_eq:NN\l_mix_tmpa_fp\l_mix_x_fp + \fp_mul:Nn\l_mix_tmpa_fp\l_mix_x_fp + \fp_set_eq:NN\l_mix_tmpb_fp\l_mix_y_fp + \fp_mul:Nn\l_mix_tmpb_fp\l_mix_y_fp + \fp_set_eq:NN\l_mix_magxy\l_mix_tmpa_fp + \fp_add:Nn\l_mix_magxy\l_mix_tmpb_fp + \fp_pow:Nn\l_mix_magxy{0.5} %sqrt(x^2+y^2) + %rot angle of normal vec around Y axis + \mix_angfromxy:Nnn\l_mix_roty_fp\l_mix_magxy\l_mix_z_fp + \fp_neg:N\l_mix_roty_fp + %rot angle of normal vec around Z axis + \mix_angfromxy:Nnn\l_mix_rotz_fp\l_mix_x_fp\l_mix_y_fp + \tl_set:Nx\l_mix_roty_tl{\fp_use:N\l_mix_roty_fp} + \mix_format_num:N\l_mix_roty_tl + \tl_set:Nx\l_mix_rotz_tl{\fp_use:N\l_mix_rotz_fp} + \mix_format_num:N\l_mix_rotz_tl + \tl_set:Nx\l_mix_csorient_tl{null~\l_mix_roty_tl\space\l_mix_rotz_tl} + }, + NORMAL .value_required:, + + END .code:n = { + \prg_case_int:nnn{\l_mix_level_tl}{ + {0}{ %VIEW + \bool_if:NF\l_mix_ciiw_bool{ + \tl_set:Nx\l_mix_args_tl{\l_mix_coo_tl\space\l_mix_ctoc_tl\space} + \exp_after:wN\mix_calc_ciiw:w\l_mix_args_tl\q_stop + } + \int_incr:N\l_mix_viewcnt_int + \tl_if_blank:VT\l_mix_xname_tl{ + \tl_set:Nx\l_mix_xname_tl{View~\int_use:N\l_mix_viewcnt_int} + } + \mix_view:n{\l_mix_xname_tl} + \tl_put_right:Nx\l_mix_iiidviewarray_tl{~\g_mix_pdflastobj_tl} + \tl_set:Nn\l_mix_level_tl{\c_minus_one} + } + + {1}{ %PART + \bool_if:NT\l_mix_blankndname_bool{ + \msg_error:nnxx{media9}{missing~part~name} + {\g_mix_vfile_tl}{\int_use:N\l_mix_partlineno_int} + } + + \mix_pdfobj:nnn{}{dict}{ + /Type/3DNode/N~\l_mix_ndname_tl + \l_mix_ndop_tl\l_mix_ndvi_tl\l_mix_ndrm_tl + \tl_if_blank:VF\l_mix_ndtrans_tl{ + /M~[\l_mix_ndtrans_tl] + } + } + + \tl_put_right:Nx\l_mix_naarray_tl{~\g_mix_pdflastobj_tl} + \tl_set:Nn\l_mix_level_tl{\c_zero} + } + {2}{ %CROSSSECT + \int_compare:nT{\l_mix_cscount_tl=\c_zero}{ + \mix_pdfobj:nnn{}{dict}{ + /Type/3DCrossSection + /C~[\l_mix_cscentre_tl] + /O~[\l_mix_csorient_tl] + /IV~true + } + \tl_put_right:Nx\l_mix_saarray_tl{~\g_mix_pdflastobj_tl} + \tl_set:Nn\l_mix_cscount_tl{\c_one} + } + \tl_set:Nn\l_mix_level_tl{\c_zero} + } + }{ + \msg_error:nnxx{media9}{no~end~here} + {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int} + } + }, + END .value_forbidden:, +} diff --git a/Master/texmf-dist/tex/latex/media9/players/APlayer.mxml b/Master/texmf-dist/tex/latex/media9/players/APlayer.mxml new file mode 100644 index 00000000000..67375fb6a06 --- /dev/null +++ b/Master/texmf-dist/tex/latex/media9/players/APlayer.mxml @@ -0,0 +1,143 @@ +<?xml version="1.0"?> +<!-- --> +<!-- Adobe Flex 4 source file of APlayer.swf, --> +<!-- a FlashPlayer-10 compatible component for playing --> +<!-- MP3 audio files and streams. --> +<!-- --> +<!-- version 20120301 --> +<!-- --> +<!-- --> +<!-- The free Adobe Flex 4 SDK is required to compile --> +<!-- this file. Get it from --> +<!-- --> +<!-- http://www.adobe.com/products/flex/ --> +<!-- --> +<!-- and run --> +<!-- --> +<!-- mxmlc -static-link-runtime-shared-libraries APlayer.mxml --> +<!-- --> +<!-- on the command line. --> +<!-- --> +<!-- --> +<!-- Copyright (C) 2012 Alexander Grahn --> +<!-- --> +<!-- This work may be distributed and/or modified under the --> +<!-- conditions of the LaTeX Project Public License, either --> +<!-- version 1.3 of this license or (at your option) any later --> +<!-- version. --> +<!-- --> +<!-- The latest version of this license is in --> +<!-- http://www.latex-project.org/lppl.txt --> +<!-- and version 1.3 or later is part of all distributions of --> +<!-- LaTeX version 2005/12/01 or later. --> +<!-- --> +<!-- This work has the LPPL maintenance status `maintained'. --> +<!-- --> +<!-- The current maintainer of this work is A. Grahn. --> +<!-- --> + +<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:s="library://ns.adobe.com/flex/spark" + xmlns:mx="library://ns.adobe.com/flex/mx" + preinitialize="initialise(FlexGlobals.topLevelApplication.parameters);" + applicationComplete="initSound();addEventListener(Event.ENTER_FRAME, onEnterFrame);" + mouseDown="pause();" + mouseUp="play();" +> + + <fx:Script> + <![CDATA[ + [Bindable] private var source:String; + [Bindable] private var autoPlay:Boolean=false; + [Bindable] private var loop:Boolean=false; + [Bindable] private var volume:Number=0.75; + [Bindable] private var balance:Number=0; + + private var snd:Sound; + private var sndCh:SoundChannel; + private var sndTr:SoundTransform; + private var playResumePosition:Number = 0; + private var playing:Boolean = false; + + import mx.core.FlexGlobals; + private function initialise(flashVars:Object):void{ + source=flashVars.source; + if(flashVars.autoPlay){autoPlay=(flashVars.autoPlay=='true')} + if(flashVars.loop){loop=(flashVars.loop=='true')} + if(flashVars.volume){volume=Number(flashVars.volume)} + if(flashVars.balance){balance=Number(flashVars.balance)} + } + + import mx.controls.Alert; + private function initSound():void + { + snd = new Sound(new URLRequest(source)); + sndTr = new SoundTransform(volume, balance); + + snd.addEventListener(IOErrorEvent.IO_ERROR, errorHandler); + snd.addEventListener(ProgressEvent.PROGRESS, progressHandler); + snd.addEventListener(Event.COMPLETE, completeHandler); + + if(autoPlay) play(); + } + + private function play():void + { + if (!playing) + { + try{sndCh = snd.play(playResumePosition, 0, sndTr);} + catch(err:Error){Alert.show(err.message,'Error');} + sndCh.addEventListener(Event.SOUND_COMPLETE, sndCompleteHandler); + playing = true; + } + } + + private function pause():void + { + if (playing) + { + playResumePosition = sndCh.position; + sndCh.stop(); + playing = false; + } + } + + private function sndCompleteHandler(event:Event):void + { + playing = false; + playResumePosition = 0; + if(loop) play(); + } + + private function completeHandler(event:Event):void + { + playProgress.indeterminate=false; + } + + import flash.events.ProgressEvent; + private function progressHandler(event:ProgressEvent):void{ + playProgress.indeterminate=true; + if(playing){ + playProgress.setProgress(0.5,1); + } + } + + private function onEnterFrame(event:Event):void{ + if(playProgress.indeterminate==false && playing){ + playProgress.setProgress(sndCh.position,snd.length); + } + } + + import flash.events.IOErrorEvent; + private function errorHandler(errorEvent:IOErrorEvent):void{ + Alert.show(errorEvent.text + '\ncould not be loaded','Error'); + } + + ]]> + </fx:Script> + + <mx:ProgressBar width="100%" mode="manual" + horizontalCenter="0" verticalCenter="0" labelPlacement="center" + label="" id="playProgress" + /> +</s:Application> diff --git a/Master/texmf-dist/tex/latex/media9/players/APlayer.swf b/Master/texmf-dist/tex/latex/media9/players/APlayer.swf Binary files differnew file mode 100644 index 00000000000..51f491dee5e --- /dev/null +++ b/Master/texmf-dist/tex/latex/media9/players/APlayer.swf diff --git a/Master/texmf-dist/tex/latex/media9/players/VPlayer.mxml b/Master/texmf-dist/tex/latex/media9/players/VPlayer.mxml new file mode 100644 index 00000000000..9d070ed2d40 --- /dev/null +++ b/Master/texmf-dist/tex/latex/media9/players/VPlayer.mxml @@ -0,0 +1,93 @@ +<?xml version="1.0"?> +<!-- --> +<!-- Adobe Flex 4 source file of VPlayer.swf, --> +<!-- a FlashPlayer-10 compatible component for playing --> +<!-- FLV and MP4/H.264 video files and streams. --> +<!-- --> +<!-- version 20120301 --> +<!-- --> +<!-- --> +<!-- The free Adobe Flex 4 SDK is required to compile --> +<!-- this file. Get it from --> +<!-- --> +<!-- http://www.adobe.com/products/flex/ --> +<!-- --> +<!-- and run --> +<!-- --> +<!-- mxmlc -static-link-runtime-shared-libraries VPlayer.mxml --> +<!-- --> +<!-- on the command line. --> +<!-- --> +<!-- --> +<!-- Copyright (C) 2011 Alexander Grahn --> +<!-- --> +<!-- This work may be distributed and/or modified under the --> +<!-- conditions of the LaTeX Project Public License, either --> +<!-- version 1.3 of this license or (at your option) any later --> +<!-- version. --> +<!-- --> +<!-- The latest version of this license is in --> +<!-- http://www.latex-project.org/lppl.txt --> +<!-- and version 1.3 or later is part of all distributions of --> +<!-- LaTeX version 2005/12/01 or later. --> +<!-- --> +<!-- This work has the LPPL maintenance status `maintained'. --> +<!-- --> +<!-- The current maintainer of this work is A. Grahn. --> +<!-- --> + +<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:s="library://ns.adobe.com/flex/spark" + xmlns:mx="library://ns.adobe.com/flex/mx" + preinitialize="initialise(FlexGlobals.topLevelApplication.parameters);" +> + <fx:Script> + <![CDATA[ + [Bindable] private var source:String; + [Bindable] private var autoPlay:Boolean=false; + [Bindable] private var loop:Boolean=false; + [Bindable] private var volume:Number=0.75; + private var vidComplete:Boolean=false; + + import mx.core.FlexGlobals; + private function initialise(flashVars:Object):void{ + source=flashVars.source; + if(flashVars.autoPlay){autoPlay=(flashVars.autoPlay=='true')} + if(flashVars.loop){loop=(flashVars.loop=='true')} + if(flashVars.volume){volume=Number(flashVars.volume)} + } + + import flash.events.ProgressEvent; + private function progressHandler(event:ProgressEvent):void{ + if (event.bytesTotal) event.target.visible=true; + else event.target.visible=false; + } + + import org.osmf.events.MediaPlayerStateChangeEvent; + import mx.controls.Alert; + private function stateChangeHandler(event:MediaPlayerStateChangeEvent):void{ + vidComplete=false; + if(event.state=='playbackError') + Alert.show('Unable to play \''+event.target.source+'\'','Error'); + } + ]]> + </fx:Script> + + <s:VideoDisplay + id="vidDisp" + width="100%" height="100%" scaleMode="stretch" + source="{source}" volume="{volume}" + autoPlay="{autoPlay}" autoRewind="false" loop="{loop}" + mouseDown="vidDisp.pause();" + mouseUp="if(vidComplete){vidDisp.seek(0);}vidDisp.play();" + mediaPlayerStateChange="stateChangeHandler(event);" + complete="vidComplete=true;" + /> + + <mx:ProgressBar width="80%" mode="polled" source="vidDisp" + horizontalCenter="0" verticalCenter="0" labelPlacement="center" + id="loadingProgress" alpha="0.5" + complete="loadingProgress.visible=false;" + progress="progressHandler(event)" + /> +</s:Application> diff --git a/Master/texmf-dist/tex/latex/media9/players/VPlayer.swf b/Master/texmf-dist/tex/latex/media9/players/VPlayer.swf Binary files differnew file mode 100644 index 00000000000..daf19dbc7fe --- /dev/null +++ b/Master/texmf-dist/tex/latex/media9/players/VPlayer.swf |