Vector3f TrackballManipulator::CursorToSpherePos() { // Get the renderer. Renderer* renderer = GraphicSubsystem::Instance()->GetRenderer(); GD_ASSERT(renderer); mEditor->GetMainView()->MakeCurrent(); // Get the camera. Camera* camera = mEditor->GetWorldManager().GetCurrentCamera(); Float farViewDistance = camera->GetFarView(); // Get the mouse position. Int32 x, y; InputSubsystem::GetMouse().GetPos(x, y); QPoint widgetPos = mEditor->GetMainView()->mapFromGlobal(QPoint(x, y)); Int32 viewport[4]; renderer->GetViewport(viewport); Vector2f screenRay( widgetPos.x(), viewport[3] - widgetPos.y() ); // Get the vector from the mouse positions. Vector3f worldRayStart = camera->GetPosition(); Vector3f worldRayEnd = renderer->ScreenToWorld( screenRay ) - camera->GetPosition(); worldRayEnd.Normalize(); worldRayEnd *= farViewDistance; Vector3f onSphere = SphereLineIntersection( worldRayStart, worldRayEnd, mBallPos, 1 ); return (onSphere-mBallPos).GetNormalized() + mBallPos; }
Entity* WorldManager::DoSelectionTest( const Vector2f& pSelectionPoint ) { Int32 viewport[4]; Renderer* renderer = GraphicSubsystem::Instance()->GetRenderer(); renderer->GetViewport(viewport); Vector3f screenRay( pSelectionPoint.x, viewport[3] - pSelectionPoint.y - 1, 0 ); Vector3f worldRay = renderer->ScreenToWorld( screenRay ); // Get the vector from the mouse positions. Vector3f testOrigin = worldRay; Vector3f testDir = worldRay - GetCurrentCamera()->GetPosition(); testDir.Normalize(); return LineTrace( testOrigin, testDir ); }
Intersection WorldViewer::pixelIntersect(const int2 &screen_pos, const FindFilter &filter) const { Intersection out; FBox out_bbox; if(filter.flags() & Flags::tile) { const TileMap &tile_map = m_world->tileMap(); vector<int> inds; tile_map.findAll(inds, IRect(screen_pos, screen_pos + int2(1, 1)), filter.flags() | Flags::visible); for(int i = 0; i < (int)inds.size(); i++) { const auto &desc = tile_map[inds[i]]; FBox bbox = desc.bbox; if(out.empty() || drawingOrder(bbox, out_bbox) == 1) if(desc.ptr->testPixel(screen_pos - worldToScreen((int3)bbox.min))) { out = ObjectRef(inds[i], false); out_bbox = bbox; } } } if(filter.flags() & Flags::entity) { int ignore_index = m_world->filterIgnoreIndex(filter); for(int n = 0; n < (int)m_entities.size(); n++) { const Entity *entity = refEntity(n); if(!entity || !m_occluder_config.isVisible(m_entities[n].occluder_id) || !Flags::test(entity->flags(), filter.flags()) || n == ignore_index) continue; if(!entity->testPixel(screen_pos)) continue; FBox bbox = entity->boundingBox(); //TODO: check this if(out.empty() || drawingOrder(bbox, out_bbox) == 1) { out = ObjectRef(n, true); out_bbox = bbox; } } } if(out.empty()) return Intersection(); return Intersection(out, intersection(screenRay(screen_pos), out_bbox)); }
void EntitiesEditor::computeCursor(int2 start, int2 end, bool floor_mode) { float2 height_off = worldToScreen(int3(0, 0, 0)); start += m_view.pos(); end += m_view.pos(); Ray ray = screenRay(start); Flags::Type flags = Flags::all; if(floor_mode) flags = flags & ~(Flags::wall_tile | Flags::object_tile); auto isect = m_tile_map.trace(ray, -1, flags | Flags::visible); float3 pos = isect.first == -1? (float3)asXZ(screenToWorld(start)) : ray.at(isect.second); m_cursor_pos = (float3)round(pos); m_selection = IRect(min(start, end), max(start, end)); }