2023-09-21 13:47:30 +08:00
|
|
|
#include "BMExports.hpp"
|
2023-09-23 15:55:57 +08:00
|
|
|
#include <IronPad.hpp>
|
|
|
|
#include <set>
|
2023-10-03 21:33:00 +08:00
|
|
|
#include <type_traits>
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
#pragma region Help & Save Functions
|
2023-09-23 15:55:57 +08:00
|
|
|
|
2023-10-02 20:54:31 +08:00
|
|
|
static bool g_IsInited = false;
|
2023-09-23 15:55:57 +08:00
|
|
|
static std::set<BMap::BMFile*> g_AllBMFiles = std::set<BMap::BMFile*>();
|
2023-10-02 20:54:31 +08:00
|
|
|
static std::set<BMap::BMMeshTransition*> g_AllBMMeshTrans = std::set<BMap::BMMeshTransition*>();
|
2023-09-21 13:47:30 +08:00
|
|
|
|
2023-10-03 21:33:00 +08:00
|
|
|
bool CheckInited() {
|
|
|
|
return g_IsInited;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CheckBMFile(BMap::BMFile* possible_bmfile) {
|
|
|
|
return (g_IsInited && possible_bmfile != nullptr && g_AllBMFiles.contains(possible_bmfile));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CheckBMMeshTrans(BMap::BMMeshTransition* possible_trans) {
|
|
|
|
return (g_IsInited && possible_trans != nullptr && g_AllBMMeshTrans.contains(possible_trans));
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Ty, std::enable_if_t<std::is_pointer_v<_Ty>, int> = 0>
|
|
|
|
_Ty CheckCKObject(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
|
|
|
|
LibCmo::CK2::ObjImpls::CKObject* obj = possible_bmfile->GetObjectPtr(possible_id);
|
|
|
|
// check id validation and class id
|
|
|
|
if (obj == nullptr || LibCmo::CK2::CKIsChildClassOf(obj->GetClassID(), expected_cid)) return nullptr;
|
|
|
|
|
|
|
|
return static_cast<_Ty>(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma endregion
|
|
|
|
|
2023-09-21 13:47:30 +08:00
|
|
|
void BMInit() {
|
2023-09-23 15:55:57 +08:00
|
|
|
// register IronPad
|
|
|
|
IronPad::IronPadRegister();
|
|
|
|
// and startup CK environment
|
|
|
|
LibCmo::CK2::CKStartUp();
|
2023-10-03 21:33:00 +08:00
|
|
|
|
2023-10-02 20:54:31 +08:00
|
|
|
// set init
|
|
|
|
g_IsInited = true;
|
2023-09-21 13:47:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void BMDispose() {
|
2023-09-23 15:55:57 +08:00
|
|
|
// free all existed file reader / writer
|
|
|
|
for (auto ptr : g_AllBMFiles) {
|
|
|
|
delete ptr;
|
|
|
|
}
|
|
|
|
g_AllBMFiles.clear();
|
2023-10-02 20:54:31 +08:00
|
|
|
// free all mesh transition
|
|
|
|
for (auto ptr : g_AllBMMeshTrans) {
|
|
|
|
delete ptr;
|
|
|
|
}
|
|
|
|
g_AllBMMeshTrans.clear();
|
|
|
|
|
|
|
|
// disable init
|
|
|
|
g_IsInited = false;
|
2023-10-03 21:33:00 +08:00
|
|
|
|
2023-09-23 15:55:57 +08:00
|
|
|
// shutdown CK environment
|
|
|
|
LibCmo::CK2::CKShutdown();
|
|
|
|
// unregister iron pad
|
|
|
|
IronPad::IronPadUnregister();
|
2023-09-21 13:47:30 +08:00
|
|
|
}
|
2023-09-23 16:25:26 +08:00
|
|
|
|
2023-10-02 20:54:31 +08:00
|
|
|
#pragma region BMFile
|
|
|
|
|
2023-09-23 16:25:26 +08:00
|
|
|
BMap::BMFile* BMFile_Load(LibCmo::CKSTRING file_name, LibCmo::CKSTRING temp_folder, LibCmo::CKSTRING texture_folder, LibCmo::CKDWORD encoding_count, LibCmo::CKSTRING encodings[]) {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckInited()) return nullptr;
|
2023-09-23 16:25:26 +08:00
|
|
|
|
2023-10-03 21:33:00 +08:00
|
|
|
// create a now one and try to load data.
|
|
|
|
std::unique_ptr<BMap::BMFile> file(new BMap::BMFile(temp_folder, texture_folder, encoding_count, encodings, false));
|
|
|
|
if (file->IsFreezed()) return nullptr;
|
|
|
|
if (!file->Load(file_name)) return nullptr;
|
|
|
|
|
|
|
|
// add into list and return
|
|
|
|
g_AllBMFiles.emplace(file.get());
|
|
|
|
return file.release();
|
2023-09-23 16:25:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
BMap::BMFile* BMFile_Create(LibCmo::CKSTRING temp_folder, LibCmo::CKSTRING texture_folder, LibCmo::CKDWORD encoding_count, LibCmo::CKSTRING encodings[]) {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckInited()) return nullptr;
|
|
|
|
|
|
|
|
// create a now one
|
|
|
|
std::unique_ptr<BMap::BMFile> file(new BMap::BMFile(temp_folder, texture_folder, encoding_count, encodings, false));
|
|
|
|
if (file->IsFreezed()) return nullptr;
|
2023-09-23 16:25:26 +08:00
|
|
|
|
2023-10-03 21:33:00 +08:00
|
|
|
// add into list and return if success
|
|
|
|
g_AllBMFiles.emplace(file.get());
|
|
|
|
return file.release();
|
2023-09-23 16:25:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool BMFile_Save(BMap::BMFile* map_file, LibCmo::CKSTRING file_name, LibCmo::CKINT compreess_level) {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckBMFile(map_file)) return false;
|
|
|
|
|
2023-09-23 16:25:26 +08:00
|
|
|
return map_file->Save(file_name, compreess_level);
|
|
|
|
}
|
|
|
|
|
2023-10-03 21:33:00 +08:00
|
|
|
bool BMFile_Free(BMap::BMFile* map_file) {
|
|
|
|
if (!CheckBMFile(map_file)) return false;
|
2023-10-02 20:54:31 +08:00
|
|
|
|
2023-10-03 21:33:00 +08:00
|
|
|
g_AllBMFiles.erase(map_file);
|
|
|
|
delete map_file;
|
|
|
|
return true;
|
2023-10-02 20:54:31 +08:00
|
|
|
}
|
|
|
|
|
2023-10-03 21:33:00 +08:00
|
|
|
LibCmo::CKDWORD BMFile_GetGroupCount(BMap::BMFile* bmfile) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->GetGroupCount();
|
|
|
|
}
|
|
|
|
LibCmo::CK2::CK_ID BMFile_GetGroup(BMap::BMFile* bmfile, LibCmo::CKDWORD idx) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->GetGroup(idx);
|
|
|
|
}
|
|
|
|
LibCmo::CK2::CK_ID BMFile_CreateGroup(BMap::BMFile* bmfile, LibCmo::CKSTRING name) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->CreateGroup(name);
|
|
|
|
}
|
|
|
|
LibCmo::CKDWORD BMFile_Get3dObjectCount(BMap::BMFile* bmfile) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->Get3dObjectCount();
|
|
|
|
}
|
|
|
|
LibCmo::CK2::CK_ID BMFile_Get3dObject(BMap::BMFile* bmfile, LibCmo::CKDWORD idx) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->Get3dObject(idx);
|
|
|
|
}
|
|
|
|
LibCmo::CK2::CK_ID BMFile_Create3dObject(BMap::BMFile* bmfile, LibCmo::CKSTRING name) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->Create3dObject(name);
|
|
|
|
}
|
|
|
|
LibCmo::CKDWORD BMFile_GetMeshCount(BMap::BMFile* bmfile) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->GetMeshCount();
|
|
|
|
}
|
|
|
|
LibCmo::CK2::CK_ID BMFile_GetMesh(BMap::BMFile* bmfile, LibCmo::CKDWORD idx) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->GetMesh(idx);
|
|
|
|
}
|
|
|
|
LibCmo::CK2::CK_ID BMFile_CreateMesh(BMap::BMFile* bmfile, LibCmo::CKSTRING name) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->CreateMesh(name);
|
|
|
|
}
|
|
|
|
LibCmo::CKDWORD BMFile_GetMaterialCount(BMap::BMFile* bmfile) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->GetMaterialCount();
|
|
|
|
}
|
|
|
|
LibCmo::CK2::CK_ID BMFile_GetMaterial(BMap::BMFile* bmfile, LibCmo::CKDWORD idx) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->GetMaterial(idx);
|
|
|
|
}
|
|
|
|
LibCmo::CK2::CK_ID BMFile_CreateMaterial(BMap::BMFile* bmfile, LibCmo::CKSTRING name) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->CreateMaterial(name);
|
|
|
|
}
|
|
|
|
LibCmo::CKDWORD BMFile_GetTextureCount(BMap::BMFile* bmfile) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->GetTextureCount();
|
|
|
|
}
|
|
|
|
LibCmo::CK2::CK_ID BMFile_GetTexture(BMap::BMFile* bmfile, LibCmo::CKDWORD idx) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->GetTexture(idx);
|
|
|
|
}
|
|
|
|
LibCmo::CK2::CK_ID BMFile_CreateTexture(BMap::BMFile* bmfile, LibCmo::CKSTRING name) {
|
|
|
|
if (!CheckBMFile(bmfile)) return 0;
|
|
|
|
return bmfile->CreateTexture(name);
|
|
|
|
}
|
2023-10-02 20:54:31 +08:00
|
|
|
|
|
|
|
#pragma endregion
|
|
|
|
|
|
|
|
#pragma region BMMeshTransition
|
|
|
|
|
|
|
|
BMap::BMMeshTransition* BMMeshTrans_New() {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckInited()) return nullptr;
|
|
|
|
|
|
|
|
// create new one, insert and return.
|
2023-10-02 20:54:31 +08:00
|
|
|
auto meshtrans = new BMap::BMMeshTransition();
|
|
|
|
g_AllBMMeshTrans.emplace(meshtrans);
|
|
|
|
return meshtrans;
|
|
|
|
}
|
|
|
|
|
2023-10-03 21:33:00 +08:00
|
|
|
bool BMMeshTrans_Delete(BMap::BMMeshTransition* trans) {
|
|
|
|
if (!CheckBMMeshTrans(trans)) return false;
|
|
|
|
|
|
|
|
g_AllBMMeshTrans.erase(trans);
|
|
|
|
delete trans;
|
|
|
|
return true;
|
2023-10-02 20:54:31 +08:00
|
|
|
}
|
|
|
|
|
2023-10-03 21:33:00 +08:00
|
|
|
bool BMMeshTrans_PrepareVertexCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) {
|
|
|
|
if (!CheckBMMeshTrans(trans)) return false;
|
|
|
|
return trans->PrepareVertexCount(count);
|
2023-10-02 20:54:31 +08:00
|
|
|
}
|
|
|
|
LibCmo::VxMath::VxVector3* BMMeshTrans_PrepareVertex(BMap::BMMeshTransition* trans) {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckBMMeshTrans(trans)) return nullptr;
|
2023-10-02 20:54:31 +08:00
|
|
|
return trans->PrepareVertex();
|
|
|
|
}
|
2023-10-03 21:33:00 +08:00
|
|
|
bool BMMeshTrans_PrepareNormalCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) {
|
|
|
|
if (!CheckBMMeshTrans(trans)) return false;
|
|
|
|
return trans->PrepareNormalCount(count);
|
2023-10-02 20:54:31 +08:00
|
|
|
}
|
|
|
|
LibCmo::VxMath::VxVector3* BMMeshTrans_PrepareNormal(BMap::BMMeshTransition* trans) {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckBMMeshTrans(trans)) return nullptr;
|
2023-10-02 20:54:31 +08:00
|
|
|
return trans->PrepareNormal();
|
|
|
|
}
|
2023-10-03 21:33:00 +08:00
|
|
|
bool BMMeshTrans_PrepareUVCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) {
|
|
|
|
if (!CheckBMMeshTrans(trans)) return false;
|
|
|
|
return trans->PrepareUVCount(count);
|
2023-10-02 20:54:31 +08:00
|
|
|
}
|
|
|
|
LibCmo::VxMath::VxVector2* BMMeshTrans_PrepareUV(BMap::BMMeshTransition* trans) {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckBMMeshTrans(trans)) return nullptr;
|
2023-10-02 20:54:31 +08:00
|
|
|
return trans->PrepareUV();
|
|
|
|
}
|
2023-10-03 21:33:00 +08:00
|
|
|
bool BMMeshTrans_PrepareMtlSlotCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) {
|
|
|
|
if (!CheckBMMeshTrans(trans)) return false;
|
|
|
|
return trans->PrepareMtlSlotCount(count);
|
2023-10-02 20:54:31 +08:00
|
|
|
}
|
|
|
|
LibCmo::CK2::ObjImpls::CKMaterial** BMMeshTrans_PrepareMtlSlot(BMap::BMMeshTransition* trans) {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckBMMeshTrans(trans)) return nullptr;
|
2023-10-02 20:54:31 +08:00
|
|
|
return trans->PrepareMtlSlot();
|
|
|
|
}
|
2023-10-03 21:33:00 +08:00
|
|
|
bool BMMeshTrans_PrepareFaceCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) {
|
|
|
|
if (!CheckBMMeshTrans(trans)) return false;
|
|
|
|
return trans->PrepareFaceCount(count);
|
2023-10-02 20:54:31 +08:00
|
|
|
}
|
|
|
|
LibCmo::CKDWORD* BMMeshTrans_PrepareFaceVertexIndices(BMap::BMMeshTransition* trans) {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckBMMeshTrans(trans)) return nullptr;
|
2023-10-02 20:54:31 +08:00
|
|
|
return trans->PrepareFaceVertexIndices();
|
|
|
|
}
|
|
|
|
LibCmo::CKDWORD* BMMeshTrans_PrepareFaceNormalIndices(BMap::BMMeshTransition* trans) {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckBMMeshTrans(trans)) return nullptr;
|
2023-10-02 20:54:31 +08:00
|
|
|
return trans->PrepareFaceNormalIndices();
|
|
|
|
}
|
|
|
|
LibCmo::CKDWORD* BMMeshTrans_PrepareFaceUVIndices(BMap::BMMeshTransition* trans) {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckBMMeshTrans(trans)) return nullptr;
|
2023-10-02 20:54:31 +08:00
|
|
|
return trans->PrepareFaceUVIndices();
|
|
|
|
}
|
|
|
|
LibCmo::CKDWORD* BMMeshTrans_PrepareFaceMtlSlot(BMap::BMMeshTransition* trans) {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckBMMeshTrans(trans)) return nullptr;
|
2023-10-02 20:54:31 +08:00
|
|
|
return trans->PrepareFaceMtlSlot();
|
|
|
|
}
|
|
|
|
bool BMMeshTrans_Parse(BMap::BMMeshTransition* trans, LibCmo::CK2::ObjImpls::CKMesh* write_into_mesh) {
|
2023-10-03 21:33:00 +08:00
|
|
|
if (!CheckBMMeshTrans(trans)) return false;
|
2023-10-02 20:54:31 +08:00
|
|
|
return trans->Parse(write_into_mesh);
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma endregion
|
|
|
|
|