1
0

feat: add new rule in BMapInspector

This commit is contained in:
2026-02-04 21:32:34 +08:00
parent 7b40c64470
commit 2240f55964
6 changed files with 95 additions and 7 deletions

View File

@@ -0,0 +1,53 @@
#include "YYCRules.hpp"
#include "Shared.hpp"
#include "SSBRules.hpp"
namespace L = LibCmo;
namespace C = LibCmo::CK2;
namespace V = LibCmo::VxMath;
namespace O = LibCmo::CK2::ObjImpls;
namespace BMapInspector::Rule {
#pragma region SSB Rule 1
constexpr char8_t SSB1[] = u8"SSB1";
constexpr L::CKFLOAT TOLERANCE = 0.001f;
SSBRule1::SSBRule1() : IRule() {}
SSBRule1::~SSBRule1() {}
std::u8string_view SSBRule1::GetRuleName() const {
return SSB1;
}
void SSBRule1::Check(Reporter::Reporter& reporter, Map::Level& level) const {
auto* ctx = level.GetCKContext();
auto physicalized_3dobjects = Shared::FetchPhysicalized3dObjects(ctx);
// Iterate all physicalized 3dobject
for (auto* physicalized_3dobject : physicalized_3dobjects) {
// Get its world matrix
const auto& matrix = physicalized_3dobject->GetWorldMatrix();
// Extract 3 columns
V::VxVector3 col1(matrix[0][0], matrix[1][0], matrix[2][0]);
V::VxVector3 col2(matrix[0][1], matrix[1][1], matrix[2][1]);
V::VxVector3 col3(matrix[0][2], matrix[1][2], matrix[2][2]);
// Compute their length, then check their value with tolerance.
bool has_scale = false;
if (!Shared::FPEqual(col1.Length(), 1.0f, TOLERANCE)) has_scale = true;
if (!Shared::FPEqual(col2.Length(), 1.0f, TOLERANCE)) has_scale = true;
if (!Shared::FPEqual(col3.Length(), 1.0f, TOLERANCE)) has_scale = true;
// If it has scale factor, report error
if (has_scale) {
reporter.FormatError(
SSB1,
u8R"(Object "%s" grouped into physicalization groups has scale factor. This will cause its collision shape is different with its render shape.)",
Shared::RenderObjectName(physicalized_3dobject));
}
}
}
#pragma endregion
} // namespace BMapInspector::Rule

View File

@@ -0,0 +1,22 @@
#pragma once
#include "../Rule.hpp"
namespace BMapInspector::Rule {
/**
* @brief speedystoneball Rule 1
* @details
* Pjysicalized object should not have scale factor, especially negative scale factor (mirror).
*/
class SSBRule1 : public IRule {
public:
SSBRule1();
virtual ~SSBRule1();
YYCC_DELETE_COPY_MOVE(SSBRule1)
public:
std::u8string_view GetRuleName() const override;
void Check(Reporter::Reporter& reporter, Map::Level& level) const override;
};
} // namespace BMapInspector::Rule

View File

@@ -2,6 +2,7 @@
#include <yycc.hpp>
#include <yycc/carton/termcolor.hpp>
#include <filesystem>
#include <cmath>
namespace termcolor = yycc::carton::termcolor;
@@ -9,12 +10,12 @@ namespace BMapInspector::Rule::Shared {
#pragma region Check Functions
/**
* @brief
* @param[in] ctx Can not be nullptr.
* @param[in] name Can not be nullptr.
* @return Found pointer to CKGroup, otherwise nullptr.
*/
bool FPEqual(L::CKFLOAT lhs, L::CKFLOAT rhs, L::CKFLOAT tolerance) {
auto diff = lhs - rhs;
auto absolute_diff = std::fabs(diff);
return absolute_diff <= tolerance;
}
O::CKGroup* FetchGroup(C::CKContext* ctx, L::CKSTRING name) {
return static_cast<O::CKGroup*>(ctx->GetObjectByNameAndClass(name, C::CK_CLASSID::CKCID_GROUP, nullptr));
}

View File

@@ -30,11 +30,19 @@ namespace BMapInspector::Rule::Shared {
#pragma region Check Functions
/**
* @brief Check whether given 2 float point values are equal with given tolerance.
* @param lhs
* @param rhs
* @param tolerance
* @return
*/
bool FPEqual(L::CKFLOAT lhs, L::CKFLOAT rhs, L::CKFLOAT tolerance);
/**
* @brief
* @param[in] ctx Can not be nullptr.
* @param[in] name Can not be nullptr.
* @return
* @return Found pointer to CKGroup, otherwise nullptr.
*/
O::CKGroup* FetchGroup(C::CKContext* ctx, L::CKSTRING name);
std::vector<O::CK3dObject*> FetchPhysicalized3dObjects(C::CKContext* ctx);