summaryrefslogtreecommitdiff
path: root/Master/texmf/asymptote/plain_picture.asy
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf/asymptote/plain_picture.asy')
-rw-r--r--Master/texmf/asymptote/plain_picture.asy106
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