std::pair<bool, Ogre::Vector3> CombatCamera::IntersectMouseWithEcliptic(const GG::Pt& pt) const { std::pair<bool, Ogre::Vector3> retval(false, Ogre::Vector3()); double ray_origin[3]; double ray_direction[3]; ViewportRay(Value(pt.x * 1.0 / GG::GUI::GetGUI()->AppWidth()), Value(pt.y * 1.0 / GG::GUI::GetGUI()->AppHeight()), ray_origin, ray_direction); double unit_z[3] = { 0, 0, 1.0 }; double origin[3] = { 0, 0, 0 }; std::pair<bool, double> intersection = Intersects(ray_origin, ray_direction, unit_z, origin); if (intersection.first) { double point[3] = { ray_origin[0] + ray_direction[0] * intersection.second, ray_origin[1] + ray_direction[1] * intersection.second, ray_origin[2] + ray_direction[2] * intersection.second }; const double MAX_DISTANCE_SQ = SystemRadius() * SystemRadius(); if ((point[0] * point[0] + point[1] * point[1] + point[2] * point[2]) < MAX_DISTANCE_SQ) { retval.first = true; retval.second.x = point[0]; retval.second.y = point[1]; retval.second.z = point[2]; } } return retval; }
void CombatCamera::MouseWheel(const GG::Pt& pt, int move, GG::Flags<GG::ModKey> mod_keys) { Ogre::Real total_move = TotalMove(move, mod_keys, DistanceToLookAtPoint()); if (0 < move) { const unsigned int TICKS = GG::GUI::GetGUI()->Ticks(); const unsigned int ZOOM_IN_TIMEOUT = 750u; if (m_initial_zoom_in_position == INVALID_MAP_LOCATION || ZOOM_IN_TIMEOUT < TICKS - m_previous_zoom_in_time) { std::pair<bool, Ogre::Vector3> intersection = IntersectMouseWithEcliptic(pt); m_initial_zoom_in_position = intersection.first ? intersection.second : INVALID_MAP_LOCATION; } if (m_initial_zoom_in_position != INVALID_MAP_LOCATION) { const double CLOSE_FACTOR = move * 0.333 * ZoomFactor(mod_keys); Ogre::Vector3 start = Moving() ? m_look_at_point_target : LookAtPoint(); Ogre::Vector3 delta = m_initial_zoom_in_position - start; double delta_length = delta.length(); double distance = std::min(std::max(1.0, delta_length * CLOSE_FACTOR), delta_length); delta.normalise(); Ogre::Vector3 new_center = start + delta * distance; if (new_center.length() < SystemRadius()) LookAtPositionAndZoom(new_center, ZoomResult(total_move)); } m_previous_zoom_in_time = TICKS; } else if (move < 0) { ZoomImpl(total_move); } }
double StarlaneEntranceOrbitalRadius() { return SystemRadius() - StarlaneEntranceRadialAxis(); }
double OrbitalRadius(unsigned int orbit) { assert(orbit < 10); return (SystemRadius() - 50.0) / 10 * (orbit + 1) - 20.0; }