mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-19 18:47:55 +08:00
refactor: 重新封装了一下战斗技能识别。 BattleSkillReadyImageAnalyzer::analyze 还没写完
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
<ClInclude Include="Vision\Infrast\InfrastSmileyImageAnalyzer.h" />
|
||||
<ClInclude Include="Vision\MatchImageAnalyzer.h" />
|
||||
<ClInclude Include="Vision\Miscellaneous\BattleImageAnalyzer.h" />
|
||||
<ClInclude Include="Vision\Miscellaneous\BattleSkillReadyImageAnalyzer.h" />
|
||||
<ClInclude Include="Vision\Miscellaneous\CreditShopImageAnalyzer.h" />
|
||||
<ClInclude Include="Vision\Miscellaneous\DepotImageAnalyzer.h" />
|
||||
<ClInclude Include="Vision\Miscellaneous\ProcessTaskImageAnalyzer.h" />
|
||||
@@ -120,7 +121,6 @@
|
||||
<ClInclude Include="Utils\Http.hpp" />
|
||||
<ClInclude Include="Utils\ImageIo.hpp" />
|
||||
<ClInclude Include="Utils\Locale.hpp" />
|
||||
<ClInclude Include="Utils\MoreCV.hpp" />
|
||||
<ClInclude Include="Utils\Logger.hpp" />
|
||||
<ClInclude Include="Utils\Meta.hpp" />
|
||||
<ClInclude Include="Utils\NoWarningCV.h" />
|
||||
@@ -150,6 +150,7 @@
|
||||
<ClCompile Include="Vision\Infrast\InfrastSmileyImageAnalyzer.cpp" />
|
||||
<ClCompile Include="Vision\MatchImageAnalyzer.cpp" />
|
||||
<ClCompile Include="Vision\Miscellaneous\BattleImageAnalyzer.cpp" />
|
||||
<ClCompile Include="Vision\Miscellaneous\BattleSkillReadyImageAnalyzer.cpp" />
|
||||
<ClCompile Include="Vision\Miscellaneous\CreditShopImageAnalyzer.cpp" />
|
||||
<ClCompile Include="Vision\Miscellaneous\DepotImageAnalyzer.cpp" />
|
||||
<ClCompile Include="Vision\Miscellaneous\ProcessTaskImageAnalyzer.cpp" />
|
||||
|
||||
@@ -270,9 +270,6 @@
|
||||
<ClInclude Include="Utils\Meta.hpp">
|
||||
<Filter>源文件\Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utils\MoreCV.hpp">
|
||||
<Filter>源文件\Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utils\NoWarningCV.h">
|
||||
<Filter>源文件\Utils</Filter>
|
||||
</ClInclude>
|
||||
@@ -429,6 +426,9 @@
|
||||
<ClInclude Include="Vision\Miscellaneous\StageDropsImageAnalyzer.h">
|
||||
<Filter>源文件\Vision\Miscellaneous</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Vision\Miscellaneous\BattleSkillReadyImageAnalyzer.h">
|
||||
<Filter>源文件\Vision\Miscellaneous</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Vision\AbstractImageAnalyzer.cpp">
|
||||
@@ -710,5 +710,8 @@
|
||||
<ClCompile Include="Vision\Miscellaneous\StageDropsImageAnalyzer.cpp">
|
||||
<Filter>源文件\Vision\Miscellaneous</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Vision\Miscellaneous\BattleSkillReadyImageAnalyzer.cpp">
|
||||
<Filter>源文件\Vision\Miscellaneous</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -7,17 +7,16 @@
|
||||
|
||||
#include "Utils/NoWarningCV.h"
|
||||
|
||||
#include "Controller.h"
|
||||
#include "Config/Miscellaneous/CopilotConfig.h"
|
||||
#include "Config/Miscellaneous/TilePack.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Config/TemplResource.h"
|
||||
#include "Vision/MatchImageAnalyzer.h"
|
||||
#include "Vision/Miscellaneous/BattleImageAnalyzer.h"
|
||||
#include "Vision/OcrWithPreprocessImageAnalyzer.h"
|
||||
#include "Controller.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Utils/MoreCV.hpp"
|
||||
#include "Vision/MatchImageAnalyzer.h"
|
||||
#include "Vision/Miscellaneous/BattleImageAnalyzer.h"
|
||||
#include "Vision/Miscellaneous/BattleSkillReadyImageAnalyzer.h"
|
||||
#include "Vision/OcrWithPreprocessImageAnalyzer.h"
|
||||
|
||||
#include "Utils/ImageIo.hpp"
|
||||
|
||||
@@ -653,21 +652,16 @@ bool asst::BattleProcessTask::wait_to_end(const BattleAction& action)
|
||||
|
||||
bool asst::BattleProcessTask::try_possible_skill(const cv::Mat& image)
|
||||
{
|
||||
auto task_ptr = Task.get<MatchTaskInfo>("BattleAutoSkillFlag");
|
||||
|
||||
const Rect& skill_roi_move = task_ptr->rect_move;
|
||||
cv::Mat temp = TemplResource::get_instance().get_templ(task_ptr->templ_name);
|
||||
|
||||
BattleSkillReadyImageAnalyzer skill_analyzer(image);
|
||||
bool used = false;
|
||||
for (auto& info : m_used_opers | views::values) {
|
||||
if (info.info.skill_usage != BattleSkillUsage::Possibly && info.info.skill_usage != BattleSkillUsage::Once) {
|
||||
continue;
|
||||
}
|
||||
auto roi = make_rect<cv::Rect>(Rect { info.pos.x, info.pos.y, 0, 0 }.move(skill_roi_move));
|
||||
roi &= cv::Rect(0, 0, image.cols, image.rows);
|
||||
|
||||
const auto result = find_skill_ready(image(roi), temp);
|
||||
if (result.empty()) continue;
|
||||
skill_analyzer.set_base_point(info.pos);
|
||||
if (!skill_analyzer.analyze()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ctrler()->click(info.pos);
|
||||
sleep(Task.get("BattleUseOper")->pre_delay);
|
||||
|
||||
@@ -10,15 +10,14 @@
|
||||
#include "Config/Miscellaneous/TilePack.h"
|
||||
#include "Config/Roguelike/RoguelikeCopilotConfig.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Config/TemplResource.h"
|
||||
#include "Controller.h"
|
||||
#include "Status.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/ImageIo.hpp"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Utils/MoreCV.hpp"
|
||||
#include "Vision/MatchImageAnalyzer.h"
|
||||
#include "Vision/Miscellaneous/BattleImageAnalyzer.h"
|
||||
#include "Vision/Miscellaneous/BattleSkillReadyImageAnalyzer.h"
|
||||
#include "Vision/OcrWithPreprocessImageAnalyzer.h"
|
||||
|
||||
bool asst::RoguelikeBattleTaskPlugin::verify(AsstMsg msg, const json::value& details) const
|
||||
@@ -902,11 +901,7 @@ bool asst::RoguelikeBattleTaskPlugin::try_possible_skill(const cv::Mat& image)
|
||||
return false;
|
||||
}
|
||||
|
||||
auto task_ptr = Task.get<MatchTaskInfo>("BattleAutoSkillFlag");
|
||||
|
||||
const Rect& skill_roi_move = task_ptr->rect_move;
|
||||
cv::Mat temp = TemplResource::get_instance().get_templ(task_ptr->templ_name);
|
||||
|
||||
BattleSkillReadyImageAnalyzer skill_analyzer(image);
|
||||
bool used = false;
|
||||
for (auto& [loc, oper_name] : m_used_tiles) {
|
||||
std::string status_key = Status::RoguelikeSkillUsagePrefix + oper_name;
|
||||
@@ -920,16 +915,11 @@ bool asst::RoguelikeBattleTaskPlugin::try_possible_skill(const cv::Mat& image)
|
||||
continue;
|
||||
}
|
||||
const Point pos = m_normal_tile_info.at(loc).pos;
|
||||
const Rect pos_rect(pos.x, pos.y, 1, 1);
|
||||
auto roi = make_rect<cv::Rect>(pos_rect.move(skill_roi_move));
|
||||
roi &= cv::Rect(0, 0, image.cols, image.rows);
|
||||
|
||||
auto result = find_skill_ready(image(roi), temp);
|
||||
if (result.empty()) continue;
|
||||
|
||||
Log.trace(result.front().second);
|
||||
|
||||
ctrler()->click(pos_rect);
|
||||
skill_analyzer.set_base_point(pos);
|
||||
if (!skill_analyzer.analyze()) {
|
||||
continue;
|
||||
}
|
||||
ctrler()->click(pos);
|
||||
sleep(Task.get("BattleUseOper")->pre_delay);
|
||||
bool ret = ProcessTask(*this, { "BattleSkillReadyOnClick" }).set_retry_times(2).run();
|
||||
if (!ret) {
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utils/NoWarningCV.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace asst
|
||||
{
|
||||
inline void key_color(cv::InputArray src, cv::OutputArray dst, const cv::Scalar& color,
|
||||
const cv::Scalar& tolerance = {})
|
||||
{
|
||||
return cv::inRange(src, color - tolerance, color + tolerance, dst);
|
||||
}
|
||||
|
||||
template <typename Pred, typename Compare = std::less<>>
|
||||
inline auto match_template_helper(
|
||||
const cv::Mat1f& image, const cv::Size& repel_box = { 0, 0 }, Pred&& filter = [](auto&&) { return true; },
|
||||
Compare&& cmp = Compare {})
|
||||
{
|
||||
using value_type = std::pair<cv::Point, double>;
|
||||
std::vector<value_type> result {};
|
||||
for (auto i = 0; i < image.cols; ++i)
|
||||
for (auto j = 0; j < image.rows; ++j) {
|
||||
const cv::Point pt = { i, j };
|
||||
const auto value = image.at<float>(pt);
|
||||
if (!filter(value)) continue;
|
||||
auto iter = std::find_if(result.rbegin(), result.rend(), [&](const value_type& pair) {
|
||||
const auto diff = pair.first - pt;
|
||||
return std::abs(diff.x) < repel_box.width && std::abs(diff.y) < repel_box.height;
|
||||
});
|
||||
if (iter != result.rend()) {
|
||||
if (cmp(iter->second, value)) {
|
||||
iter->first = pt;
|
||||
iter->second = value;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.emplace_back(pt, value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline auto find_skill_ready(const cv::Mat& image, const cv::Mat& temp)
|
||||
{
|
||||
auto preprocess = [](cv::Mat &img) {
|
||||
cv::Mat mask_y2;
|
||||
key_color(img, mask_y2, { 40, 94, 103 }, { 10, 10, 10 }); // BGR
|
||||
img.setTo(cv::Scalar { 2, 216, 255 }, mask_y2); // BGR
|
||||
cv::Mat mask_y1;
|
||||
key_color(img, mask_y1, { 2, 216, 255 }, { 20, 20, 20 });
|
||||
cv::dilate(mask_y1, mask_y1, cv::getStructuringElement(cv::MORPH_RECT, { 4, 4 }));
|
||||
cv::bitwise_not(mask_y1, mask_y1);
|
||||
img.setTo(cv::Scalar { 0, 0, 0 }, mask_y1);
|
||||
};
|
||||
|
||||
cv::Mat tmp = temp.clone();
|
||||
cv::Mat img = image.clone();
|
||||
|
||||
cv::Mat template_mask;
|
||||
key_color(tmp, template_mask, { 0, 255, 0 }, { 0, 0, 0 });
|
||||
cv::bitwise_not(template_mask, template_mask);
|
||||
|
||||
preprocess(img);
|
||||
preprocess(tmp);
|
||||
|
||||
cv::Mat match;
|
||||
cv::matchTemplate(img, tmp, match, cv::TM_SQDIFF, template_mask);
|
||||
match /= template_mask.cols * template_mask.rows;
|
||||
cv::sqrt(match, match);
|
||||
|
||||
auto result = match_template_helper(
|
||||
match, { tmp.cols, tmp.rows }, [](float v) { return v < 130.; }, std::greater<> {});
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace asst
|
||||
@@ -51,4 +51,4 @@ namespace asst
|
||||
using InstHelper::ctrler;
|
||||
using InstHelper::need_exit;
|
||||
};
|
||||
}
|
||||
} // namespace asst
|
||||
|
||||
@@ -12,10 +12,8 @@
|
||||
#include "Vision/MultiMatchImageAnalyzer.h"
|
||||
#include "Vision/OcrWithFlagTemplImageAnalyzer.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Utils/MoreCV.hpp"
|
||||
|
||||
bool
|
||||
asst::BattleImageAnalyzer::set_target(int target)
|
||||
bool asst::BattleImageAnalyzer::set_target(int target)
|
||||
{
|
||||
m_target = target;
|
||||
return true;
|
||||
@@ -43,18 +41,7 @@ bool asst::BattleImageAnalyzer::analyze()
|
||||
|
||||
// 可能没有干员(全上场了),所以干员识别结果不影响返回值
|
||||
if (m_target & Target::Oper) {
|
||||
bool oper_ret = opers_analyze();
|
||||
if (m_target == Target::Skill) {
|
||||
ret = oper_ret;
|
||||
}
|
||||
}
|
||||
|
||||
// 可能没有可使用的技能,所以技能识别结果不影响返回值
|
||||
if (m_target & Target::Skill) {
|
||||
bool skill_ret = skill_analyze();
|
||||
if (m_target == Target::Skill) {
|
||||
ret = skill_ret;
|
||||
}
|
||||
opers_analyze();
|
||||
}
|
||||
|
||||
if (m_target & Target::Kills) {
|
||||
@@ -82,11 +69,6 @@ const std::vector<asst::Rect>& asst::BattleImageAnalyzer::get_homes() const noex
|
||||
return m_homes;
|
||||
}
|
||||
|
||||
const std::vector<asst::Rect>& asst::BattleImageAnalyzer::get_ready_skills() const noexcept
|
||||
{
|
||||
return m_ready_skills;
|
||||
}
|
||||
|
||||
int asst::BattleImageAnalyzer::get_hp() const noexcept
|
||||
{
|
||||
return m_hp;
|
||||
@@ -358,30 +340,6 @@ bool asst::BattleImageAnalyzer::home_analyze()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asst::BattleImageAnalyzer::skill_analyze()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
const auto skill_task_ptr = Task.get<MatchTaskInfo>("BattleSkillReady");
|
||||
const Rect& rect_move = skill_task_ptr->rect_move;
|
||||
|
||||
cv::Mat temp = TemplResource::get_instance().get_templ(skill_task_ptr->templ_name);
|
||||
|
||||
const auto result = find_skill_ready(m_image(make_rect<cv::Rect>(skill_task_ptr->roi)), temp);
|
||||
|
||||
if (result.empty()) return false;
|
||||
|
||||
ranges::transform(result, std::back_inserter(m_ready_skills), [&](auto&& pair) {
|
||||
const cv::Point& pos = pair.first;
|
||||
return Rect { pos.x + skill_task_ptr->roi.x, pos.y + skill_task_ptr->roi.y, temp.cols, temp.rows }.move(
|
||||
rect_move);
|
||||
});
|
||||
|
||||
Log.trace(m_ready_skills);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asst::BattleImageAnalyzer::hp_analyze()
|
||||
{
|
||||
// 识别 HP 的那个蓝白色图标
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace asst
|
||||
HP = 1, // 剩余生命值
|
||||
Home = 2, // 蓝色的家门
|
||||
Oper = 4, // 下方的干员信息
|
||||
Skill = 8, // cd 转好了可以使用的技能
|
||||
//Skill = 8, // cd 转好了可以使用的技能
|
||||
Kills = 16, // 击杀数
|
||||
Cost = 32, // 费用
|
||||
Vacancies = 64, // 剩余可部署干员数
|
||||
@@ -33,7 +33,6 @@ namespace asst
|
||||
virtual const std::vector<BattleRealTimeOper>& get_opers() const noexcept;
|
||||
virtual const std::vector<Rect>& get_homes() const noexcept;
|
||||
|
||||
const std::vector<Rect>& get_ready_skills() const noexcept;
|
||||
int get_hp() const noexcept;
|
||||
int get_kills() const noexcept;
|
||||
int get_total_kills() const noexcept;
|
||||
@@ -50,7 +49,7 @@ namespace asst
|
||||
bool oper_available_analyze(const Rect& roi);
|
||||
|
||||
bool home_analyze(); // 识别蓝色的家门
|
||||
bool skill_analyze(); // 识别技能是否可用
|
||||
//bool skill_analyze(); // 识别技能是否可用
|
||||
bool hp_analyze(); // 识别剩余生命值
|
||||
bool kills_analyze(); // 识别击杀数
|
||||
bool cost_analyze(); // 识别费用
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#include "BattleSkillReadyImageAnalyzer.h"
|
||||
|
||||
#include "Utils/NoWarningCV.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include "Config/TaskData.h"
|
||||
#include "Config/TemplResource.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
|
||||
bool asst::BattleSkillReadyImageAnalyzer::analyze()
|
||||
{
|
||||
auto task_ptr = Task.get<MatchTaskInfo>("BattleAutoSkillFlag");
|
||||
const cv::Mat& templ = TemplResource::get_instance().get_templ(task_ptr->templ_name);
|
||||
|
||||
auto key_color = [](cv::InputArray src, cv::OutputArray dst, const cv::Scalar& color,
|
||||
const cv::Scalar& tolerance = {}) {
|
||||
cv::inRange(src, color - tolerance, color + tolerance, dst);
|
||||
};
|
||||
auto preprocess = [&](cv::Mat& img) {
|
||||
cv::Mat mask_y2;
|
||||
key_color(img, mask_y2, { 40, 94, 103 }, { 10, 10, 10 }); // BGR
|
||||
img.setTo(cv::Scalar { 2, 216, 255 }, mask_y2); // BGR
|
||||
cv::Mat mask_y1;
|
||||
key_color(img, mask_y1, { 2, 216, 255 }, { 20, 20, 20 });
|
||||
cv::dilate(mask_y1, mask_y1, cv::getStructuringElement(cv::MORPH_RECT, { 4, 4 }));
|
||||
cv::bitwise_not(mask_y1, mask_y1);
|
||||
img.setTo(cv::Scalar { 0, 0, 0 }, mask_y1);
|
||||
};
|
||||
|
||||
cv::Mat tmp = templ.clone();
|
||||
cv::Mat img = m_image.clone()(make_rect<cv::Rect>(m_roi));
|
||||
|
||||
cv::Mat template_mask;
|
||||
key_color(tmp, template_mask, { 0, 255, 0 }, { 0, 0, 0 });
|
||||
cv::bitwise_not(template_mask, template_mask);
|
||||
|
||||
preprocess(img);
|
||||
preprocess(tmp);
|
||||
|
||||
cv::Mat match;
|
||||
cv::matchTemplate(img, tmp, match, cv::TM_SQDIFF, template_mask);
|
||||
match /= template_mask.cols * template_mask.rows;
|
||||
cv::sqrt(match, match);
|
||||
|
||||
// TODO: 这块我没太看懂,等 horror 改改
|
||||
//auto all_matched = match_template_helper(
|
||||
// match, { tmp.cols, tmp.rows }, [](float v) { return v < 130.; }, std::greater<> {});
|
||||
|
||||
//if (all_matched.empty()) {
|
||||
// return false;
|
||||
//}
|
||||
|
||||
//m_result = all_matched.front();
|
||||
return true;
|
||||
}
|
||||
|
||||
void asst::BattleSkillReadyImageAnalyzer::set_base_point(const Point& pt)
|
||||
{
|
||||
auto task_ptr = Task.get<MatchTaskInfo>("BattleAutoSkillFlag");
|
||||
const Rect& skill_roi_move = task_ptr->rect_move;
|
||||
|
||||
set_roi(Rect(pt.x, pt.y, 0, 0).move(skill_roi_move));
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "Vision/AbstractImageAnalyzer.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class BattleSkillReadyImageAnalyzer final : public AbstractImageAnalyzer
|
||||
{
|
||||
public:
|
||||
using AbstractImageAnalyzer::AbstractImageAnalyzer;
|
||||
virtual ~BattleSkillReadyImageAnalyzer() override = default;
|
||||
|
||||
virtual bool analyze() override;
|
||||
|
||||
void set_base_point(const Point& pt);
|
||||
|
||||
private:
|
||||
MatchRect m_result;
|
||||
};
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "Utils/Ranges.hpp"
|
||||
#include <utility>
|
||||
|
||||
#include "Utils/MoreCV.hpp"
|
||||
#include "Utils/NoWarningCV.h"
|
||||
|
||||
#include "Config/TaskData.h"
|
||||
@@ -122,14 +121,32 @@ bool asst::MultiMatchImageAnalyzer::multi_match_templ(const cv::Mat templ)
|
||||
cv::matchTemplate(image_roi, templ, matched, cv::TM_CCOEFF_NORMED, mask);
|
||||
}
|
||||
|
||||
const auto result =
|
||||
match_template_helper(matched, { static_cast<int>(templ.cols * 0.6), static_cast<int>(templ.rows * 0.6) },
|
||||
[this](float value) -> bool { return m_templ_thres < value && value < 2.0; });
|
||||
|
||||
ranges::transform(result, std::back_inserter(m_result), [&, this](const auto& pair) -> MatchRect {
|
||||
const cv::Point roi_pt = pair.first;
|
||||
return { pair.second, { roi_pt.x + m_roi.x, roi_pt.y + m_roi.y, templ.cols, templ.rows } };
|
||||
});
|
||||
int mini_distance = (std::min)(templ.cols, templ.rows) / 2;
|
||||
for (int i = 0; i != matched.rows; ++i) {
|
||||
for (int j = 0; j != matched.cols; ++j) {
|
||||
auto value = matched.at<float>(i, j);
|
||||
if (m_templ_thres <= value && value < 2.0) {
|
||||
Rect rect(j + m_roi.x, i + m_roi.y, templ.cols, templ.rows);
|
||||
bool need_push = true;
|
||||
// 如果有两个点离得太近,只取里面得分高的那个
|
||||
// 一般相邻的都是刚刚push进去的,这里倒序快一点
|
||||
for (auto& iter : ranges::reverse_view(m_result)) {
|
||||
if (std::abs(j + m_roi.x - iter.rect.x) < mini_distance &&
|
||||
std::abs(i + m_roi.y - iter.rect.y) < mini_distance) {
|
||||
if (iter.score < value) {
|
||||
iter.rect = rect;
|
||||
iter.score = value;
|
||||
} // else 这个点就放弃了
|
||||
need_push = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (need_push) {
|
||||
m_result.emplace_back(value, rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ASST_DEBUG
|
||||
for (const auto& rect : m_result) {
|
||||
|
||||
Reference in New Issue
Block a user