goat3d
diff goatview/src/goatview.cc @ 90:8b156bc5205b
[maxgoat] fixed the transform export bug
[goatview] added widgets for the animation controls
[goatview] added a grid ground plane with automatic sizing and transitions from size to size
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 17 May 2014 06:26:24 +0300 |
parents | 7941e89798e5 |
children | ae6c5941faac |
line diff
1.1 --- a/goatview/src/goatview.cc Fri May 16 05:23:10 2014 +0300 1.2 +++ b/goatview/src/goatview.cc Sat May 17 06:26:24 2014 +0300 1.3 @@ -6,22 +6,27 @@ 1.4 #include "goatview.h" 1.5 #include "goat3d.h" 1.6 1.7 +static void draw_grid(); 1.8 +static void draw_grid(float sz, int nlines, float alpha = 1.0f); 1.9 static void draw_node(goat3d_node *node); 1.10 static void draw_mesh(goat3d_mesh *mesh); 1.11 +static int next_pow2(int x); 1.12 1.13 goat3d *scene; 1.14 static SceneModel *sdata; 1.15 static GoatViewport *glview; 1.16 1.17 static long anim_time; 1.18 -static float cam_theta, cam_phi, cam_dist = 8; 1.19 +static float cam_theta, cam_phi = 25, cam_dist = 8; 1.20 static float fov = 60.0; 1.21 static bool use_nodes = true; 1.22 static bool use_lighting = true; 1.23 1.24 void post_redisplay() 1.25 { 1.26 - glview->updateGL(); 1.27 + if(glview) { 1.28 + glview->updateGL(); 1.29 + } 1.30 } 1.31 1.32 1.33 @@ -101,7 +106,7 @@ 1.34 1.35 QAction *act_quit = new QAction("&Quit", this); 1.36 act_quit->setShortcuts(QKeySequence::Quit); 1.37 - connect(act_quit, &QAction::triggered, [&](){qApp->quit();}); 1.38 + connect(act_quit, &QAction::triggered, [&](){ qApp->quit(); }); 1.39 menu_file->addAction(act_quit); 1.40 1.41 // view menu 1.42 @@ -136,7 +141,7 @@ 1.43 QVBoxLayout *dock_vbox = new QVBoxLayout; 1.44 dock_cont->setLayout(dock_vbox); 1.45 1.46 - QDockWidget *dock = new QDockWidget("Scene graph", this); 1.47 + QDockWidget *dock = new QDockWidget(this); 1.48 dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); 1.49 dock->setWidget(dock_cont); 1.50 addDockWidget(Qt::LeftDockWidgetArea, dock); 1.51 @@ -164,11 +169,37 @@ 1.52 QHBoxLayout *dock_hbox = new QHBoxLayout; 1.53 dock_cont->setLayout(dock_hbox); 1.54 1.55 - QSlider *slider_time = new QSlider(Qt::Orientation::Horizontal); 1.56 + // animation control box 1.57 + QGridLayout *anim_ctl_box = new QGridLayout; 1.58 + dock_hbox->addLayout(anim_ctl_box); 1.59 + 1.60 + anim_ctl_box->addWidget(new QLabel("Animation"), 0, 0); 1.61 + cbox_anims = new QComboBox; 1.62 + cbox_anims->setDisabled(true); 1.63 + anim_ctl_box->addWidget(cbox_anims, 0, 1); 1.64 + 1.65 + chk_loop = new QCheckBox("loop"); 1.66 + chk_loop->setChecked(false); 1.67 + anim_ctl_box->addWidget(chk_loop, 1, 0); 1.68 + 1.69 + QToolBar *toolbar_ctl = new QToolBar; 1.70 + anim_ctl_box->addWidget(toolbar_ctl, 1, 1); 1.71 + 1.72 + act_rewind = new QAction(style()->standardIcon(QStyle::SP_MediaSkipBackward), "Rewind", this); 1.73 + act_rewind->setDisabled(true); 1.74 + toolbar_ctl->addAction(act_rewind); 1.75 + act_play = new QAction(style()->standardIcon(QStyle::SP_MediaPlay), "Play", this); 1.76 + act_play->setDisabled(true); 1.77 + toolbar_ctl->addAction(act_play); 1.78 + 1.79 + // timeline slider 1.80 + slider_time = new QSlider(Qt::Orientation::Horizontal); 1.81 slider_time->setDisabled(true); 1.82 + connect(slider_time, &QSlider::valueChanged, 1.83 + [&](){ anim_time = slider_time->value(); post_redisplay(); }); 1.84 dock_hbox->addWidget(slider_time); 1.85 1.86 - dock = new QDockWidget("Animation", this); 1.87 + dock = new QDockWidget(this); 1.88 dock->setAllowedAreas(Qt::BottomDockWidgetArea); 1.89 dock->setWidget(dock_cont); 1.90 addDockWidget(Qt::BottomDockWidgetArea, dock); 1.91 @@ -270,6 +301,8 @@ 1.92 glRotatef(cam_phi, 1, 0, 0); 1.93 glRotatef(cam_theta, 0, 1, 0); 1.94 1.95 + draw_grid(); 1.96 + 1.97 if(!scene) return; 1.98 1.99 if(use_nodes) { 1.100 @@ -304,6 +337,63 @@ 1.101 #error "GLEW_ARB_transpose_matrix undefined?" 1.102 #endif 1.103 1.104 +static void draw_grid() 1.105 +{ 1.106 + float viewsz_orig = cam_dist * tan(DEG_TO_RAD(fov) / 2.0); 1.107 + float sz1 = next_pow2((int)viewsz_orig); 1.108 + float sz0 = sz1 / 2.0; 1.109 + float t = (viewsz_orig - sz0) / (sz1 - sz0); 1.110 + float alpha = t < 0.333333 ? 0.0 : (t > 0.666666 ? 1.0 : (t - 0.333333) / 0.333333); 1.111 + 1.112 + glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BITS); 1.113 + 1.114 + glEnable(GL_BLEND); 1.115 + glDepthFunc(GL_ALWAYS); 1.116 + 1.117 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1.118 + draw_grid(sz0 * 2.0, 10, 1.0 - alpha); 1.119 + draw_grid(sz1 * 2.0, 10, alpha); 1.120 + 1.121 + glPopAttrib(); 1.122 +} 1.123 + 1.124 +static void draw_grid(float sz, int nlines, float alpha) 1.125 +{ 1.126 + float hsz = sz / 2.0; 1.127 + float offs = sz / (float)nlines; 1.128 + 1.129 + glPushAttrib(GL_ENABLE_BIT); 1.130 + glDisable(GL_LIGHTING); 1.131 + glDisable(GL_TEXTURE_2D); 1.132 + 1.133 + glLineWidth(2.0); 1.134 + glBegin(GL_LINES); 1.135 + glColor4f(1, 0, 0, alpha); 1.136 + glVertex3f(-hsz, 0, 0); 1.137 + glVertex3f(hsz, 0, 0); 1.138 + glColor4f(0, 0, 1, alpha); 1.139 + glVertex3f(0, 0, -hsz); 1.140 + glVertex3f(0, 0, hsz); 1.141 + glEnd(); 1.142 + 1.143 + glLineWidth(1.0); 1.144 + glBegin(GL_LINES); 1.145 + glColor4f(0.5, 0.5, 0.5, alpha); 1.146 + for(int i=0; i<nlines / 2; i++) { 1.147 + float dist = (float)(i + 1) * offs; 1.148 + for(int j=0; j<2; j++) { 1.149 + float sign = j > 0 ? -1.0 : 1.0; 1.150 + glVertex3f(-hsz, 0, dist * sign); 1.151 + glVertex3f(hsz, 0, dist * sign); 1.152 + glVertex3f(dist * sign, 0, -hsz); 1.153 + glVertex3f(dist * sign, 0, hsz); 1.154 + } 1.155 + } 1.156 + glEnd(); 1.157 + 1.158 + glPopAttrib(); 1.159 +} 1.160 + 1.161 static void draw_node(goat3d_node *node) 1.162 { 1.163 SceneNodeData *data = sdata ? sdata->get_node_data(node) : 0; 1.164 @@ -336,14 +426,12 @@ 1.165 glVertex3f(bmax[0], bmin[1], bmax[2]); 1.166 glVertex3f(bmin[0], bmin[1], bmax[2]); 1.167 glEnd(); 1.168 - 1.169 glBegin(GL_LINE_LOOP); 1.170 glVertex3f(bmin[0], bmax[1], bmin[2]); 1.171 glVertex3f(bmax[0], bmax[1], bmin[2]); 1.172 glVertex3f(bmax[0], bmax[1], bmax[2]); 1.173 glVertex3f(bmin[0], bmax[1], bmax[2]); 1.174 glEnd(); 1.175 - 1.176 glBegin(GL_LINES); 1.177 glVertex3f(bmin[0], bmin[1], bmin[2]); 1.178 glVertex3f(bmin[0], bmax[1], bmin[2]); 1.179 @@ -378,8 +466,10 @@ 1.180 1.181 if(mtl && (color = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_DIFFUSE))) { 1.182 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); 1.183 + glColor3fv(color); 1.184 } else { 1.185 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, white); 1.186 + glColor3fv(white); 1.187 } 1.188 if(mtl && (color = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_SPECULAR))) { 1.189 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color); 1.190 @@ -475,3 +565,15 @@ 1.191 { 1.192 QMessageBox::information(this, "About GoatView", about_str); 1.193 } 1.194 + 1.195 + 1.196 +static int next_pow2(int x) 1.197 +{ 1.198 + x--; 1.199 + x = (x >> 1) | x; 1.200 + x = (x >> 2) | x; 1.201 + x = (x >> 4) | x; 1.202 + x = (x >> 8) | x; 1.203 + x = (x >> 16) | x; 1.204 + return x + 1; 1.205 +}