diff options
Diffstat (limited to 'Master/texmf/asymptote/plain_picture.asy')
-rw-r--r-- | Master/texmf/asymptote/plain_picture.asy | 106 |
1 files changed, 88 insertions, 18 deletions
diff --git a/Master/texmf/asymptote/plain_picture.asy b/Master/texmf/asymptote/plain_picture.asy index b3836d7ef51..432a4a6ae6d 100644 --- a/Master/texmf/asymptote/plain_picture.asy +++ b/Master/texmf/asymptote/plain_picture.asy @@ -401,10 +401,18 @@ struct transformation { transform3 compute() { return projection*modelview; } + transformation copy() { + transformation T=new transformation; + T.modelview=copy(modelview); + T.projection=copy(projection); + T.infinity=infinity; + T.oblique=oblique; + return T; + } } struct projection { - transform3 t; // projection*modelview (cached) + transform3 t; // projection*modelview (cached) bool infinity; bool oblique; bool absolute=false; @@ -420,21 +428,16 @@ struct projection { bool autoadjust=true; // Adjust camera to lie outside bounding volume? bool center=false; // Center target within bounding volume? int ninterpolate; // Used for projecting nurbs to 2D Bezier curves. + transformation T; void calculate() { - transformation T=projector(camera,up,target); + T=projector(camera,up,target); t=T.compute(); infinity=T.infinity; oblique=T.oblique; ninterpolate=infinity ? 1 : 16; } - transformation transformation() { - return projector(camera,up,target); - } - - transform3 modelview() {return transformation().modelview;} - triple vector() { return camera-target; } @@ -473,6 +476,7 @@ struct projection { P.center=center; P.projector=projector; P.ninterpolate=ninterpolate; + P.T=T.copy(); return P; } @@ -500,6 +504,71 @@ struct projection { projection currentprojection; +struct light { + real[][] diffuse; + real[][] ambient; + real[][] specular; + pen background=nullpen; // Background color of the 3D canvas. + real specularfactor; + bool viewport; // Are the lights specified (and fixed) in the viewport frame? + triple[] position; // Only directional lights are currently implemented. + + transform3 T=identity(4); // Transform to apply to normal vectors. + + bool on() {return position.length > 0;} + + void operator init(pen[] diffuse, + pen[] ambient=array(diffuse.length,black), + pen[] specular=diffuse, pen background=nullpen, + real specularfactor=1, + bool viewport=false, triple[] position) { + int n=diffuse.length; + assert(ambient.length == n && specular.length == n && position.length == n); + + this.diffuse=new real[n][]; + this.ambient=new real[n][]; + this.specular=new real[n][]; + this.background=background; + this.position=new triple[n]; + for(int i=0; i < position.length; ++i) { + this.diffuse[i]=rgba(diffuse[i]); + this.ambient[i]=rgba(ambient[i]); + this.specular[i]=rgba(specular[i]); + this.position[i]=unit(position[i]); + } + this.specularfactor=specularfactor; + this.viewport=viewport; + } + + void operator init(pen diffuse=white, pen ambient=black, pen specular=diffuse, + pen background=nullpen, real specularfactor=1, + bool viewport=false...triple[] position) { + int n=position.length; + operator init(array(n,diffuse),array(n,ambient),array(n,specular), + background,specularfactor,viewport,position); + } + + void operator init(pen diffuse=white, pen ambient=black, pen specular=diffuse, + pen background=nullpen, bool viewport=false, + real x, real y, real z) { + operator init(diffuse,ambient,specular,background,viewport,(x,y,z)); + } + + void operator init(explicit light light) { + diffuse=copy(light.diffuse); + ambient=copy(light.ambient); + specular=copy(light.specular); + background=light.background; + specularfactor=light.specularfactor; + viewport=light.viewport; + position=copy(light.position); + } + + real[] background() {return rgba(background == nullpen ? white : background);} +} + +light currentlight; + triple min3(pen p) { return linewidth(p)*(-0.5,-0.5,-0.5); @@ -990,7 +1059,7 @@ struct picture { if(status == simplex.problem.OPTIMAL) { return scaling.build(p.a(),p.b()).a; } else if(status == simplex.problem.UNBOUNDED) { - if(warn) write("warning: "+dir+" scaling in picture unbounded"); + if(warn) warning("unbounded",dir+" scaling in picture unbounded"); return 0; } else { if(!warn) return 1; @@ -1001,8 +1070,8 @@ struct picture { abort("unbounded picture"); } if(userzero) return 1; - write("warning: cannot fit picture to "+dir+"size "+(string) size - +"...enlarging..."); + warning("cannotfit","cannot fit picture to "+dir+"size "+(string) size + +"...enlarging..."); return calculateScaling(dir,coords,sqrt(2)*size,warn); } } @@ -1184,11 +1253,11 @@ struct picture { pair d=size(f); static real epsilon=100*realEpsilon; if(d.x > xsize*(1+epsilon)) - write("warning: frame exceeds xlimit: "+(string) d.x+" > "+ - (string) xsize); + warning("xlimit","frame exceeds xlimit: "+(string) d.x+" > "+ + (string) xsize); if(d.y > ysize*(1+epsilon)) - write("warning: frame exceeds ylimit: "+(string) d.y+" > "+ - (string) ysize); + warning("ylimit","frame exceeds ylimit: "+(string) d.y+" > "+ + (string) ysize); return f; } @@ -1290,14 +1359,15 @@ struct picture { } static frame fitter(string,picture,string,real,real,bool,bool,string,string, - projection); + light,projection); frame fit(string prefix="", string format="", real xsize=this.xsize, real ysize=this.ysize, bool keepAspect=this.keepAspect, bool view=false, - string options="", string script="", + string options="", string script="", light light=currentlight, projection P=currentprojection) { return fitter == null ? fit2(xsize,ysize,keepAspect) : - fitter(prefix,this,format,xsize,ysize,keepAspect,view,options,script,P); + fitter(prefix,this,format,xsize,ysize,keepAspect,view,options,script, + light,P); } // In case only an approximate picture size estimate is available, return the |