//================================== // VRMenuMgrLocal::CreateObject // creates a new menu object menuHandle_t VRMenuMgrLocal::CreateObject( VRMenuObjectParms const & parms ) { if ( !Initialized ) { LOG( "VRMenuMgrLocal::CreateObject - manager has not been initialized!" ); return menuHandle_t(); } // validate parameters if ( parms.Type >= VRMENU_MAX ) { LOG( "VRMenuMgrLocal::CreateObject - Invalid menu object type: %i", parms.Type ); return menuHandle_t(); } // create the handle first so we can enforce setting it be requiring it to be passed to the constructor int index = -1; if ( FreeList.GetSizeI() > 0 ) { index = FreeList.Back(); FreeList.PopBack(); } else { index = ObjectList.GetSizeI(); } UInt32 id = ++CurrentId; menuHandle_t handle = ComposeHandle( index, id ); //LOG( "VRMenuMgrLocal::CreateObject - handle is %llu", handle.Get() ); VRMenuObject * obj = new VRMenuObjectLocal( parms, handle ); if ( obj == NULL ) { LOG( "VRMenuMgrLocal::CreateObject - failed to allocate menu object!" ); OVR_ASSERT( obj != NULL ); // this would be bad -- but we're likely just going to explode elsewhere return menuHandle_t(); } obj->Init( parms ); if ( index == ObjectList.GetSizeI() ) { // we have to grow the array ObjectList.PushBack( obj ); } else { // insert in existing slot OVR_ASSERT( ObjectList[index] == NULL ); ObjectList[index ] = obj; } return handle; }
//============================== // VRMenuEventHandler::Closing void VRMenuEventHandler::Closing( Array< VRMenuEvent > & events ) { LOG( "Closing" ); // broadcast the closing event VRMenuEvent event( VRMENU_EVENT_CLOSING, EVENT_DISPATCH_BROADCAST, menuHandle_t(), Vector3f( 0.0f ), HitTestResult() ); events.PushBack( event ); }
//============================== // VRMenuEventHandler::Opened void VRMenuEventHandler::Opened( Array< VRMenuEvent > & events ) { LOG( "Opened" ); // broadcast the opened event VRMenuEvent event( VRMENU_EVENT_OPENED, EVENT_DISPATCH_BROADCAST, menuHandle_t(), Vector3f( 0.0f ), HitTestResult() ); events.PushBack( event ); }
//============================== // VRMenuEventHandler::Closed void VRMenuEventHandler::Closed( Array< VRMenuEvent > & events ) { LOG( "Closed" ); // broadcast the closed event VRMenuEvent event( VRMENU_EVENT_CLOSED, EVENT_DISPATCH_BROADCAST, menuHandle_t(), Vector3f( 0.0f ), HitTestResult() ); events.PushBack( event ); if ( FocusedHandle.IsValid() ) { VRMenuEvent event( VRMENU_EVENT_FOCUS_LOST, EVENT_DISPATCH_TARGET, FocusedHandle, Vector3f( 0.0f ), HitTestResult() ); events.PushBack( event ); FocusedHandle.Release(); LOG( "Released FocusHandle" ); } }
//============================== // VRMenuEventHandler::Frame void VRMenuEventHandler::Frame( OvrGuiSys & guiSys, VrFrame const & vrFrame, menuHandle_t const & rootHandle, Posef const & menuPose, Array< VRMenuEvent > & events ) { VRMenuObject * root = guiSys.GetVRMenuMgr().ToObject( rootHandle ); if ( root == NULL ) { return; } // find the object the gaze is touching and update gaze focus const Matrix4f viewMatrix = guiSys.GetApp()->GetLastViewMatrix(); const Vector3f viewPos( GetViewMatrixPosition( viewMatrix ) ); const Vector3f viewFwd( GetViewMatrixForward( viewMatrix ) ); HitTestResult result; menuHandle_t hitHandle = root->HitTest( guiSys, menuPose, viewPos, viewFwd, ContentFlags_t( CONTENT_SOLID ), result ); result.RayStart = viewPos; result.RayDir = viewFwd; VRMenuObject * hit = hitHandle.IsValid() ? guiSys.GetVRMenuMgr().ToObject( hitHandle ) : NULL; /* if ( hit != NULL ) { guiSys.GetApp()->ShowInfoText( 0.0f, "%s", hit->GetText().ToCStr() ); } */ bool focusChanged = ( hitHandle != FocusedHandle ); if ( focusChanged ) { // focus changed VRMenuObject * oldFocus = guiSys.GetVRMenuMgr().ToObject( FocusedHandle ); if ( oldFocus != NULL ) { // setup event for item losing the focus VRMenuEvent event( VRMENU_EVENT_FOCUS_LOST, EVENT_DISPATCH_TARGET, FocusedHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } if ( hit != NULL ) { if ( ( hit->GetFlags() & VRMENUOBJECT_FLAG_NO_FOCUS_GAINED ) == 0 ) { // set up event for item gaining the focus VRMenuEvent event( VRMENU_EVENT_FOCUS_GAINED, EVENT_DISPATCH_FOCUS, hitHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } } FocusedHandle = hitHandle; } if ( ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_UP ) != 0 ) { VRMenuEvent event( VRMENU_EVENT_SWIPE_UP, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } if ( ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_DOWN ) != 0 ) { VRMenuEvent event( VRMENU_EVENT_SWIPE_DOWN, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } if ( ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_FORWARD ) != 0 ) { VRMenuEvent event( VRMENU_EVENT_SWIPE_FORWARD, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } if ( ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_BACK ) != 0 ) { VRMenuEvent event( VRMENU_EVENT_SWIPE_BACK, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } bool touchPressed = ( vrFrame.Input.buttonPressed & ( BUTTON_TOUCH | BUTTON_A ) ) != 0; bool touchReleased = !touchPressed && ( vrFrame.Input.buttonReleased & ( BUTTON_TOUCH | BUTTON_A ) ) != 0; bool touchDown = ( vrFrame.Input.buttonState & BUTTON_TOUCH ) != 0; // Need to update this for keyboard events as well for ( int i = 0; i < vrFrame.Input.NumKeyEvents; i++ ) { if ( vrFrame.Input.KeyEvents[i].KeyCode == OVR_KEY_RETURN ) { switch ( vrFrame.Input.KeyEvents[i].EventType ) { case KEY_EVENT_DOWN: touchPressed = true; break; case KEY_EVENT_UP: touchReleased = true; break; default: break; } } } /* // report swipe data char const * swipeNames[5] = { "none", "down", "up", "back", "forward" }; int swipeUpDown = ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_UP ) ? 2 : 0; swipeUpDown = ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_DOWN ) ? 1 : swipeUpDown; int swipeForwardBack = ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_FORWARD ) ? 4 : 0; swipeForwardBack = ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_BACK ) ? 3 : swipeForwardBack; guiSys.GetApp()->ShowInfoText( 1.0f, "touch %s\n( %s, %s )\n( %.2f, %.2f )\n( %.2f, %.2f )", touchDown ? swipeNames[1] : swipeNames[2], swipeNames[swipeUpDown], swipeNames[swipeForwardBack], vrFrame.Input.touch[0], vrFrame.Input.touch[1], vrFrame.Input.touchRelative[0], vrFrame.Input.touchRelative[1] ); */ // if nothing is focused, send events to the root if ( touchPressed ) { VRMenuEvent event( VRMENU_EVENT_TOUCH_DOWN, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } if ( touchReleased ) { VRMenuEvent event( VRMENU_EVENT_TOUCH_UP, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( vrFrame.Input.touchRelative, 0.0f ), result ); events.PushBack( event ); } if ( touchDown ) { if ( vrFrame.Input.touchRelative.LengthSq() > Mathf::SmallestNonDenormal ) { VRMenuEvent event( VRMENU_EVENT_TOUCH_RELATIVE, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( vrFrame.Input.touchRelative, 0.0f ), result ); events.PushBack( event ); } VRMenuEvent event( VRMENU_EVENT_TOUCH_ABSOLUTE, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( vrFrame.Input.touch, 0.0f ), result ); events.PushBack( event ); } { // always post the frame event to the root VRMenuEvent event( VRMENU_EVENT_FRAME_UPDATE, EVENT_DISPATCH_BROADCAST, menuHandle_t(), Vector3f( 0.0f ), result ); events.PushBack( event ); } }
//============================== // VRMenuEventHandler::InitComponents void VRMenuEventHandler::InitComponents( Array< VRMenuEvent > & events ) { VRMenuEvent event( VRMENU_EVENT_INIT, EVENT_DISPATCH_BROADCAST, menuHandle_t(), Vector3f( 0.0f ), HitTestResult() ); events.PushBack( event ); }
//============================== // VRMenuEventHandler::Frame void VRMenuEventHandler::Frame( App * app, VrFrame const & vrFrame, OvrVRMenuMgr & menuMgr, BitmapFont const & font, menuHandle_t const & rootHandle,Posef const & menuPose, gazeCursorUserId_t const & gazeUserId, Array< VRMenuEvent > & events ) { VRMenuObject * root = menuMgr.ToObject( rootHandle ); if ( root == NULL ) { return; } // find the object the gaze is touching and update gaze focus const Matrix4f viewMatrix = app->GetLastViewMatrix(); const Vector3f viewPos( GetViewMatrixPosition( viewMatrix ) ); const Vector3f viewFwd( GetViewMatrixForward( viewMatrix ) ); HitTestResult result; menuHandle_t hitHandle = root->HitTest( app, menuMgr, font, menuPose, viewPos, viewFwd, ContentFlags_t( CONTENT_SOLID ), result ); result.RayStart = viewPos; result.RayDir = viewFwd; VRMenuObject * hit = hitHandle.IsValid() ? menuMgr.ToObject( hitHandle ) : NULL; app->GetGazeCursor().UpdateForUser( gazeUserId, result.t, ( hit != NULL && !( hit->GetFlags() & VRMenuObjectFlags_t( VRMENUOBJECT_NO_GAZE_HILIGHT ) ) ) ? CURSOR_STATE_HILIGHT : CURSOR_STATE_NORMAL ); /* if ( hit != NULL ) { app->ShowInfoText( 0.0f, "%s", hit->GetText().ToCStr() ); } */ bool focusChanged = ( hitHandle != FocusedHandle ); if ( focusChanged ) { // focus changed VRMenuObject * oldFocus = menuMgr.ToObject( FocusedHandle ); if ( oldFocus != NULL ) { // setup event for item losing the focus VRMenuEvent event( VRMENU_EVENT_FOCUS_LOST, EVENT_DISPATCH_TARGET, FocusedHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } if ( hit != NULL ) { if ( ( hit->GetFlags() & VRMENUOBJECT_FLAG_NO_FOCUS_GAINED ) == 0 ) { // set up event for item gaining the focus VRMenuEvent event( VRMENU_EVENT_FOCUS_GAINED, EVENT_DISPATCH_FOCUS, hitHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } } FocusedHandle = hitHandle; } bool touchPressed = ( vrFrame.Input.buttonPressed & ( BUTTON_TOUCH | BUTTON_A ) ) != 0; bool touchReleased = !touchPressed && ( vrFrame.Input.buttonReleased & ( BUTTON_TOUCH | BUTTON_A ) ) != 0; bool touchDown = ( vrFrame.Input.buttonState & BUTTON_TOUCH ) != 0; if ( ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_UP ) != 0 ) { VRMenuEvent event( VRMENU_EVENT_SWIPE_UP, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } if ( ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_DOWN ) != 0 ) { VRMenuEvent event( VRMENU_EVENT_SWIPE_DOWN, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } if ( ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_FORWARD ) != 0 ) { VRMenuEvent event( VRMENU_EVENT_SWIPE_FORWARD, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } if ( ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_BACK ) != 0 ) { VRMenuEvent event( VRMENU_EVENT_SWIPE_BACK, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } /* // report swipe data char const * swipeNames[5] = { "none", "down", "up", "back", "forward" }; int swipeUpDown = ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_UP ) ? 2 : 0; swipeUpDown = ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_DOWN ) ? 1 : swipeUpDown; int swipeForwardBack = ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_FORWARD ) ? 4 : 0; swipeForwardBack = ( vrFrame.Input.buttonPressed & BUTTON_SWIPE_BACK ) ? 3 : swipeForwardBack; app->ShowInfoText( 1.0f, "touch %s\n( %s, %s )\n( %.2f, %.2f )\n( %.2f, %.2f )", touchDown ? swipeNames[1] : swipeNames[2], swipeNames[swipeUpDown], swipeNames[swipeForwardBack], vrFrame.Input.touch[0], vrFrame.Input.touch[1], vrFrame.Input.touchRelative[0], vrFrame.Input.touchRelative[1] ); */ // if nothing is focused, send events to the root if ( touchPressed ) { VRMenuEvent event( VRMENU_EVENT_TOUCH_DOWN, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( 0.0f ), result ); events.PushBack( event ); } if ( touchReleased ) { VRMenuEvent event( VRMENU_EVENT_TOUCH_UP, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( vrFrame.Input.touchRelative, 0.0f ), result ); events.PushBack( event ); } if ( touchDown ) { if ( vrFrame.Input.touchRelative.LengthSq() > Mathf::SmallestNonDenormal ) { VRMenuEvent event( VRMENU_EVENT_TOUCH_RELATIVE, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( vrFrame.Input.touchRelative, 0.0f ), result ); events.PushBack( event ); } VRMenuEvent event( VRMENU_EVENT_TOUCH_ABSOLUTE, EVENT_DISPATCH_FOCUS, FocusedHandle, Vector3f( vrFrame.Input.touch, 0.0f ), result ); events.PushBack( event ); } { // always post the frame event to the root VRMenuEvent event( VRMENU_EVENT_FRAME_UPDATE, EVENT_DISPATCH_BROADCAST, menuHandle_t(), Vector3f( 0.0f ), result ); events.PushBack( event ); } }