void Pick3DObjectExample::CreateWorldSpaceRayFromScreen(const Eegeo::v2& screenPoint, Ray& ray) { const Eegeo::Camera::RenderCamera& renderCamera = m_cameraProvider.GetRenderCamera(); //normalize the point double nx = 2.0 * screenPoint.GetX() / m_renderContext.GetScreenWidth() - 1; double ny = - 2.0 * screenPoint.GetY() / m_renderContext.GetScreenHeight() + 1; //prepare near and far points Eegeo::v4 near(nx, ny, 0.0f, 1.0); Eegeo::v4 far(nx, ny, 1.0f, 1.0); Eegeo::m44 invVP; Eegeo::m44::Inverse(invVP, renderCamera.GetViewProjectionMatrix()); //unproject the points Eegeo::v4 unprojectedNear = Eegeo::v4::Mul(near, invVP); Eegeo::v4 unprojectedFar = Eegeo::v4::Mul(far, invVP); //convert to 3d Eegeo::v3 unprojectedNearWorld = unprojectedNear / unprojectedNear.GetW(); Eegeo::v3 unprojectedFarWorld = unprojectedFar / unprojectedFar.GetW(); //check intersection with a ray cast from camera position ray.m_origin = renderCamera.GetEcefLocation(); ray.m_direction = (unprojectedNearWorld - unprojectedFarWorld).Norm(); }
void WorldPinsScaleController::UpdateWorldPin(WorldPinItemModel& worldPinItemModel, float deltaSeconds, const Eegeo::Camera::RenderCamera& renderCamera) { const bool showingInterior = m_interiorsController.ShowingInterior(); bool shouldHideInteirorPin = worldPinItemModel.IsInterior(); if( showingInterior == false) { shouldHideInteirorPin = shouldHideInteirorPin && !worldPinItemModel.GetInteriorData().showInExterior; } else { shouldHideInteirorPin = shouldHideInteirorPin && (worldPinItemModel.GetInteriorData().floor != m_interiorsController.GetCurrentFloorIndex()); } Eegeo::v2 screenLocation; GetScreenLocation(worldPinItemModel, screenLocation, renderCamera); const float ratioX = screenLocation.GetX() / renderCamera.GetViewportWidth(); const float ratioY = screenLocation.GetY() / renderCamera.GetViewportHeight(); const bool shouldHide = (ratioX < 0.1f) || (ratioX > 0.9f) || (ratioY < 0.15f) || (ratioY > 0.9f) || shouldHideInteirorPin; if(shouldHide) { worldPinItemModel.Hide(); } else { worldPinItemModel.Show(); } worldPinItemModel.Update(deltaSeconds); }
void PinsWithAttachedJavaUIExample::Draw() { //lazily create the pin button when we start drawing so it is not displayed on top of the loading screen if(m_world.Initialising()) { return; } else if(m_buttonID == 0) { CreateJavaUIButton(); } AndroidSafeNativeThreadAttachment attached(m_nativeState); JNIEnv* env = attached.envForThread; Eegeo_ASSERT(m_buttonID != 0); // Get the pin position on the screen Eegeo::Pins::PinRepository& pinRepo = m_pPinsModule->GetRepository(); Eegeo::Pins::Pin* pPin = pinRepo.GetPinAtIndex(0); Eegeo_ASSERT(pPin != NULL); Eegeo::Pins::PinController& pinController = m_pPinsModule->GetController(); Eegeo::Geometry::Bounds2D pinScreenBounds = Eegeo::Geometry::Bounds2D::Empty(); pinController.GetScreenBoundsForPin(*pPin, pinScreenBounds); Eegeo::v2 screenPosition = pinScreenBounds.center(); // now update the java ui to be in sync with the pin, positioned above it on screen. // the pixel nudging is hard-coded for simplicity; you should probably do something more sophisticated // (based on the size of your pin & java ui assets) const int buttonOffsetPixelsX = 40; const int buttonOffsetPixelsY = 110; env->CallVoidMethod( m_hudPinController, m_updateLocationMethodId, m_buttonID, screenPosition.GetX() - buttonOffsetPixelsX, screenPosition.GetY() - buttonOffsetPixelsY ); }
bool PinsWithAttachedJavaUIExample::Event_TouchTap(const AppInterface::TapData& data) { Eegeo::v2 screenTapPoint = Eegeo::v2(data.point.GetX(), data.point.GetY()); Eegeo_TTY("Searching for Pins intersecting tap point %d,%d...", (int) screenTapPoint.GetX(), (int) screenTapPoint.GetY()); Eegeo::Pins::PinController& pinController = m_pPinsModule->GetController(); std::vector<Eegeo::Pins::Pin*> intersectingPinsClosestToCameraFirst; if(pinController.TryGetPinsIntersectingScreenPoint(screenTapPoint, intersectingPinsClosestToCameraFirst)) { Eegeo_TTY("found %ld :\n", intersectingPinsClosestToCameraFirst.size()); for(std::vector<Eegeo::Pins::Pin*>::const_iterator it = intersectingPinsClosestToCameraFirst.begin(); it != intersectingPinsClosestToCameraFirst.end(); ++it) { Eegeo::Pins::Pin* pPin = *it; Eegeo_TTY("\tId=%d, User Data='%s'\n", pPin->GetId(), ((std::string*) pPin->GetUserData())->c_str()); } return true; } else { Eegeo_TTY("none found.\n"); return false; } }
bool WorldMenuItemView::IsCollidingWithPoint(const Eegeo::v2& screenPoint, Eegeo::UI::IUICameraProvider& cameraProvider) { if(!m_pSprite->GetItemShouldRender()) return false; Eegeo::Camera::RenderCamera& renderCamera = cameraProvider.GetRenderCameraForUI(); if (renderCamera.GetEcefLocation().SquareDistanceTo(m_pSprite->GetEcefPosition()) < (GetItemRadius() * GetItemRadius())) { return false; } Eegeo::dv3 rayOrigin = renderCamera.GetEcefLocation(); Eegeo::dv3 rayDirection; Eegeo::Camera::CameraHelpers::GetScreenPickRay(renderCamera, screenPoint.GetX(), screenPoint.GetY(), rayDirection); return Eegeo::Geometry::IntersectionTests::TestRaySphere(rayOrigin, rayDirection, m_pSprite->GetEcefPosition(), GetItemRadius()); }