diff --git a/BMap/BMExports.cpp b/BMap/BMExports.cpp index c4f7885..ac4e6b0 100644 --- a/BMap/BMExports.cpp +++ b/BMap/BMExports.cpp @@ -6,6 +6,12 @@ #pragma region Help & Save Functions +static constexpr const LibCmo::CK2::CK_ID INVALID_CKID = 0; +static LibCmo::CK2::CK_ID SafeGetID(LibCmo::CK2::ObjImpls::CKObject* obj) { + if (obj == nullptr) return INVALID_CKID; + else return obj->GetID(); +} + static bool g_IsInited = false; static std::set g_AllBMFiles = std::set(); static std::set g_AllBMMeshTrans = std::set(); @@ -23,7 +29,7 @@ bool CheckBMMeshTrans(BMap::BMMeshTransition* possible_trans) { } template, int> = 0> -_Ty CheckCKObject(BMap::BMFile* possible_bmfile, LibCmo::CK2::CK_ID possible_id, LibCmo::CK2::CK_CLASSID expected_cid) { +_Ty CheckGeneralObject(BMap::BMFile* possible_bmfile, LibCmo::CK2::CK_ID possible_id, LibCmo::CK2::CK_CLASSID expected_cid) { // check bm file self. if (!CheckBMFile(possible_bmfile)) return nullptr; // check id @@ -34,6 +40,14 @@ _Ty CheckCKObject(BMap::BMFile* possible_bmfile, LibCmo::CK2::CK_ID possible_id, return static_cast<_Ty>(obj); } +#define CheckCKObject(bmfile, objid) CheckGeneralObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_OBJECT) +//#define CheckCKBeObject(bmfile, objid) CheckGeneralObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_BEOBJECT) +#define CheckCKGroup(bmfile, objid) CheckGeneralObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_GROUP) +#define CheckCK3dObject(bmfile, objid) CheckGeneralObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT) +#define CheckCKMesh(bmfile, objid) CheckGeneralObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_MESH) +#define CheckCKMaterial(bmfile, objid) CheckGeneralObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_MATERIAL) +#define CheckCKTexture(bmfile, objid) CheckGeneralObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE) + #pragma endregion void BMInit() { @@ -251,14 +265,14 @@ bool BMMeshTrans_Parse(BMap::BMMeshTransition* trans, LibCmo::CK2::ObjImpls::CKM #pragma region CKObject -LibCmo::CKSTRING BMCKObject_GetName(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid) { - auto obj = CheckCKObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_OBJECT); +LibCmo::CKSTRING BMObject_GetName(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid) { + auto obj = CheckCKObject(bmfile, objid); if (obj == nullptr) return nullptr; return obj->GetName(); } -bool BMCKObject_SetName(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CKSTRING name) { - auto obj = CheckCKObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_OBJECT); +bool BMObject_SetName(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CKSTRING name) { + auto obj = CheckCKObject(bmfile, objid); if (obj == nullptr) return false; obj->SetName(name); return true; @@ -268,27 +282,25 @@ bool BMCKObject_SetName(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo:: #pragma region CKGroup -bool BMCKGroup_AddObject(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CK2::CK_ID memberid) { - auto obj = CheckCKObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_GROUP); - auto memberobj = CheckCKObject(bmfile, memberid, LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT); +bool BMGroup_AddObject(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CK2::CK_ID memberid) { + auto obj = CheckCKGroup(bmfile, objid); + auto memberobj = CheckCK3dObject(bmfile, memberid); if (obj == nullptr || memberobj == nullptr) return false; return obj->AddObject(memberobj) == LibCmo::CK2::CKERROR::CKERR_OK; } -LibCmo::CKDWORD BMCKGroup_GetObjectCount(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid) { - auto obj = CheckCKObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_GROUP); +LibCmo::CKDWORD BMGroup_GetObjectCount(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid) { + auto obj = CheckCKGroup(bmfile, objid); if (obj == nullptr) return false; return obj->GetObjectCount(); } -LibCmo::CK2::CK_ID BMCKGroup_GetObject(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CKDWORD pos) { - auto obj = CheckCKObject(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_GROUP); +LibCmo::CK2::CK_ID BMGroup_GetObject(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CKDWORD pos) { + auto obj = CheckCKGroup(bmfile, objid); if (obj == nullptr) return 0; - auto cache = obj->GetObject(pos); - if (cache == nullptr) return 0; - return cache->GetID(); + return SafeGetID(obj->GetObject(pos)); } #pragma endregion @@ -307,5 +319,58 @@ LibCmo::CK2::CK_ID BMCKGroup_GetObject(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID #pragma region CK3dObject +CStyleVxMatrix BM3dEntity_GetWorldMatrix(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid) { + CStyleVxMatrix result; + auto obj = CheckCK3dObject(bmfile, objid); + if (obj == nullptr) { + result.FromVxMatrix(LibCmo::VxMath::VxMatrix()); + } else { + result.FromVxMatrix(obj->GetWorldMatrix()); + } + + return result; +} + +bool BM3dEntity_SetWorldMatrix(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, CStyleVxMatrix mat) { + auto obj = CheckCK3dObject(bmfile, objid); + if (obj == nullptr) return false; + + LibCmo::VxMath::VxMatrix cppmat; + mat.ToVxMatrix(cppmat); + obj->SetWorldMatrix(cppmat); + return true; +} + +LibCmo::CK2::CK_ID BM3dEntity_GetCurrentMesh(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid) { + auto obj = CheckCK3dObject(bmfile, objid); + if (obj == nullptr) return 0; + + return SafeGetID(obj->GetCurrentMesh()); +} + +bool BM3dEntity_SetCurrentMesh(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CK2::CK_ID meshid) { + auto obj = CheckCK3dObject(bmfile, objid); + auto meshobj = CheckCKMesh(bmfile, meshid); + if (obj == nullptr || meshobj == nullptr) return false; + + obj->SetCurrentMesh(meshobj); + return true; +} + +bool BM3dEntity_GetVisivility(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid) { + auto obj = CheckCK3dObject(bmfile, objid); + if (obj == nullptr) return false; + + return obj->IsVisible(); +} + +bool BM3dEntity_SetVisivility(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, bool is_visible) { + auto obj = CheckCK3dObject(bmfile, objid); + if (obj == nullptr) return false; + + obj->Show(is_visible ? LibCmo::CK2::CK_OBJECT_SHOWOPTION::CKSHOW : LibCmo::CK2::CK_OBJECT_SHOWOPTION::CKHIDE); + return true; +} + #pragma endregion diff --git a/BMap/BMExports.hpp b/BMap/BMExports.hpp index 3840d2b..2ae1567 100644 --- a/BMap/BMExports.hpp +++ b/BMap/BMExports.hpp @@ -1,6 +1,7 @@ #pragma once #include "BMap.hpp" +#include /* Design Note: @@ -71,16 +72,16 @@ LIBCMO_EXPORT bool BMMeshTrans_Parse(BMap::BMMeshTransition* trans, LibCmo::CK2: #pragma region CKObject -LIBCMO_EXPORT LibCmo::CKSTRING BMCKObject_GetName(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid); -LIBCMO_EXPORT bool BMCKObject_SetName(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CKSTRING name); +LIBCMO_EXPORT LibCmo::CKSTRING BMObject_GetName(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid); +LIBCMO_EXPORT bool BMObject_SetName(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CKSTRING name); #pragma endregion #pragma region CKGroup -LIBCMO_EXPORT bool BMCKGroup_AddObject(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CK2::CK_ID memberid); -LIBCMO_EXPORT LibCmo::CKDWORD BMCKGroup_GetObjectCount(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid); -LIBCMO_EXPORT LibCmo::CK2::CK_ID BMCKGroup_GetObject(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CKDWORD pos); +LIBCMO_EXPORT bool BMGroup_AddObject(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CK2::CK_ID memberid); +LIBCMO_EXPORT LibCmo::CKDWORD BMGroup_GetObjectCount(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid); +LIBCMO_EXPORT LibCmo::CK2::CK_ID BMGroup_GetObject(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CKDWORD pos); #pragma endregion @@ -98,4 +99,22 @@ LIBCMO_EXPORT LibCmo::CK2::CK_ID BMCKGroup_GetObject(BMap::BMFile* bmfile, LibCm #pragma region CK3dObject +// This struct is designed to prevent C4190 warning +struct CStyleVxMatrix { + LibCmo::CKBYTE placeholder[sizeof(LibCmo::VxMath::VxMatrix)]; + void FromVxMatrix(const LibCmo::VxMath::VxMatrix& mat) { + std::memcpy(this, &mat, std::min(sizeof(LibCmo::VxMath::VxMatrix), sizeof(CStyleVxMatrix))); + } + void ToVxMatrix(LibCmo::VxMath::VxMatrix& mat) { + std::memcpy(&mat, this, std::min(sizeof(LibCmo::VxMath::VxMatrix), sizeof(CStyleVxMatrix))); + } +}; + +LIBCMO_EXPORT CStyleVxMatrix BM3dEntity_GetWorldMatrix(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid); +LIBCMO_EXPORT bool BM3dEntity_SetWorldMatrix(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, CStyleVxMatrix mat); +LIBCMO_EXPORT LibCmo::CK2::CK_ID BM3dEntity_GetCurrentMesh(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid); +LIBCMO_EXPORT bool BM3dEntity_SetCurrentMesh(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, LibCmo::CK2::CK_ID meshid); +LIBCMO_EXPORT bool BM3dEntity_GetVisivility(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid); +LIBCMO_EXPORT bool BM3dEntity_SetVisivility(BMap::BMFile* bmfile, LibCmo::CK2::CK_ID objid, bool is_visible); + #pragma endregion