From c48096383ed398a518e69070bfc9373537ab00bb Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Thu, 13 Sep 2018 02:00:41 +0300 Subject: [PATCH] fixed hand tracking world position, and picking up objects in VR --- alien_run | 5 +++ src/app.cc | 104 +++++++++++++++++++++++++++++++++++++++++++++----------- src/exman.h | 1 + src/main.cc | 2 ++ src/vrinput.cc | 8 +++++ 5 files changed, 100 insertions(+), 20 deletions(-) diff --git a/alien_run b/alien_run index ff80c8a..2769e22 100755 --- a/alien_run +++ b/alien_run @@ -1,2 +1,7 @@ #!/bin/sh + +# do a make instalien for proper installation, but copy the executable +# every time just to make iteration easier +cp demo.exe /alien/demo/demo.exe + rsh alien "cd C:\Users\nuclear\Desktop\samba\demo && demo.exe $*" diff --git a/src/app.cc b/src/app.cc index 764d248..91de3f4 100644 --- a/src/app.cc +++ b/src/app.cc @@ -82,6 +82,8 @@ ExSelection exsel_grab_left, exsel_grab_right; static ExhibitSlot exslot_left, exslot_right; #define exslot_mouse exslot_right +static bool pointing; + static Renderer *rend; static RenderTarget *goatvr_rtarg; @@ -371,6 +373,12 @@ static void update(float dt) floor_y = avatar.pos.y - user_eye_height; } + if(have_headtracking) { + Quat qhead; + goatvr_head_orientation(&qhead.x); + avatar.tracked_head_rotation(qhead); + } + // TODO move to the avatar system // calculate mouselook view matrix mouse_view_matrix = Mat4::identity; @@ -381,26 +389,81 @@ static void update(float dt) mouse_view_matrix.pre_rotate_y(deg_to_rad(avatar.body_rot)); mouse_view_matrix.pre_translate(-avatar.pos.x, -avatar.pos.y, -avatar.pos.z); - // update hand-tracking if(have_handtracking) { update_vrhands(&avatar); - if(vrhand[0].valid) { - exslot_left.node.set_position(vrhand[0].pos); - exslot_left.node.set_rotation(vrhand[0].rot); + ExSelection *exsel_grab[] = { &exsel_grab_left, &exsel_grab_right }; + ExhibitSlot *exslot[] = { &exslot_left, &exslot_right }; - // right hand takes precedence for hover - if(!exsel_grab_left && !exsel_hover) { - exsel_hover = exman->select(Sphere(vrhand[0].pos, 5)); + for(int i=0; i<2; i++) { + if(vrhand[i].valid) { + exslot[i]->node.set_position(vrhand[i].pos); + exslot[i]->node.set_rotation(vrhand[i].rot * exslot[i]->rotation); + + bool act_grab = goatvr_action(i, GOATVR_ACTION_GRAB) != 0; + + ExSelection sel; + sel = exman->select(Sphere(vrhand[i].pos, 10)); + + if(!*exsel_grab[i]) { + // we don't have an exhibit grabbed + if(act_grab) { + // grab an exhibit + *exsel_grab[i] = sel; + exslot[i]->rotation = sel.ex->node->get_rotation(); + debug_log("Grabbing with rot: %f %f %f %f\n", exslot[i]->rotation.x, + exslot[i]->rotation.y, exslot[i]->rotation.z, exslot[i]->rotation.w); + exslot[i]->attach_exhibit(sel.ex, EXSLOT_ATTACH_TRANSIENT); + if(exsel_active) { + exsel_active = ExSelection::null; // cancel active on grab + } + } else { + // just hover + exsel_hover = sel; + } + } else { + // we have an exhibit grabbed + if(!act_grab) { + // drop it + Exhibit *ex = exsel_grab[i]->ex; + exslot[i]->detach_exhibit(); + + ExhibitSlot *slot = exman->nearest_empty_slot(vrhand[i].pos, 100); + if(!slot) { + debug_log("no empty slot nearby\n"); + if(ex->prev_slot && ex->prev_slot->empty()) { + slot = ex->prev_slot; + debug_log("using previous slot\n"); + } + } + + if(slot) { + ex->node->set_rotation(exslot[i]->node.get_rotation()); + slot->attach_exhibit(ex); + } else { + // nowhere to put it, stash it for later + exman->stash_exhibit(ex); + debug_log("no slots available, stashing\n"); + } + + *exsel_grab[i] = ExSelection::null; + } + } } } - if(vrhand[1].valid) { - exslot_right.node.set_position(vrhand[1].pos); - exslot_right.node.set_rotation(vrhand[1].rot); - if(!exsel_grab_right) { - exsel_hover = exman->select(Sphere(vrhand[1].pos, 5)); + // if there are no grabs, and we're pointing with the right finger, override active + if(!exsel_grab_left && !exsel_grab_right) { + if(goatvr_action(1, GOATVR_ACTION_POINT)) { + Ray ray; + ray.origin = vrhand[1].pos; + ray.dir = rotate(Vec3(0, 0, -1), vrhand[1].rot); + //exsel_active = exman->select(ray); + pointing = true; + } else { + exsel_active = ExSelection::null; + pointing = false; } } @@ -527,9 +590,6 @@ static void draw_scene() exman->draw(); if(have_handtracking) { - Mat4 head_xform = inverse(mouse_view_matrix);//goatvr_head_matrix(); - Mat4 head_dir_xform = head_xform.upper3x3(); - glUseProgram(0); glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); @@ -540,10 +600,14 @@ static void draw_scene() } else { glColor3f(0.5, 0.5, 0.5); } - Vec3 v = head_xform * vrhand[i].pos; - Vec3 dir = head_dir_xform * rotate(Vec3(0, 0, -1), vrhand[i].rot) * 20.0f; - Vec3 up = head_dir_xform * rotate(Vec3(0, 1, 0), vrhand[i].rot) * 10.0f; - Vec3 right = head_dir_xform * rotate(Vec3(1, 0, 0), vrhand[i].rot) * 10.0f; + Vec3 v = vrhand[i].pos; + Vec3 dir = rotate(Vec3(0, 0, -1), vrhand[i].rot) * 20.0f; + Vec3 up = rotate(Vec3(0, 1, 0), vrhand[i].rot) * 10.0f; + Vec3 right = rotate(Vec3(1, 0, 0), vrhand[i].rot) * 10.0f; + + if(i == 1 && pointing) { + dir *= 1000.0f; + } glVertex3f(v.x, v.y, v.z); glVertex3f(v.x + dir.x, v.y + dir.y, v.z + dir.z); @@ -762,7 +826,7 @@ void app_mouse_button(int bn, bool pressed, int x, int y) debug_log("no empty slot nearby\n"); if(ex->prev_slot && ex->prev_slot->empty()) { slot = ex->prev_slot; - debug_log("using previous slot"); + debug_log("using previous slot\n"); } } diff --git a/src/exman.h b/src/exman.h index df3d8bd..d7d64fa 100644 --- a/src/exman.h +++ b/src/exman.h @@ -17,6 +17,7 @@ private: Exhibit *ex; public: + Quat rotation; SceneNode node; ExhibitSlot(Exhibit *ex = 0); diff --git a/src/main.cc b/src/main.cc index e3c8a73..4fae92d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -79,6 +79,8 @@ int main(int argc, char **argv) } app_reshape(win_width, win_height); + SDL_RaiseWindow(win); + while(!quit) { SDL_Event ev; diff --git a/src/vrinput.cc b/src/vrinput.cc index d5692b8..6bb2aaa 100644 --- a/src/vrinput.cc +++ b/src/vrinput.cc @@ -28,10 +28,18 @@ void destroy_vrhands() void update_vrhands(const Avatar *avatar) { + Quat qbodyrot; + qbodyrot.set_rotation(Vec3(0, 1, 0), -deg_to_rad(avatar->get_body_rotation())); + Vec3 pos = avatar->get_position(); + for(int i=0; i<2; i++) { if(goatvr_hand_active(i)) { goatvr_hand_position(i, &vrhand[i].pos.x); goatvr_hand_orientation(i, &vrhand[i].rot.x); + + vrhand[i].pos = rotate(vrhand[i].pos, qbodyrot) + pos; + vrhand[i].rot = qbodyrot * vrhand[i].rot; + vrhand[i].valid = true; } else { vrhand[i].valid = false; -- 1.7.10.4