# HG changeset patch # User John Tsiombikas # Date 1400297184 -10800 # Node ID 8b156bc5205bc08c2daa9aebfcce4a7e92d597b0 # Parent c1871707c67803bd55086cddcb6dc8f7da4e8599 [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 diff -r c1871707c678 -r 8b156bc5205b exporters/maxgoat/src/maxgoat.cc --- a/exporters/maxgoat/src/maxgoat.cc Fri May 16 05:23:10 2014 +0300 +++ b/exporters/maxgoat/src/maxgoat.cc Sat May 17 06:26:24 2014 +0300 @@ -295,13 +295,13 @@ // grab the animation data if(!dynamic_cast(this)) { // no animation, just get the static PRS - GMatrix maxmatrix = maxnode->GetObjectTM(); + GMatrix maxmatrix = maxnode->GetLocalTM(); Point3 trans = maxmatrix.Translation(); Quat rot = maxmatrix.Rotation(); Point3 scale = maxmatrix.Scaling(); goat3d_set_node_position(node, trans.x, trans.y, trans.z, 0); - goat3d_set_node_rotation(node, rot.x, rot.y, rot.z, rot.w, 0); + goat3d_set_node_rotation(node, rot.x, rot.y, rot.z, -rot.w, 0); goat3d_set_node_scaling(node, scale.x, scale.y, scale.z, 0); } else { @@ -412,19 +412,19 @@ maxlog("node %s: getting %d linear rotation keys\n", nodename, rkeys.Count()); for(int i=0; iGetBezierKeys(rkeys, IGAME_ROT)) { maxlog("node %s: getting %d bezier rotation keys\n", nodename, rkeys.Count()); for(int i=0; iGetTCBKeys(rkeys, IGAME_ROT)) { maxlog("node %s: getting %d TCB rotation keys\n", nodename, rkeys.Count()); for(int i=0; isecond, q, order); - goat3d_set_node_rotation(node, q.x, q.y, q.z, q.w, it->first); + goat3d_set_node_rotation(node, q.x, q.y, q.z, -q.w, it->first); ++it; } } diff -r c1871707c678 -r 8b156bc5205b goatview/src/goatview.cc --- a/goatview/src/goatview.cc Fri May 16 05:23:10 2014 +0300 +++ b/goatview/src/goatview.cc Sat May 17 06:26:24 2014 +0300 @@ -6,22 +6,27 @@ #include "goatview.h" #include "goat3d.h" +static void draw_grid(); +static void draw_grid(float sz, int nlines, float alpha = 1.0f); static void draw_node(goat3d_node *node); static void draw_mesh(goat3d_mesh *mesh); +static int next_pow2(int x); goat3d *scene; static SceneModel *sdata; static GoatViewport *glview; static long anim_time; -static float cam_theta, cam_phi, cam_dist = 8; +static float cam_theta, cam_phi = 25, cam_dist = 8; static float fov = 60.0; static bool use_nodes = true; static bool use_lighting = true; void post_redisplay() { - glview->updateGL(); + if(glview) { + glview->updateGL(); + } } @@ -101,7 +106,7 @@ QAction *act_quit = new QAction("&Quit", this); act_quit->setShortcuts(QKeySequence::Quit); - connect(act_quit, &QAction::triggered, [&](){qApp->quit();}); + connect(act_quit, &QAction::triggered, [&](){ qApp->quit(); }); menu_file->addAction(act_quit); // view menu @@ -136,7 +141,7 @@ QVBoxLayout *dock_vbox = new QVBoxLayout; dock_cont->setLayout(dock_vbox); - QDockWidget *dock = new QDockWidget("Scene graph", this); + QDockWidget *dock = new QDockWidget(this); dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); dock->setWidget(dock_cont); addDockWidget(Qt::LeftDockWidgetArea, dock); @@ -164,11 +169,37 @@ QHBoxLayout *dock_hbox = new QHBoxLayout; dock_cont->setLayout(dock_hbox); - QSlider *slider_time = new QSlider(Qt::Orientation::Horizontal); + // animation control box + QGridLayout *anim_ctl_box = new QGridLayout; + dock_hbox->addLayout(anim_ctl_box); + + anim_ctl_box->addWidget(new QLabel("Animation"), 0, 0); + cbox_anims = new QComboBox; + cbox_anims->setDisabled(true); + anim_ctl_box->addWidget(cbox_anims, 0, 1); + + chk_loop = new QCheckBox("loop"); + chk_loop->setChecked(false); + anim_ctl_box->addWidget(chk_loop, 1, 0); + + QToolBar *toolbar_ctl = new QToolBar; + anim_ctl_box->addWidget(toolbar_ctl, 1, 1); + + act_rewind = new QAction(style()->standardIcon(QStyle::SP_MediaSkipBackward), "Rewind", this); + act_rewind->setDisabled(true); + toolbar_ctl->addAction(act_rewind); + act_play = new QAction(style()->standardIcon(QStyle::SP_MediaPlay), "Play", this); + act_play->setDisabled(true); + toolbar_ctl->addAction(act_play); + + // timeline slider + slider_time = new QSlider(Qt::Orientation::Horizontal); slider_time->setDisabled(true); + connect(slider_time, &QSlider::valueChanged, + [&](){ anim_time = slider_time->value(); post_redisplay(); }); dock_hbox->addWidget(slider_time); - dock = new QDockWidget("Animation", this); + dock = new QDockWidget(this); dock->setAllowedAreas(Qt::BottomDockWidgetArea); dock->setWidget(dock_cont); addDockWidget(Qt::BottomDockWidgetArea, dock); @@ -270,6 +301,8 @@ glRotatef(cam_phi, 1, 0, 0); glRotatef(cam_theta, 0, 1, 0); + draw_grid(); + if(!scene) return; if(use_nodes) { @@ -304,6 +337,63 @@ #error "GLEW_ARB_transpose_matrix undefined?" #endif +static void draw_grid() +{ + float viewsz_orig = cam_dist * tan(DEG_TO_RAD(fov) / 2.0); + float sz1 = next_pow2((int)viewsz_orig); + float sz0 = sz1 / 2.0; + float t = (viewsz_orig - sz0) / (sz1 - sz0); + float alpha = t < 0.333333 ? 0.0 : (t > 0.666666 ? 1.0 : (t - 0.333333) / 0.333333); + + glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BITS); + + glEnable(GL_BLEND); + glDepthFunc(GL_ALWAYS); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + draw_grid(sz0 * 2.0, 10, 1.0 - alpha); + draw_grid(sz1 * 2.0, 10, alpha); + + glPopAttrib(); +} + +static void draw_grid(float sz, int nlines, float alpha) +{ + float hsz = sz / 2.0; + float offs = sz / (float)nlines; + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + + glLineWidth(2.0); + glBegin(GL_LINES); + glColor4f(1, 0, 0, alpha); + glVertex3f(-hsz, 0, 0); + glVertex3f(hsz, 0, 0); + glColor4f(0, 0, 1, alpha); + glVertex3f(0, 0, -hsz); + glVertex3f(0, 0, hsz); + glEnd(); + + glLineWidth(1.0); + glBegin(GL_LINES); + glColor4f(0.5, 0.5, 0.5, alpha); + for(int i=0; i 0 ? -1.0 : 1.0; + glVertex3f(-hsz, 0, dist * sign); + glVertex3f(hsz, 0, dist * sign); + glVertex3f(dist * sign, 0, -hsz); + glVertex3f(dist * sign, 0, hsz); + } + } + glEnd(); + + glPopAttrib(); +} + static void draw_node(goat3d_node *node) { SceneNodeData *data = sdata ? sdata->get_node_data(node) : 0; @@ -336,14 +426,12 @@ glVertex3f(bmax[0], bmin[1], bmax[2]); glVertex3f(bmin[0], bmin[1], bmax[2]); glEnd(); - glBegin(GL_LINE_LOOP); glVertex3f(bmin[0], bmax[1], bmin[2]); glVertex3f(bmax[0], bmax[1], bmin[2]); glVertex3f(bmax[0], bmax[1], bmax[2]); glVertex3f(bmin[0], bmax[1], bmax[2]); glEnd(); - glBegin(GL_LINES); glVertex3f(bmin[0], bmin[1], bmin[2]); glVertex3f(bmin[0], bmax[1], bmin[2]); @@ -378,8 +466,10 @@ if(mtl && (color = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_DIFFUSE))) { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); + glColor3fv(color); } else { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, white); + glColor3fv(white); } if(mtl && (color = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_SPECULAR))) { glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color); @@ -475,3 +565,15 @@ { QMessageBox::information(this, "About GoatView", about_str); } + + +static int next_pow2(int x) +{ + x--; + x = (x >> 1) | x; + x = (x >> 2) | x; + x = (x >> 4) | x; + x = (x >> 8) | x; + x = (x >> 16) | x; + return x + 1; +} diff -r c1871707c678 -r 8b156bc5205b goatview/src/goatview.h --- a/goatview/src/goatview.h Fri May 16 05:23:10 2014 +0300 +++ b/goatview/src/goatview.h Sat May 17 06:26:24 2014 +0300 @@ -21,6 +21,12 @@ QTreeView *treeview; SceneModel *scene_model; + // animation controls + QSlider *slider_time; + QComboBox *cbox_anims; + QCheckBox *chk_loop; + QAction *act_play, *act_rewind; + void closeEvent(QCloseEvent *ev); bool make_menu(); bool make_dock();