StationSector* BaseStation::getSectorUnderMouse(const cocos2d::Vec3& position) { static const auto winSize = cocos2d::Director::getInstance()->getOpenGLView()->getVisibleSize(); static auto camera = GameHub::instance()->getCameraWrap(); static cocos2d::Vec3 src; static cocos2d::Vec3 dst; static cocos2d::Vec2 offset; static float dist; static float dot; static float det; static float angle; offset.set(getToCenterOffset(position)); dist = offset.distanceSquared(cocos2d::Vec2::ZERO); dot = cocos2d::Vec2::UNIT_X.x * offset.x + cocos2d::Vec2::UNIT_X.y * offset.y; // dot product det = cocos2d::Vec2::UNIT_X.x * offset.y - cocos2d::Vec2::UNIT_X.y * offset.x; // determinant angle = -atan2f(det, dot); angle = (angle > 0 ? angle : (2 * 3.14f + angle)) * 360 / (2 * 3.14f); for (unsigned int i = 0; i < m_maxLevels; ++i) { for (auto sector : m_builtAssets[i]) { if (!sector) { // if sectors gonna be destoyed at random indecies in the future // change it to continue break; } if (dist > sector->getMinR() && dist < sector->getMaxR() && angle > sector->getMinA() && angle < sector->getMaxA()) { return sector; } } } return nullptr; }
void BaseStation::onMouseMove(cocos2d::Event* evt) { static const auto winSize = cocos2d::Director::getInstance()->getOpenGLView()->getVisibleSize(); static auto camera = GameHub::instance()->getCameraWrap(); static cocos2d::Vec3 src; static cocos2d::Vec3 dst; static cocos2d::Ray ray; static cocos2d::Vec3 hitpoint; auto mouseEvent = dynamic_cast<cocos2d::EventMouse*>(evt); const auto& mouseLoc = mouseEvent->getLocationInView(); const auto mouseOffset = cocos2d::Vec2(mouseLoc.x, winSize.height - mouseLoc.y); src.set(mouseOffset.x, mouseOffset.y, 10000.0f); dst.set(mouseOffset.x, mouseOffset.y, 0.0f); camera->unproject(src, src); camera->unproject(dst, dst); ray.set(src, dst - src); if (intersects(ray, m_collider.getAABB(), hitpoint)) { static cocos2d::Vec2 offset; static float dist; static float dot; static float det; static float angle; offset.set(getToCenterOffset(hitpoint)); dist = offset.distanceSquared(cocos2d::Vec2::ZERO); dot = cocos2d::Vec2::UNIT_X.x * offset.x + cocos2d::Vec2::UNIT_X.y * offset.y; // dot product det = cocos2d::Vec2::UNIT_X.x * offset.y - cocos2d::Vec2::UNIT_X.y * offset.x; // determinant angle = -atan2f(det, dot); angle = (angle > 0 ? angle : (2 * 3.14f + angle)) * 360 / (2 * 3.14f); bool found = false; for (unsigned int i = 0; i < m_maxLevels; ++i) { for (auto sector : m_builtAssets[i]) { if (!sector) { // if sectors gonna be destoyed at random indecies in the future // change it to continue break; } // special check for hovering the center of the station //m_isCenterHovered = (i == 0 && dist < sector->getMinR()); if (dist > sector->getMinR() && dist < sector->getMaxR() && angle > sector->getMinA() && angle < sector->getMaxA()) { m_selections[i].first->setVisible(true); m_selections[i].first->setRotation(sector->getMinA()); found = true; if (m_hoveredSector && m_hoveredSector != sector) { // hide the previous one auto level = m_hoveredSector->getLevel(); m_selections[level].first->setVisible(false); m_hoveredSector = sector; } else { m_hoveredSector = sector; } break; } } if (found) { //CCLOG("level:%d index:%d", m_hoveredSector->getLevel(), m_hoveredSector->getIndex()); break; } else { m_selections[i].first->setVisible(false); m_hoveredSector = nullptr; } } } }