summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/glrender.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/glrender.cc')
-rw-r--r--Build/source/utils/asymptote/glrender.cc208
1 files changed, 130 insertions, 78 deletions
diff --git a/Build/source/utils/asymptote/glrender.cc b/Build/source/utils/asymptote/glrender.cc
index 38389284c78..ebb446c28da 100644
--- a/Build/source/utils/asymptote/glrender.cc
+++ b/Build/source/utils/asymptote/glrender.cc
@@ -53,12 +53,16 @@ using camp::bbox3;
using settings::getSetting;
using settings::Setting;
-const double moveFactor=1.0;
-const double zoomFactor=1.05;
-const double zoomFactorStep=0.1;
-const double spinStep=60.0; // Degrees per second
-const double arcballRadius=750.0;
-const double resizeStep=1.2;
+// For now, don't use POSIX timers by default due to portability issues.
+#ifdef HAVE_POSIX_TIMERS
+static timer_t timerid;
+static struct itimerspec Timeout;
+#else
+static struct itimerval Timeout;
+#endif
+
+static const double milliseconds=1000.0; // In microseconds.
+timeval lasttime;
double Aspect;
bool View;
@@ -120,7 +124,7 @@ bool antialias;
int x0,y0;
string Action;
-int MenuButton=0;
+int MenuButton;
double lastangle;
@@ -258,6 +262,7 @@ void setProjection()
else
glFrustum(xmin,xmax,ymin,ymax,-zmax,-zmin);
glMatrixMode(GL_MODELVIEW);
+ double arcballRadius=getSetting<double>("arcballradius");
arcball.set_params(vec2(0.5*Width,0.5*Height),arcballRadius*Zoom);
}
@@ -495,7 +500,6 @@ void togglefitscreen()
void updateHandler(int)
{
- initlighting();
update();
glutShowWindow();
glutShowWindow(); // Call twice to work around apparent freeglut bug.
@@ -529,11 +533,41 @@ void reshape(int width, int height)
reshape0(width,height);
}
+void initTimer()
+{
+ gettimeofday(&lasttime,NULL);
+}
+
+void idleFunc(void (*f)())
+{
+ initTimer();
+ glutIdleFunc(f);
+}
+
+void idle()
+{
+ glutIdleFunc(NULL);
+ Xspin=Yspin=Zspin=false;
+}
+
+void home()
+{
+ idle();
+ X=Y=cx=cy=0.0;
+ arcball.init();
+ glLoadIdentity();
+ glGetFloatv(GL_MODELVIEW_MATRIX,Rotate);
+ lastzoom=Zoom=Zoom0;
+ setDimensions(Width,Height,0,0);
+ initlighting();
+}
+
void quit()
{
if(glthread) {
+ home();
glutHideWindow();
-#ifdef HAVE_LIBPTHREAD
+ #ifdef HAVE_LIBPTHREAD
if(!interact::interactive)
endwait(readySignal,readyLock);
#endif
@@ -597,9 +631,8 @@ void capzoom()
void disableMenu()
{
- if(MenuButton)
- glutDetachMenu(MenuButton);
Menu=false;
+ glutDetachMenu(MenuButton);
}
void zoom(int x, int y)
@@ -612,30 +645,37 @@ void zoom(int x, int y)
return;
}
Motion=true;
- static const double limit=log(0.1*DBL_MAX)/log(zoomFactor);
- lastzoom=Zoom;
- double s=zoomFactorStep*(y0-y);
- if(fabs(s) < limit) {
- Zoom *= pow(zoomFactor,s);
- capzoom();
- y0=y;
- setProjection();
- glutPostRedisplay();
+ double zoomFactor=getSetting<double>("zoomfactor");
+ if(zoomFactor > 0.0) {
+ double zoomStep=getSetting<double>("zoomstep");
+ const double limit=log(0.1*DBL_MAX)/log(zoomFactor);
+ lastzoom=Zoom;
+ double s=zoomStep*(y0-y);
+ if(fabs(s) < limit) {
+ Zoom *= pow(zoomFactor,s);
+ capzoom();
+ y0=y;
+ setProjection();
+ glutPostRedisplay();
+ }
}
}
}
void mousewheel(int wheel, int direction, int x, int y)
{
- lastzoom=Zoom;
- if(direction > 0)
- Zoom *= zoomFactor;
- else
- Zoom /= zoomFactor;
-
- capzoom();
- setProjection();
- glutPostRedisplay();
+ double zoomFactor=getSetting<double>("zoomfactor");
+ if(zoomFactor > 0.0) {
+ lastzoom=Zoom;
+ if(direction > 0)
+ Zoom *= zoomFactor;
+ else
+ Zoom /= zoomFactor;
+
+ capzoom();
+ setProjection();
+ glutPostRedisplay();
+ }
}
void rotate(int x, int y)
@@ -677,7 +717,7 @@ void updateArcball()
}
update();
}
-
+
void rotateX(double step)
{
glLoadIdentity();
@@ -786,9 +826,45 @@ string action(int button, int mod)
return "";
}
+void timeout(int)
+{
+ if(Menu) disableMenu();
+}
+
+void init_timeout()
+{
+ static struct sigaction action;
+ action.sa_handler=timeout;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags=0;
+ sigaction(SIGALRM,&action,NULL);
+
+ Timeout.it_value.tv_sec=Timeout.it_interval.tv_sec=0;
+#ifdef HAVE_POSIX_TIMERS
+ timer_create (CLOCK_REALTIME,NULL,&timerid);
+ Timeout.it_interval.tv_nsec=0;
+#else
+ Timeout.it_interval.tv_usec=0;
+#endif
+}
+
+void set_timeout(int microseconds)
+{
+ if(microseconds >= 0) {
+#ifdef HAVE_POSIX_TIMERS
+ Timeout.it_value.tv_nsec=1000*microseconds;
+ timer_settime(timerid,0,&Timeout,NULL);
+#else
+ Timeout.it_value.tv_usec=microseconds;
+ setitimer(ITIMER_REAL,&Timeout,NULL);
+#endif
+ }
+}
+
void mouse(int button, int state, int x, int y)
{
- string Action=action(button,glutGetModifiers());
+ int mod=glutGetModifiers();
+ string Action=action(button,mod);
if(Action == "zoomin") {
glutMotionFunc(NULL);
@@ -801,12 +877,13 @@ void mouse(int button, int state, int x, int y)
return;
}
- if(Action == "zoom/menu") {
+ if(Action == "zoom/menu" && mod == 0) {
if(state == GLUT_UP && !Motion) {
MenuButton=button;
glutMotionFunc(NULL);
glutAttachMenu(button);
Menu=true;
+ set_timeout((int) (getSetting<double>("doubleclick")*milliseconds));
return;
}
}
@@ -837,14 +914,13 @@ void mouse(int button, int state, int x, int y)
}
}
-timeval lasttime;
-
double spinstep()
{
timeval tv;
gettimeofday(&tv,NULL);
- double step=spinStep*(tv.tv_sec-lasttime.tv_sec+
- ((double) tv.tv_usec-lasttime.tv_usec)/1000000.0);
+ double step=getSetting<double>("spinstep")*
+ (tv.tv_sec-lasttime.tv_sec+
+ ((double) tv.tv_usec-lasttime.tv_usec)/1000000.0);
lasttime=tv;
return step;
}
@@ -864,26 +940,19 @@ void zspin()
rotateZ(spinstep());
}
-void initTimer()
-{
- gettimeofday(&lasttime,NULL);
-}
-
void expand()
{
- setsize((int) (Width*resizeStep+0.5),(int) (Height*resizeStep+0.5));
+ double resizeStep=getSetting<double>("resizestep");
+ if(resizeStep > 0.0)
+ setsize((int) (Width*resizeStep+0.5),(int) (Height*resizeStep+0.5));
}
void shrink()
{
- setsize(max((int) (Width/resizeStep+0.5),1),
- max((int) (Height/resizeStep+0.5),1));
-}
-
-void idleFunc(void (*f)())
-{
- initTimer();
- glutIdleFunc(f);
+ double resizeStep=getSetting<double>("resizestep");
+ if(resizeStep > 0.0)
+ setsize(max((int) (Width/resizeStep+0.5),1),
+ max((int) (Height/resizeStep+0.5),1));
}
void mode()
@@ -911,12 +980,6 @@ void mode()
glutPostRedisplay();
}
-void idle()
-{
- glutIdleFunc(NULL);
- Xspin=Yspin=Zspin=false;
-}
-
void spinx()
{
if(Xspin)
@@ -950,17 +1013,6 @@ void spinz()
}
}
-void home()
-{
- idle();
- X=Y=cx=cy=0.0;
- arcball.init();
- glLoadIdentity();
- glGetFloatv(GL_MODELVIEW_MATRIX,Rotate);
- lastzoom=Zoom=Zoom0;
- setDimensions(Width,Height,0,0);
-}
-
void write(const char *text, const double *v)
{
cout << text << "=(" << v[0] << "," << v[1] << "," << v[2] << ")";
@@ -998,7 +1050,8 @@ void camera()
pair viewportshift(X/Width*lastzoom+Shift.getx(),
Y/Height*lastzoom+Shift.gety());
- cout << "currentprojection="
+ cout << endl
+ << "currentprojection="
<< (orthographic ? "orthographic(" : "perspective(") << endl
<< "camera=" << Camera << "," << endl
<< "up=" << Up << "," << endl
@@ -1011,7 +1064,7 @@ void camera()
cout << "," << endl << "viewportshift=" << viewportshift;
if(!orthographic)
cout << "," << endl << "autoadjust=false";
- cout << ");" << endl << endl;
+ cout << ");" << endl;
}
void keyboard(unsigned char key, int x, int y)
@@ -1067,7 +1120,8 @@ enum Menu {HOME,FITSCREEN,XSPIN,YSPIN,ZSPIN,STOP,MODE,EXPORT,CAMERA,QUIT};
void menu(int choice)
{
- disableMenu();
+ set_timeout(0);
+ if(Menu) disableMenu();
ignorezoom=true;
Motion=true;
switch (choice) {
@@ -1126,6 +1180,7 @@ void init()
screenWidth=glutGet(GLUT_SCREEN_WIDTH);
screenHeight=glutGet(GLUT_SCREEN_HEIGHT);
+ init_timeout();
}
// angle=0 means orthographic.
@@ -1240,10 +1295,8 @@ void glrender(const string& prefix, const picture *pic, const string& format,
#ifdef HAVE_LIBPTHREAD
if(glthread && initializedView) {
- if(!View) {
+ if(!View)
readyAfterExport=queueExport=true;
- }
-
pthread_kill(mainthread,SIGUSR1);
return;
}
@@ -1284,16 +1337,16 @@ void glrender(const string& prefix, const picture *pic, const string& format,
string suffix;
for(size_t i=0; i < nbuttons; ++i) {
int button=buttons[i];
- if(action(button,0) == "menu") {
- suffix="Click "+buttonnames[i]+" button for menu";
+ if(action(button,0) == "zoom/menu") {
+ suffix="Double 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";
+ if(action(button,0) == "menu") {
+ suffix="Click "+buttonnames[i]+" button for menu";
break;
}
}
@@ -1367,7 +1420,6 @@ void glrender(const string& prefix, const picture *pic, const string& format,
gluNurbsCallback(nurb,GLU_NURBS_COLOR,(_GLUfuncptr) glColor4fv);
mode();
- initlighting();
if(View) {
initializedView=true;
glutReshapeFunc(reshape);