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 +}