summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/glrender.cc
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-07-03 00:02:22 +0000
committerKarl Berry <karl@freefriends.org>2009-07-03 00:02:22 +0000
commitc20b61928150008d080bab09e967fcaebc93da81 (patch)
treebffa7c8765003c0e8f2a40c72479e5caa6f748bd /Build/source/utils/asymptote/glrender.cc
parent9ec802a431dfe1b27063bac2f8dd9bc58cf997b0 (diff)
asy 1.79
git-svn-id: svn://tug.org/texlive/trunk@14078 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/glrender.cc')
-rw-r--r--Build/source/utils/asymptote/glrender.cc188
1 files changed, 137 insertions, 51 deletions
diff --git a/Build/source/utils/asymptote/glrender.cc b/Build/source/utils/asymptote/glrender.cc
index 8dec9d0405c..38389284c78 100644
--- a/Build/source/utils/asymptote/glrender.cc
+++ b/Build/source/utils/asymptote/glrender.cc
@@ -87,6 +87,8 @@ bool ignorezoom;
int Fitscreen;
int Mode;
+double Angle;
+bool orthographic;
double H;
double xmin,xmax;
double ymin,ymax;
@@ -94,7 +96,11 @@ double zmin,zmax;
double Xmin,Xmax;
double Ymin,Ymax;
+
+pair Shift;
double X,Y;
+double cx,cy;
+double Xfactor,Yfactor;
int minimumsize=50; // Minimum initial rendering window width and height
@@ -109,6 +115,7 @@ double *Ambient;
double *Specular;
bool ViewportLighting;
bool queueExport=false;
+bool readyAfterExport=false;
bool antialias;
int x0,y0;
@@ -118,6 +125,7 @@ int MenuButton=0;
double lastangle;
double Zoom;
+double Zoom0;
double lastzoom;
GLfloat Rotate[16];
@@ -212,26 +220,27 @@ void initlighting()
void setDimensions(int Width, int Height, double X, double Y)
{
double Aspect=((double) Width)/Height;
- double X0=X*(xmax-xmin)/(lastzoom*Width);
- double Y0=Y*(ymax-ymin)/(lastzoom*Height);
- if(H == 0.0) {
+ double X0=(X/Width*lastzoom+Shift.getx()*Xfactor)*(xmax-xmin);
+ double Y0=(Y/Height*lastzoom+Shift.gety()*Yfactor)*(ymax-ymin);
+ double Zoominv=1.0/Zoom;
+ if(orthographic) {
double xsize=Xmax-Xmin;
double ysize=Ymax-Ymin;
if(xsize < ysize*Aspect) {
- double r=0.5*ysize*Zoom*Aspect;
+ double r=0.5*ysize*Aspect*Zoominv;
xmin=-r-X0;
xmax=r-X0;
- ymin=Ymin*Zoom-Y0;
- ymax=Ymax*Zoom-Y0;
+ ymin=Ymin*Zoominv-Y0;
+ ymax=Ymax*Zoominv-Y0;
} else {
- double r=0.5*xsize*Zoom/Aspect;
- xmin=Xmin*Zoom-X0;
- xmax=Xmax*Zoom-X0;
+ double r=0.5*xsize/(Aspect*Zoom);
+ xmin=Xmin*Zoominv-X0;
+ xmax=Xmax*Zoominv-X0;
ymin=-r-Y0;
ymax=r-Y0;
}
} else {
- double r=H*Zoom;
+ double r=H*Zoominv;
xmin=-r*Aspect-X0;
xmax=r*Aspect-X0;
ymin=-r-Y0;
@@ -244,12 +253,12 @@ void setProjection()
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
setDimensions(Width,Height,X,Y);
- if(H == 0.0)
+ if(orthographic)
glOrtho(xmin,xmax,ymin,ymax,-zmax,-zmin);
else
glFrustum(xmin,xmax,ymin,ymax,-zmax,-zmin);
glMatrixMode(GL_MODELVIEW);
- arcball.set_params(vec2(0.5*Width,0.5*Height),arcballRadius/Zoom);
+ arcball.set_params(vec2(0.5*Width,0.5*Height),arcballRadius*Zoom);
}
bool capsize(int& width, int& height)
@@ -268,8 +277,8 @@ bool capsize(int& width, int& height)
void reshape0(int width, int height)
{
- X=X/Width*width;
- Y=Y/Height*height;
+ X=(X/Width)*width;
+ Y=(Y/Height)*height;
Width=width;
Height=height;
@@ -283,7 +292,7 @@ void update()
lastzoom=Zoom;
glLoadIdentity();
double cz=0.5*(zmin+zmax);
- glTranslatef(0,0,cz);
+ glTranslatef(cx,cy,cz);
glMultMatrixf(Rotate);
glTranslatef(0,0,-cz);
setProjection();
@@ -307,7 +316,7 @@ void drawscene(double Width, double Height)
triple m(xmin,ymin,zmin);
triple M(xmax,ymax,zmax);
- double perspective=H == 0.0 ? 0.0 : 1.0/zmax;
+ double perspective=orthographic ? 0.0 : 1.0/zmax;
double size2=hypot(Width,Height);
@@ -354,10 +363,7 @@ void Export()
trImageBuffer(tr,GL_RGB,GL_UNSIGNED_BYTE,data);
setDimensions(fullWidth,fullHeight,X/Width*fullWidth,Y/Width*fullWidth);
- if(H == 0.0)
- trOrtho(tr,xmin,xmax,ymin,ymax,-zmax,-zmin);
- else
- trFrustum(tr,xmin,xmax,ymin,ymax,-zmax,-zmin);
+ (orthographic ? trOrtho : trFrustum)(tr,xmin,xmax,ymin,ymax,-zmax,-zmin);
size_t count=0;
do {
@@ -388,10 +394,12 @@ void Export()
outOfMemory();
}
setProjection();
-
+
#ifdef HAVE_LIBPTHREAD
- if(glthread)
+ if(glthread && readyAfterExport) {
endwait(readySignal,readyLock);
+ readyAfterExport=false;
+ }
#endif
}
@@ -438,12 +446,12 @@ void fullscreen()
{
Width=screenWidth;
Height=screenHeight;
+ reshape0(Width,Height);
#ifdef __CYGWIN__
glutFullScreen();
#else
glutPositionWindow(0,0);
glutReshapeWindow(Width,Height);
- reshape0(Width,Height);
glutPostRedisplay();
#endif
}
@@ -453,6 +461,7 @@ void fitscreen()
switch(Fitscreen) {
case 0: // Original size
{
+ Xfactor=Yfactor=1.0;
setsize(oldWidth,oldHeight,minimumsize);
break;
}
@@ -469,6 +478,8 @@ void fitscreen()
}
case 2: // Full screen
{
+ Xfactor=((double) screenHeight)/Height;
+ Yfactor=((double) screenWidth)/Width;
fullscreen();
break;
}
@@ -492,10 +503,11 @@ void updateHandler(int)
fitscreen();
}
-void exportHandler(int)
+void autoExport()
{
if(!Iconify)
glutShowWindow();
+ readyAfterExport=true;
Export();
if(!Iconify)
glutHideWindow();
@@ -508,7 +520,6 @@ void reshape(int width, int height)
if(initialize) {
initialize=false;
signal(SIGUSR1,updateHandler);
- signal(SIGUSR2,exportHandler);
}
}
@@ -548,11 +559,28 @@ void display()
}
}
-void move(int x, int y)
+void shift(int x, int y)
{
if(x > 0 && y > 0) {
- X += (x-x0)*Zoom;
- Y += (y0-y)*Zoom;
+ double Zoominv=1.0/Zoom;
+ X += (x-x0)*Zoominv;
+ Y += (y0-y)*Zoominv;
+ x0=x; y0=y;
+ update();
+ }
+}
+
+void pan(int x, int y)
+{
+ if(x > 0 && y > 0) {
+ if(orthographic) {
+ double Zoominv=1.0/Zoom;
+ X += (x-x0)*Zoominv;
+ Y += (y0-y)*Zoominv;
+ } else {
+ cx += (x-x0)*(xmax-xmin)/Width;
+ cy += (y0-y)*(ymax-ymin)/Height;
+ }
x0=x; y0=y;
update();
}
@@ -586,7 +614,7 @@ void zoom(int x, int y)
Motion=true;
static const double limit=log(0.1*DBL_MAX)/log(zoomFactor);
lastzoom=Zoom;
- double s=zoomFactorStep*(y-y0);
+ double s=zoomFactorStep*(y0-y);
if(fabs(s) < limit) {
Zoom *= pow(zoomFactor,s);
capzoom();
@@ -601,9 +629,9 @@ void mousewheel(int wheel, int direction, int x, int y)
{
lastzoom=Zoom;
if(direction > 0)
- Zoom /= zoomFactor;
- else
Zoom *= zoomFactor;
+ else
+ Zoom /= zoomFactor;
capzoom();
setProjection();
@@ -752,7 +780,7 @@ string action(int button, int mod)
array *Buttons[]={left,middle,right,wheelup,wheeldown};
array *a=Buttons[button];
size_t size=checkArray(a);
- if(Mod >= 0 && Mod < (Int) size)
+ if(Mod >= 0 && Mod < size)
return read<string>(a,Mod);
}
return "";
@@ -763,10 +791,12 @@ void mouse(int button, int state, int x, int y)
string Action=action(button,glutGetModifiers());
if(Action == "zoomin") {
+ glutMotionFunc(NULL);
mousewheel(0,1,x,y);
return;
}
if(Action == "zoomout") {
+ glutMotionFunc(NULL);
mousewheel(0,-1,x,y);
return;
}
@@ -774,6 +804,7 @@ void mouse(int button, int state, int x, int y)
if(Action == "zoom/menu") {
if(state == GLUT_UP && !Motion) {
MenuButton=button;
+ glutMotionFunc(NULL);
glutAttachMenu(button);
Menu=true;
return;
@@ -789,7 +820,10 @@ void mouse(int button, int state, int x, int y)
glutMotionFunc(rotate);
} else if(Action == "shift") {
x0=x; y0=y;
- glutMotionFunc(move);
+ glutMotionFunc(shift);
+ } else if(Action == "pan") {
+ x0=x; y0=y;
+ glutMotionFunc(pan);
} else if(Action == "zoom" || Action == "zoom/menu") {
y0=y;
glutMotionFunc(zoom);
@@ -797,8 +831,10 @@ void mouse(int button, int state, int x, int y)
lastangle=Degrees(x,y);
glutMotionFunc(rotateZ);
}
- } else
+ } else {
arcball.mouse_up();
+ glutMotionFunc(NULL);
+ }
}
timeval lasttime;
@@ -917,11 +953,12 @@ void spinz()
void home()
{
idle();
- X=Y=0.0;
+ X=Y=cx=cy=0.0;
arcball.init();
glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX,Rotate);
- lastzoom=Zoom=1.0;
+ lastzoom=Zoom=Zoom0;
+ setDimensions(Width,Height,0,0);
}
void write(const char *text, const double *v)
@@ -931,18 +968,26 @@ void write(const char *text, const double *v)
void camera()
{
- double cz=0.5*(zmin+zmax);
camp::Triple vCamera,vTarget,vUp;
+ double cz=0.5*(zmin+zmax);
+
for(int i=0; i < 3; ++i) {
double sumCamera=0.0, sumTarget=0.0, sumUp=0.0;
+ int i4=4*i;
for(int j=0; j < 4; ++j) {
- sumCamera += T[4*i+j]*(Rotate[4*j+3]-cz*Rotate[4*j+2]);
- sumUp += T[4*i+j]*(Rotate[4*j+3]+Rotate[4*j+1]);
- sumTarget += T[4*i+j]*Rotate[4*j+3];
+ int j4=4*j;
+ double R0=Rotate[j4];
+ double R1=Rotate[j4+1];
+ double R2=Rotate[j4+2];
+ double R3=Rotate[j4+3];
+ double T4ij=T[i4+j];
+ sumCamera += T4ij*(R3-cx*R0-cy*R1-cz*R2);
+ sumUp += T4ij*R1;
+ sumTarget += T4ij*(R3-cx*R0-cy*R1);
}
vCamera[i]=sumCamera;
- vUp[i]=sumUp-sumTarget;
+ vUp[i]=sumUp;
vTarget[i]=sumTarget;
}
@@ -950,9 +995,23 @@ void camera()
triple Up=triple(vUp);
triple Target=triple(vTarget);
- cout << "camera=" << Camera << "," << endl
+ pair viewportshift(X/Width*lastzoom+Shift.getx(),
+ Y/Height*lastzoom+Shift.gety());
+
+ cout << "currentprojection="
+ << (orthographic ? "orthographic(" : "perspective(") << endl
+ << "camera=" << Camera << "," << endl
<< "up=" << Up << "," << endl
- << "target=" << Target << endl << endl;
+ << "target=" << Target << "," << endl;
+ if(orthographic)
+ cout << "zoom=" << Zoom;
+ else
+ cout << "angle=" << 2.0*atan(tan(0.5*Angle)/Zoom)/radians;
+ if(viewportshift != pair(0.0,0.0))
+ cout << "," << endl << "viewportshift=" << viewportshift;
+ if(!orthographic)
+ cout << "," << endl << "autoadjust=false";
+ cout << ");" << endl << endl;
}
void keyboard(unsigned char key, int x, int y)
@@ -988,10 +1047,12 @@ void keyboard(unsigned char key, int x, int y)
break;
case '+':
case '=':
+ case '>':
expand();
break;
case '-':
case '_':
+ case '<':
shrink();
break;
case 17: // Ctrl-q
@@ -1069,8 +1130,8 @@ void init()
// angle=0 means orthographic.
void glrender(const string& prefix, const picture *pic, const string& format,
- double width, double height,
- double angle, const triple& m, const triple& M, double *t,
+ double width, double height, double angle, double zoom,
+ const triple& m, const triple& M, const pair& shift, double *t,
double *background, size_t nlights, triple *lights,
double *diffuse, double *ambient, double *specular,
bool Viewportlighting, bool view, int oldpid)
@@ -1084,6 +1145,8 @@ void glrender(const string& prefix, const picture *pic, const string& format,
static bool initializedView=false;
+ if(zoom == 0.0) zoom=1.0;
+
Prefix=prefix;
Picture=pic;
Format=format;
@@ -1096,7 +1159,10 @@ void glrender(const string& prefix, const picture *pic, const string& format,
Specular=specular;
ViewportLighting=Viewportlighting;
View=view;
+ Angle=angle*radians;
+ Zoom0=zoom;
Oldpid=oldpid;
+ Shift=shift;
Xmin=m.getx();
Xmax=M.getx();
@@ -1104,12 +1170,15 @@ void glrender(const string& prefix, const picture *pic, const string& format,
Ymax=M.gety();
zmin=m.getz();
zmax=M.getz();
- H=angle != 0.0 ? -tan(0.5*angle*radians)*zmax : 0.0;
-
+
+ orthographic=Angle == 0.0;
+ H=orthographic ? 0.0 : -tan(0.5*Angle)*zmax;
+
Menu=false;
Motion=true;
ignorezoom=false;
Mode=0;
+ Xfactor=Yfactor=1.0;
static bool initialize=true;
@@ -1171,7 +1240,10 @@ void glrender(const string& prefix, const picture *pic, const string& format,
#ifdef HAVE_LIBPTHREAD
if(glthread && initializedView) {
- if(!View) queueExport=true;
+ if(!View) {
+ readyAfterExport=queueExport=true;
+ }
+
pthread_kill(mainthread,SIGUSR1);
return;
}
@@ -1209,11 +1281,25 @@ void glrender(const string& prefix, const picture *pic, const string& format,
#endif
#endif
string title=string(settings::PROGRAM)+": "+prefix;
+ string suffix;
for(size_t i=0; i < nbuttons; ++i) {
int button=buttons[i];
- if(action(button,0) == "zoom/menu")
- title += " [Double click "+buttonnames[i]+" button for menu]";
+ if(action(button,0) == "menu") {
+ suffix="Click "+buttonnames[i]+" button for menu";
+ break;
+ }
+ }
+ if(suffix.empty()) {
+ for(size_t i=0; i < nbuttons; ++i) {
+ int button=buttons[i];
+ if(action(button,0) == "zoom/menu") {
+ suffix="Double click "+buttonnames[i]+" button for menu";
+ break;
+ }
+ }
}
+
+ title += " ["+suffix+"]";
window=glutCreateWindow(title.c_str());
GLint samplebuf[1];
@@ -1309,7 +1395,7 @@ void glrender(const string& prefix, const picture *pic, const string& format,
glutMainLoop();
} else {
- exportHandler(0);
+ autoExport();
if(!glthread) quit();
}
}