From 1eb9d3f8052e9b31a847c74695a0ec184e2a780a Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Thu, 5 Feb 2026 14:12:16 +0800 Subject: [PATCH] feat: add camera support for BMap --- Ballance/BMap/BMap/BMExports.cpp | 114 +++++++++++++++++++++++ Ballance/BMap/BMap/BMExports.hpp | 33 +++++++ Ballance/BMap/BMap/BMap.cpp | 29 ++++-- Ballance/BMap/BMap/BMap.hpp | 4 + Ballance/BMapInspector/Rule/YYCRules.cpp | 2 +- 5 files changed, 171 insertions(+), 11 deletions(-) diff --git a/Ballance/BMap/BMap/BMExports.cpp b/Ballance/BMap/BMap/BMExports.cpp index 1c269a5..db8464b 100644 --- a/Ballance/BMap/BMap/BMExports.cpp +++ b/Ballance/BMap/BMap/BMExports.cpp @@ -51,9 +51,13 @@ T CheckGenericObject(BMap::BMFile* possible_bmfile, LibCmo::CK2::CK_ID possible_ #define CheckCKTexture(bmfile, objid) CheckGenericObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE) #define CheckCKLight(bmfile, objid) CheckGenericObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_LIGHT) #define CheckCKTargetLight(bmfile, objid) CheckGenericObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_TARGETLIGHT) +#define CheckCKCamera(bmfile, objid) CheckGenericObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_CAMERA) +#define CheckCKTargetCamera(bmfile, objid) CheckGenericObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_TARGETCAMERA) #pragma endregion +// clang-format off + #pragma region Module Init & Dispose bool BMInit() { @@ -254,6 +258,21 @@ bool BMFile_CreateTargetLight(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2 BMPARAM_OUT_ASSIGN(out_id, bmfile->CreateTargetLight()); return true; } +bool BMFile_GetTargetCameraCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count)) { + if (!CheckBMFile(bmfile)) return false; + BMPARAM_OUT_ASSIGN(out_count, bmfile->GetTargetCameraCount()); + return true; +} +bool BMFile_GetTargetCamera(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id)) { + if (!CheckBMFile(bmfile)) return false; + BMPARAM_OUT_ASSIGN(out_id, bmfile->GetTargetCamera(idx)); + return true; +} +bool BMFile_CreateTargetCamera(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id)) { + if (!CheckBMFile(bmfile)) return false; + BMPARAM_OUT_ASSIGN(out_id, bmfile->CreateTargetCamera()); + return true; +} #pragma endregion @@ -1042,3 +1061,98 @@ bool BMLight_SetFalloffShape(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibC // nothing #pragma endregion + +#pragma region CKCamera + +bool BMCamera_GetProjectionType(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_CAMERA_PROJECTION, out_val)) { + auto obj = CheckCKCamera(bmfile, objid); + if (obj == nullptr) return false; + + BMPARAM_OUT_ASSIGN(out_val, obj->GetProjectionType()); + return true; +} +bool BMCamera_SetProjectionType(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_CAMERA_PROJECTION, val)) { + auto obj = CheckCKCamera(bmfile, objid); + if (obj == nullptr) return false; + + obj->SetProjectionType(val); + return true; +} + +bool BMCamera_GetOrthographicZoom(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)) { + auto obj = CheckCKCamera(bmfile, objid); + if (obj == nullptr) return false; + BMPARAM_OUT_ASSIGN(out_val, obj->GetOrthographicZoom()); + return true; +} +bool BMCamera_SetOrthographicZoom(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)) { + auto obj = CheckCKCamera(bmfile, objid); + if (obj == nullptr) return false; + obj->SetOrthographicZoom(val); + return true; +} + +bool BMCamera_GetFrontPlane(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)) { + auto obj = CheckCKCamera(bmfile, objid); + if (obj == nullptr) return false; + BMPARAM_OUT_ASSIGN(out_val, obj->GetFrontPlane()); + return true; +} +bool BMCamera_SetFrontPlane(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)) { + auto obj = CheckCKCamera(bmfile, objid); + if (obj == nullptr) return false; + obj->SetFrontPlane(val); + return true; +} +bool BMCamera_GetBackPlane(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)) { + auto obj = CheckCKCamera(bmfile, objid); + if (obj == nullptr) return false; + BMPARAM_OUT_ASSIGN(out_val, obj->GetFrontPlane()); + return true; +} +bool BMCamera_SetBackPlane(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)) { + auto obj = CheckCKCamera(bmfile, objid); + if (obj == nullptr) return false; + obj->SetBackPlane(val); + return true; +} +bool BMCamera_GetFov(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)) { + auto obj = CheckCKCamera(bmfile, objid); + if (obj == nullptr) return false; + BMPARAM_OUT_ASSIGN(out_val, obj->GetFrontPlane()); + return true; +} +bool BMCamera_SetFov(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)) { + auto obj = CheckCKCamera(bmfile, objid); + if (obj == nullptr) return false; + obj->SetFov(val); + return true; +} + +bool BMCamera_GetAspectRatio(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKDWORD, out_width), BMPARAM_OUT(LibCmo::CKDWORD, out_height)) { + auto obj = CheckCKCamera(bmfile, objid); + if (obj == nullptr) return false; + + LibCmo::CKDWORD cache_width, cache_height; + obj->GetAspectRatio(cache_width, cache_height); + BMPARAM_OUT_ASSIGN(out_width, cache_width); + BMPARAM_OUT_ASSIGN(out_height, cache_height); + + return true; +} +bool BMCamera_SetAspectRatio(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, width), BMPARAM_IN(LibCmo::CKDWORD, height)) { + auto obj = CheckCKCamera(bmfile, objid); + if (obj == nullptr) return false; + obj->SetAspectRatio(width, height); + return true; +} + +#pragma endregion + +#pragma region CKTargetCamera + +// nothing + +#pragma endregion + +// clang-format on diff --git a/Ballance/BMap/BMap/BMExports.hpp b/Ballance/BMap/BMap/BMExports.hpp index f30d1aa..6eeec1b 100644 --- a/Ballance/BMap/BMap/BMExports.hpp +++ b/Ballance/BMap/BMap/BMExports.hpp @@ -104,6 +104,8 @@ bool some_interface_func(BMPARAM_OUT(Type_t, param_name)) { #pragma endregion +// clang-format off + #pragma region Init / Dispose BMAP_EXPORT bool BMInit(); @@ -159,6 +161,9 @@ BMAP_EXPORT bool BMFile_CreateTexture(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(Lib BMAP_EXPORT bool BMFile_GetTargetLightCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count)); BMAP_EXPORT bool BMFile_GetTargetLight(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id)); BMAP_EXPORT bool BMFile_CreateTargetLight(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id)); +BMAP_EXPORT bool BMFile_GetTargetCameraCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count)); +BMAP_EXPORT bool BMFile_GetTargetCamera(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id)); +BMAP_EXPORT bool BMFile_CreateTargetCamera(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id)); #pragma endregion @@ -339,3 +344,31 @@ BMAP_EXPORT bool BMLight_SetFalloffShape(BMPARAM_OBJECT_DECL(bmfile, objid), BMP // nothing #pragma endregion + +#pragma region CKCamera + +BMAP_EXPORT bool BMCamera_GetProjectionType(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_CAMERA_PROJECTION, out_val)); +BMAP_EXPORT bool BMCamera_SetProjectionType(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_CAMERA_PROJECTION, val)); + +BMAP_EXPORT bool BMCamera_GetOrthographicZoom(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)); +BMAP_EXPORT bool BMCamera_SetOrthographicZoom(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)); + +BMAP_EXPORT bool BMCamera_GetFrontPlane(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)); +BMAP_EXPORT bool BMCamera_SetFrontPlane(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)); +BMAP_EXPORT bool BMCamera_GetBackPlane(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)); +BMAP_EXPORT bool BMCamera_SetBackPlane(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)); +BMAP_EXPORT bool BMCamera_GetFov(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)); +BMAP_EXPORT bool BMCamera_SetFov(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)); + +BMAP_EXPORT bool BMCamera_GetAspectRatio(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKDWORD, out_width), BMPARAM_OUT(LibCmo::CKDWORD, out_height)); +BMAP_EXPORT bool BMCamera_SetAspectRatio(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, width), BMPARAM_IN(LibCmo::CKDWORD, height)); + +#pragma endregion + +#pragma region CKTargetCamera + +// nothing + +#pragma endregion + +// clang-format on diff --git a/Ballance/BMap/BMap/BMap.cpp b/Ballance/BMap/BMap/BMap.cpp index c2e7da7..95eaa37 100644 --- a/Ballance/BMap/BMap/BMap.cpp +++ b/Ballance/BMap/BMap/BMap.cpp @@ -11,9 +11,7 @@ namespace BMap { // check whether callback is nullptr. m_IsInitError = m_IsInitError || (raw_callback == nullptr); if (raw_callback != nullptr) { - m_Context->SetOutputCallback([raw_callback](LibCmo::CKSTRING strl) -> void { - raw_callback(strl); - }); + m_Context->SetOutputCallback([raw_callback](LibCmo::CKSTRING strl) -> void { raw_callback(strl); }); } // set temp folder and texture folder @@ -89,28 +87,33 @@ namespace BMap { m_ObjMaterials.clear(); m_ObjTextures.clear(); m_ObjTargetLights.clear(); + m_ObjTargetCameras.clear(); for (const auto& fileobj : reader.GetFileObjects()) { if (fileobj.ObjPtr == nullptr) continue; + using LibCmo::CK2::CK_CLASSID; switch (fileobj.ObjectCid) { - case LibCmo::CK2::CK_CLASSID::CKCID_GROUP: + case CK_CLASSID::CKCID_GROUP: m_ObjGroups.emplace_back(fileobj.CreatedObjectId); break; - case LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT: + case CK_CLASSID::CKCID_3DOBJECT: m_Obj3dObjects.emplace_back(fileobj.CreatedObjectId); break; - case LibCmo::CK2::CK_CLASSID::CKCID_MESH: + case CK_CLASSID::CKCID_MESH: m_ObjMeshes.emplace_back(fileobj.CreatedObjectId); break; - case LibCmo::CK2::CK_CLASSID::CKCID_MATERIAL: + case CK_CLASSID::CKCID_MATERIAL: m_ObjMaterials.emplace_back(fileobj.CreatedObjectId); break; - case LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE: + case CK_CLASSID::CKCID_TEXTURE: m_ObjTextures.emplace_back(fileobj.CreatedObjectId); break; - case LibCmo::CK2::CK_CLASSID::CKCID_TARGETLIGHT: + case CK_CLASSID::CKCID_TARGETLIGHT: m_ObjTargetLights.emplace_back(fileobj.CreatedObjectId); break; + case CK_CLASSID::CKCID_TARGETCAMERA: + m_ObjTargetCameras.emplace_back(fileobj.CreatedObjectId); + break; default: break; // skip unknow objects } @@ -142,7 +145,10 @@ namespace BMap { for (const auto& id : m_ObjTextures) { writer.AddSavedObject(m_Context->GetObject(id)); } - for (const auto& id :m_ObjTargetLights) { + for (const auto& id : m_ObjTargetLights) { + writer.AddSavedObject(m_Context->GetObject(id)); + } + for (const auto& id : m_ObjTargetCameras) { writer.AddSavedObject(m_Context->GetObject(id)); } @@ -238,6 +244,9 @@ namespace BMap { LibCmo::CKDWORD BMFile::GetTargetLightCount() { return CommonGetObjectCount(m_ObjTargetLights); } LibCmo::CK2::CK_ID BMFile::GetTargetLight(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjTargetLights, idx); } LibCmo::CK2::CK_ID BMFile::CreateTargetLight() { return CommonCreateObject(m_ObjTargetLights, LibCmo::CK2::CK_CLASSID::CKCID_TARGETLIGHT); } + LibCmo::CKDWORD BMFile::GetTargetCameraCount() { return CommonGetObjectCount(m_ObjTargetCameras); } + LibCmo::CK2::CK_ID BMFile::GetTargetCamera(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjTargetCameras, idx); } + LibCmo::CK2::CK_ID BMFile::CreateTargetCamera() { return CommonCreateObject(m_ObjTargetCameras, LibCmo::CK2::CK_CLASSID::CKCID_TARGETCAMERA); } #pragma endregion diff --git a/Ballance/BMap/BMap/BMap.hpp b/Ballance/BMap/BMap/BMap.hpp index 2c5aa68..46f2922 100644 --- a/Ballance/BMap/BMap/BMap.hpp +++ b/Ballance/BMap/BMap/BMap.hpp @@ -126,6 +126,9 @@ namespace BMap { LibCmo::CKDWORD GetTargetLightCount(); LibCmo::CK2::CK_ID GetTargetLight(LibCmo::CKDWORD idx); LibCmo::CK2::CK_ID CreateTargetLight(); + LibCmo::CKDWORD GetTargetCameraCount(); + LibCmo::CK2::CK_ID GetTargetCamera(LibCmo::CKDWORD idx); + LibCmo::CK2::CK_ID CreateTargetCamera(); private: LibCmo::CK2::CKContext* m_Context; @@ -136,6 +139,7 @@ namespace BMap { std::vector m_ObjMaterials; std::vector m_ObjTextures; std::vector m_ObjTargetLights; + std::vector m_ObjTargetCameras; }; diff --git a/Ballance/BMapInspector/Rule/YYCRules.cpp b/Ballance/BMapInspector/Rule/YYCRules.cpp index 44ed6df..eabb7f3 100644 --- a/Ballance/BMapInspector/Rule/YYCRules.cpp +++ b/Ballance/BMapInspector/Rule/YYCRules.cpp @@ -48,7 +48,7 @@ namespace BMapInspector::Rule { // No, this is not rail texture, throw error. reporter.FormatError( YYC1, - u8R"(Object "%s" is grouped into Phys_FloorRails, but its texture "%s" (referred by mesh %s and material %s) seems not the rail texture. This will cause some parts of this object be smooth unexpectly.)", + u8R"(Object "%s" is grouped into Phys_FloorRails, but its texture "%s" (referred by mesh "%s" and material "%s") seems not the rail texture. This will cause some parts of this object be smooth unexpectly.)", Shared::RenderObjectName(group_3dobject), Shared::RenderObjectName(texture), Shared::RenderObjectName(mesh),