goat3d

changeset 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 c1871707c678
children f92da4fa9a6d
files exporters/maxgoat/src/maxgoat.cc goatview/src/goatview.cc goatview/src/goatview.h
diffstat 3 files changed, 122 insertions(+), 14 deletions(-) [+]
line diff
     1.1 --- a/exporters/maxgoat/src/maxgoat.cc	Fri May 16 05:23:10 2014 +0300
     1.2 +++ b/exporters/maxgoat/src/maxgoat.cc	Sat May 17 06:26:24 2014 +0300
     1.3 @@ -295,13 +295,13 @@
     1.4  	// grab the animation data
     1.5  	if(!dynamic_cast<GoatAnimExporter*>(this)) {
     1.6  		// no animation, just get the static PRS
     1.7 -		GMatrix maxmatrix = maxnode->GetObjectTM();
     1.8 +		GMatrix maxmatrix = maxnode->GetLocalTM();
     1.9  		Point3 trans = maxmatrix.Translation();
    1.10  		Quat rot = maxmatrix.Rotation();
    1.11  		Point3 scale = maxmatrix.Scaling();
    1.12  
    1.13  		goat3d_set_node_position(node, trans.x, trans.y, trans.z, 0);
    1.14 -		goat3d_set_node_rotation(node, rot.x, rot.y, rot.z, rot.w, 0);
    1.15 +		goat3d_set_node_rotation(node, rot.x, rot.y, rot.z, -rot.w, 0);
    1.16  		goat3d_set_node_scaling(node, scale.x, scale.y, scale.z, 0);
    1.17  
    1.18  	} else {
    1.19 @@ -412,19 +412,19 @@
    1.20  		maxlog("node %s: getting %d linear rotation keys\n", nodename, rkeys.Count());
    1.21  		for(int i=0; i<rkeys.Count(); i++) {
    1.22  			Quat q = rkeys[i].linearKey.qval;
    1.23 -			goat3d_set_node_rotation(node, q.x, q.y, q.z, q.w, KEY_TIME(rkeys[i]));
    1.24 +			goat3d_set_node_rotation(node, q.x, q.y, q.z, -q.w, KEY_TIME(rkeys[i]));
    1.25  		}
    1.26  	} else if(ctrl->GetBezierKeys(rkeys, IGAME_ROT)) {
    1.27  		maxlog("node %s: getting %d bezier rotation keys\n", nodename, rkeys.Count());
    1.28  		for(int i=0; i<rkeys.Count(); i++) {
    1.29  			Quat q = rkeys[i].bezierKey.qval;
    1.30 -			goat3d_set_node_rotation(node, q.x, q.y, q.z, q.w, KEY_TIME(rkeys[i]));
    1.31 +			goat3d_set_node_rotation(node, q.x, q.y, q.z, -q.w, KEY_TIME(rkeys[i]));
    1.32  		}
    1.33  	} else if(ctrl->GetTCBKeys(rkeys, IGAME_ROT)) {
    1.34  		maxlog("node %s: getting %d TCB rotation keys\n", nodename, rkeys.Count());
    1.35  		for(int i=0; i<rkeys.Count(); i++) {
    1.36  			Quat q(rkeys[i].tcbKey.aval);
    1.37 -			goat3d_set_node_rotation(node, q.x, q.y, q.z, q.w, KEY_TIME(rkeys[i]));
    1.38 +			goat3d_set_node_rotation(node, q.x, q.y, q.z, -q.w, KEY_TIME(rkeys[i]));
    1.39  		}
    1.40  	} else {
    1.41  		get_euler_keys(ctrl, node);
    1.42 @@ -471,7 +471,7 @@
    1.43  	while(it != euler.end()) {
    1.44  		Quat q;
    1.45  		EulerToQuat(it->second, q, order);
    1.46 -		goat3d_set_node_rotation(node, q.x, q.y, q.z, q.w, it->first);
    1.47 +		goat3d_set_node_rotation(node, q.x, q.y, q.z, -q.w, it->first);
    1.48  		++it;
    1.49  	}
    1.50  }
     2.1 --- a/goatview/src/goatview.cc	Fri May 16 05:23:10 2014 +0300
     2.2 +++ b/goatview/src/goatview.cc	Sat May 17 06:26:24 2014 +0300
     2.3 @@ -6,22 +6,27 @@
     2.4  #include "goatview.h"
     2.5  #include "goat3d.h"
     2.6  
     2.7 +static void draw_grid();
     2.8 +static void draw_grid(float sz, int nlines, float alpha = 1.0f);
     2.9  static void draw_node(goat3d_node *node);
    2.10  static void draw_mesh(goat3d_mesh *mesh);
    2.11 +static int next_pow2(int x);
    2.12  
    2.13  goat3d *scene;
    2.14  static SceneModel *sdata;
    2.15  static GoatViewport *glview;
    2.16  
    2.17  static long anim_time;
    2.18 -static float cam_theta, cam_phi, cam_dist = 8;
    2.19 +static float cam_theta, cam_phi = 25, cam_dist = 8;
    2.20  static float fov = 60.0;
    2.21  static bool use_nodes = true;
    2.22  static bool use_lighting = true;
    2.23  
    2.24  void post_redisplay()
    2.25  {
    2.26 -	glview->updateGL();
    2.27 +	if(glview) {
    2.28 +		glview->updateGL();
    2.29 +	}
    2.30  }
    2.31  
    2.32  
    2.33 @@ -101,7 +106,7 @@
    2.34  
    2.35  	QAction *act_quit = new QAction("&Quit", this);
    2.36  	act_quit->setShortcuts(QKeySequence::Quit);
    2.37 -	connect(act_quit, &QAction::triggered, [&](){qApp->quit();});
    2.38 +	connect(act_quit, &QAction::triggered, [&](){ qApp->quit(); });
    2.39  	menu_file->addAction(act_quit);
    2.40  
    2.41  	// view menu
    2.42 @@ -136,7 +141,7 @@
    2.43  	QVBoxLayout *dock_vbox = new QVBoxLayout;
    2.44  	dock_cont->setLayout(dock_vbox);
    2.45  
    2.46 -	QDockWidget *dock = new QDockWidget("Scene graph", this);
    2.47 +	QDockWidget *dock = new QDockWidget(this);
    2.48  	dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    2.49  	dock->setWidget(dock_cont);
    2.50  	addDockWidget(Qt::LeftDockWidgetArea, dock);
    2.51 @@ -164,11 +169,37 @@
    2.52  	QHBoxLayout *dock_hbox = new QHBoxLayout;
    2.53  	dock_cont->setLayout(dock_hbox);
    2.54  
    2.55 -	QSlider *slider_time = new QSlider(Qt::Orientation::Horizontal);
    2.56 +	// animation control box
    2.57 +	QGridLayout *anim_ctl_box = new QGridLayout;
    2.58 +	dock_hbox->addLayout(anim_ctl_box);
    2.59 +
    2.60 +	anim_ctl_box->addWidget(new QLabel("Animation"), 0, 0);
    2.61 +	cbox_anims = new QComboBox;
    2.62 +	cbox_anims->setDisabled(true);
    2.63 +	anim_ctl_box->addWidget(cbox_anims, 0, 1);
    2.64 +
    2.65 +	chk_loop = new QCheckBox("loop");
    2.66 +	chk_loop->setChecked(false);
    2.67 +	anim_ctl_box->addWidget(chk_loop, 1, 0);
    2.68 +
    2.69 +	QToolBar *toolbar_ctl = new QToolBar;
    2.70 +	anim_ctl_box->addWidget(toolbar_ctl, 1, 1);
    2.71 +
    2.72 +	act_rewind = new QAction(style()->standardIcon(QStyle::SP_MediaSkipBackward), "Rewind", this);
    2.73 +	act_rewind->setDisabled(true);
    2.74 +	toolbar_ctl->addAction(act_rewind);
    2.75 +	act_play = new QAction(style()->standardIcon(QStyle::SP_MediaPlay), "Play", this);
    2.76 +	act_play->setDisabled(true);
    2.77 +	toolbar_ctl->addAction(act_play);
    2.78 +
    2.79 +	// timeline slider
    2.80 +	slider_time = new QSlider(Qt::Orientation::Horizontal);
    2.81  	slider_time->setDisabled(true);
    2.82 +	connect(slider_time, &QSlider::valueChanged,
    2.83 +		[&](){ anim_time = slider_time->value(); post_redisplay(); });
    2.84  	dock_hbox->addWidget(slider_time);
    2.85  
    2.86 -	dock = new QDockWidget("Animation", this);
    2.87 +	dock = new QDockWidget(this);
    2.88  	dock->setAllowedAreas(Qt::BottomDockWidgetArea);
    2.89  	dock->setWidget(dock_cont);
    2.90  	addDockWidget(Qt::BottomDockWidgetArea, dock);
    2.91 @@ -270,6 +301,8 @@
    2.92  	glRotatef(cam_phi, 1, 0, 0);
    2.93  	glRotatef(cam_theta, 0, 1, 0);
    2.94  
    2.95 +	draw_grid();
    2.96 +
    2.97  	if(!scene) return;
    2.98  
    2.99  	if(use_nodes) {
   2.100 @@ -304,6 +337,63 @@
   2.101  #error "GLEW_ARB_transpose_matrix undefined?"
   2.102  #endif
   2.103  
   2.104 +static void draw_grid()
   2.105 +{
   2.106 +	float viewsz_orig = cam_dist * tan(DEG_TO_RAD(fov) / 2.0);
   2.107 +	float sz1 = next_pow2((int)viewsz_orig);
   2.108 +	float sz0 = sz1 / 2.0;
   2.109 +	float t = (viewsz_orig - sz0) / (sz1 - sz0);
   2.110 +	float alpha = t < 0.333333 ? 0.0 : (t > 0.666666 ? 1.0 : (t - 0.333333) / 0.333333);
   2.111 +
   2.112 +	glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BITS);
   2.113 +
   2.114 +	glEnable(GL_BLEND);
   2.115 +	glDepthFunc(GL_ALWAYS);
   2.116 +
   2.117 +	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   2.118 +	draw_grid(sz0 * 2.0, 10, 1.0 - alpha);
   2.119 +	draw_grid(sz1 * 2.0, 10, alpha);
   2.120 +
   2.121 +	glPopAttrib();
   2.122 +}
   2.123 +
   2.124 +static void draw_grid(float sz, int nlines, float alpha)
   2.125 +{
   2.126 +	float hsz = sz / 2.0;
   2.127 +	float offs = sz / (float)nlines;
   2.128 +
   2.129 +	glPushAttrib(GL_ENABLE_BIT);
   2.130 +	glDisable(GL_LIGHTING);
   2.131 +	glDisable(GL_TEXTURE_2D);
   2.132 +
   2.133 +	glLineWidth(2.0);
   2.134 +	glBegin(GL_LINES);
   2.135 +	glColor4f(1, 0, 0, alpha);
   2.136 +	glVertex3f(-hsz, 0, 0);
   2.137 +	glVertex3f(hsz, 0, 0);
   2.138 +	glColor4f(0, 0, 1, alpha);
   2.139 +	glVertex3f(0, 0, -hsz);
   2.140 +	glVertex3f(0, 0, hsz);
   2.141 +	glEnd();
   2.142 +
   2.143 +	glLineWidth(1.0);
   2.144 +	glBegin(GL_LINES);
   2.145 +	glColor4f(0.5, 0.5, 0.5, alpha);
   2.146 +	for(int i=0; i<nlines / 2; i++) {
   2.147 +		float dist = (float)(i + 1) * offs;
   2.148 +		for(int j=0; j<2; j++) {
   2.149 +			float sign = j > 0 ? -1.0 : 1.0;
   2.150 +			glVertex3f(-hsz, 0, dist * sign);
   2.151 +			glVertex3f(hsz, 0, dist * sign);
   2.152 +			glVertex3f(dist * sign, 0, -hsz);
   2.153 +			glVertex3f(dist * sign, 0, hsz);
   2.154 +		}
   2.155 +	}
   2.156 +	glEnd();
   2.157 +
   2.158 +	glPopAttrib();
   2.159 +}
   2.160 +
   2.161  static void draw_node(goat3d_node *node)
   2.162  {
   2.163  	SceneNodeData *data = sdata ? sdata->get_node_data(node) : 0;
   2.164 @@ -336,14 +426,12 @@
   2.165  				glVertex3f(bmax[0], bmin[1], bmax[2]);
   2.166  				glVertex3f(bmin[0], bmin[1], bmax[2]);
   2.167  				glEnd();
   2.168 -
   2.169  				glBegin(GL_LINE_LOOP);
   2.170  				glVertex3f(bmin[0], bmax[1], bmin[2]);
   2.171  				glVertex3f(bmax[0], bmax[1], bmin[2]);
   2.172  				glVertex3f(bmax[0], bmax[1], bmax[2]);
   2.173  				glVertex3f(bmin[0], bmax[1], bmax[2]);
   2.174  				glEnd();
   2.175 -
   2.176  				glBegin(GL_LINES);
   2.177  				glVertex3f(bmin[0], bmin[1], bmin[2]);
   2.178  				glVertex3f(bmin[0], bmax[1], bmin[2]);
   2.179 @@ -378,8 +466,10 @@
   2.180  
   2.181  	if(mtl && (color = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_DIFFUSE))) {
   2.182  		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
   2.183 +		glColor3fv(color);
   2.184  	} else {
   2.185  		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, white);
   2.186 +		glColor3fv(white);
   2.187  	}
   2.188  	if(mtl && (color = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_SPECULAR))) {
   2.189  		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
   2.190 @@ -475,3 +565,15 @@
   2.191  {
   2.192  	QMessageBox::information(this, "About GoatView", about_str);
   2.193  }
   2.194 +
   2.195 +
   2.196 +static int next_pow2(int x)
   2.197 +{
   2.198 +	x--;
   2.199 +	x = (x >> 1) | x;
   2.200 +	x = (x >> 2) | x;
   2.201 +	x = (x >> 4) | x;
   2.202 +	x = (x >> 8) | x;
   2.203 +	x = (x >> 16) | x;
   2.204 +	return x + 1;
   2.205 +}
     3.1 --- a/goatview/src/goatview.h	Fri May 16 05:23:10 2014 +0300
     3.2 +++ b/goatview/src/goatview.h	Sat May 17 06:26:24 2014 +0300
     3.3 @@ -21,6 +21,12 @@
     3.4  	QTreeView *treeview;
     3.5  	SceneModel *scene_model;
     3.6  
     3.7 +	// animation controls
     3.8 +	QSlider *slider_time;
     3.9 +	QComboBox *cbox_anims;
    3.10 +	QCheckBox *chk_loop;
    3.11 +	QAction *act_play, *act_rewind;
    3.12 +
    3.13  	void closeEvent(QCloseEvent *ev);
    3.14  	bool make_menu();
    3.15  	bool make_dock();