1
0

19 Commits

Author SHA1 Message Date
ff2600c8fb fix: fix libcom top headers 2026-01-24 17:49:59 +08:00
9228f343ff chore: change build script to make BMap can be used by CMake
- change script for installing BMap like LibCmo although no one will use it.
- move package install command into respective cmake script.
- change BMap project layout
2026-01-24 17:32:22 +08:00
f9ab66dfc2 chore: update build script
- change project layout for better understanding.
- update build script for more close to standard cmake way.
2026-01-24 17:16:13 +08:00
af6a50c2f9 feat: use cmdline args as the args of BMap bindings.
- update testbench of PyBMap and BMapSharp. use command line arguments as the arguments of testbench, instead of hardcoded variables in code.
2025-01-02 10:59:16 +08:00
0bf0519c4c fix: fix linux build issue
- use std::cos and std::sin instead of std::cosf and std::sinf. it seems that some linux environment do not have these 2 functions in std namespace.
2024-12-31 18:25:44 +08:00
c18ff8f2e3 fix: fix various issues.
- fix convertion loss in CKCamera.
- bump up version to 0.3.0
- use CMake to generate version info header.
- fix annotation about Dassault ComputeCRC error.
- change member field initialization value in CKLight.
2024-12-31 17:48:24 +08:00
fe4a58e864 feat: add CKLight support and apply BMap changes to Python and CSharp bindings.
- add CKLight and CKTargetLight in BMap bindings
- apply BMap changes, for example, the rename of BM3dObject_ prefix to BM3dEntity_, to BMap bindings.
2024-12-30 11:28:59 +08:00
eaeaf956b5 fix: fix type error in BMap type check macro. 2024-12-29 10:13:56 +08:00
6bb2421e1f feat: add CKLight into BMap.
- add CKLight support in BMap.
- move the implementation of BMFile into CPP file from HPP file.
- swap the order of the implementation of BMFile and BMMeshTransition to correspond with the order of their declaration.
- add document for some member functions of BMFile.
2024-12-29 10:05:13 +08:00
ead22d13ff fix: remove useless void in function parameter list
- according to c++ standard, single void in function parameter is equal to empty parameter list. for removing this syntax which may cause misunderstanding (becuase in C, they are different I guess), I replace all `(void)` to `()`.
2024-12-28 22:09:26 +08:00
aeb2e86b14 fix: fix the issue when loading new version created files.
- Fix the CRC check issue when loading new Virtools created files (> 4.0)
	* This is caused by a bug written by stupid Virtools programmer. For more detail, see code annotation.
	* After this patch, LibCmo have ability that load new Virtools created files including max2nmo exported NMO, Virtools 5.0 created CMO and etc.
2024-12-28 16:29:35 +08:00
86b27557c9 feat: add 4 new added classes in Unvirt.
- fix a fatal issue that make the output message from CKContext is empty.
- fix argument type error for CKCamera::GetAspect and CKCamera::SetAspect.
- add enums annotation and struct diaplay function in Unvirt for showing 4 new added classes.
2024-12-25 13:58:39 +08:00
eef3a352d9 feat: finish CKTargetCamera and CKTargetLight.
- finish all new added 4 classes, CKCamera, CKTargetCamera, CKLight, CKTargetLight. but no test.
2024-12-25 11:12:23 +08:00
b74f1b965c feat: finish CKCamera 2024-12-25 09:07:02 +08:00
c235524403 fix: fix 2 issues
- rename float to CKFLOAT in VxMatrix.
- move CKLightData struct to CKDefine.hpp because it not a private struct used by CKLight, but a CKRasterizer struct.
2024-12-25 08:28:42 +08:00
4bfc4782b5 refactor: refactor VxVector and its generator.
- refactor VxVector-like struct. split their declaration and implementatio because their implementation is too long. and occupy too much space in header.
- refactor VxVector struct generator. use jinja2 template engine, rather ran hand-written format string to make it is easy to read (although it still tough when first reading).
- add unary operator overloading for VxVector-like struct.
- add some VxMatrix functions which are essential to CKCamera.
- rename VxMatrix::ResetToIdentity to VxMatrix::SetIdentity to make it same as original Virtools SDK.
- the spaceship overloading with auto return value still may have bugs. please watch it carefully.
2024-12-24 23:37:04 +08:00
3eeb1f6cb6 feat: finish CKLight class.
- basically finish CKLight but no test now.
2024-12-24 10:59:19 +08:00
ff5a590cf4 feat: add basic layout for CKLight and CKCamera.
- add basic class layout and member function for CKLight and CKCamera.
- register CKLight and CKCamera in CKGlobals to let CK engine can recognize them.
- modify EnumsMigration to add new 2 enums for CKLight and CKCamera.
2024-12-23 22:21:50 +08:00
d29d40448b fix: fix CMake install path issue.
- fix the wrong reference in CMake script which install lib target into wrong directory.
- add file, change CMake script and modify header file for preparing develop of CKLight and CKCamera.
- fix doc typo.
2024-12-23 09:23:46 +08:00
114 changed files with 4046 additions and 2464 deletions

19
.gitignore vendored
View File

@@ -1,19 +1,24 @@
# -------------------- Personal -------------------- ## ======== Personal ========
# Ignore build resources
out/
build/
install/
extern/
temp/
# Ignore all possible test used Virtools files # Ignore all possible test used Virtools files
*.nmo *.nmo
*.cmo *.cmo
*.nms *.nms
*.vmo *.vmo
# Ignore temporary Visual Studio files and folders # Ignore CMake generated stuff
temp/
out/
CMakeSettings.json CMakeSettings.json
# -------------------- VSCode -------------------- ## ======== VSCode ========
.vscode/ .vscode/
# -------------------- CMake -------------------- ## ======== CMake ========
CMakeLists.txt.user CMakeLists.txt.user
CMakeCache.txt CMakeCache.txt
CMakeFiles CMakeFiles
@@ -26,7 +31,7 @@ compile_commands.json
CTestTestfile.cmake CTestTestfile.cmake
_deps _deps
# -------------------- Visual Studio -------------------- ## ======== Visual Studio ========
## Ignore Visual Studio temporary files, build results, and ## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons. ## files generated by popular Visual Studio add-ons.
## ##

View File

@@ -42,10 +42,13 @@ _Ty CheckGeneralObject(BMap::BMFile* possible_bmfile, LibCmo::CK2::CK_ID possibl
#define CheckCKObject(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CKObject*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_OBJECT) #define CheckCKObject(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CKObject*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_OBJECT)
#define CheckCKGroup(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CKGroup*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_GROUP) #define CheckCKGroup(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CKGroup*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_GROUP)
#define CheckCK3dEntity(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CK3dEntity*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_3DENTITY)
#define CheckCK3dObject(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CK3dObject*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT) #define CheckCK3dObject(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CK3dObject*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT)
#define CheckCKMesh(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CKMesh*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_MESH) #define CheckCKMesh(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CKMesh*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_MESH)
#define CheckCKMaterial(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CKMaterial*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_MATERIAL) #define CheckCKMaterial(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CKMaterial*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_MATERIAL)
#define CheckCKTexture(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CKTexture*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE) #define CheckCKTexture(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CKTexture*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE)
#define CheckCKLight(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CKLight*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_LIGHT)
#define CheckCKTargetLight(bmfile, objid) CheckGeneralObject<LibCmo::CK2::ObjImpls::CKTargetLight*>(bmfile, objid, LibCmo::CK2::CK_CLASSID::CKCID_TARGETLIGHT)
#pragma endregion #pragma endregion
@@ -143,7 +146,7 @@ bool BMFile_Create(
bool BMFile_Save( bool BMFile_Save(
BMPARAM_IN(BMap::BMFile*, map_file), BMPARAM_IN(BMap::BMFile*, map_file),
BMPARAM_IN(LibCmo::CKSTRING, file_name), BMPARAM_IN(LibCmo::CKSTRING, file_name),
BMPARAM_IN(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS, texture_save_opt), BMPARAM_IN(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS, texture_save_opt),
BMPARAM_IN(bool, use_compress), BMPARAM_IN(bool, use_compress),
BMPARAM_IN(LibCmo::CKINT, compreess_level)) { BMPARAM_IN(LibCmo::CKINT, compreess_level)) {
if (!CheckBMFile(map_file)) return false; if (!CheckBMFile(map_file)) return false;
@@ -234,6 +237,21 @@ bool BMFile_CreateTexture(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK
BMPARAM_OUT_ASSIGN(out_id, bmfile->CreateTexture()); BMPARAM_OUT_ASSIGN(out_id, bmfile->CreateTexture());
return true; return true;
} }
bool BMFile_GetTargetLightCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count)) {
if (!CheckBMFile(bmfile)) return false;
BMPARAM_OUT_ASSIGN(out_count, bmfile->GetTargetLightCount());
return true;
}
bool BMFile_GetTargetLight(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->GetTargetLight(idx));
return true;
}
bool BMFile_CreateTargetLight(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id)) {
if (!CheckBMFile(bmfile)) return false;
BMPARAM_OUT_ASSIGN(out_id, bmfile->CreateTargetLight());
return true;
}
#pragma endregion #pragma endregion
@@ -841,34 +859,34 @@ bool BMMesh_SetMaterialSlot(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCm
#pragma endregion #pragma endregion
#pragma region CK3dObject #pragma region CK3dEntity
bool BM3dObject_GetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxMatrix, out_mat)) { bool BM3dEntity_GetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxMatrix, out_mat)) {
auto obj = CheckCK3dObject(bmfile, objid); auto obj = CheckCK3dEntity(bmfile, objid);
if (obj == nullptr) return false; if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_mat, obj->GetWorldMatrix()); BMPARAM_OUT_ASSIGN(out_mat, obj->GetWorldMatrix());
return true; return true;
} }
bool BM3dObject_SetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxMatrix, mat)) { bool BM3dEntity_SetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxMatrix, mat)) {
auto obj = CheckCK3dObject(bmfile, objid); auto obj = CheckCK3dEntity(bmfile, objid);
if (obj == nullptr) return false; if (obj == nullptr) return false;
obj->SetWorldMatrix(mat); obj->SetWorldMatrix(mat);
return true; return true;
} }
bool BM3dObject_GetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_meshid)) { bool BM3dEntity_GetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_meshid)) {
auto obj = CheckCK3dObject(bmfile, objid); auto obj = CheckCK3dEntity(bmfile, objid);
if (obj == nullptr) return false; if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_meshid, SafeGetID(obj->GetCurrentMesh())); BMPARAM_OUT_ASSIGN(out_meshid, SafeGetID(obj->GetCurrentMesh()));
return true; return true;
} }
bool BM3dObject_SetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, meshid)) { bool BM3dEntity_SetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, meshid)) {
auto obj = CheckCK3dObject(bmfile, objid); auto obj = CheckCK3dEntity(bmfile, objid);
auto meshobj = CheckCKMesh(bmfile, meshid); auto meshobj = CheckCKMesh(bmfile, meshid);
if (obj == nullptr /*|| meshobj == nullptr*/) return false; //allow nullptr assign if (obj == nullptr /*|| meshobj == nullptr*/) return false; //allow nullptr assign
@@ -876,16 +894,16 @@ bool BM3dObject_SetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(Li
return true; return true;
} }
bool BM3dObject_GetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_isVisible)) { bool BM3dEntity_GetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_isVisible)) {
auto obj = CheckCK3dObject(bmfile, objid); auto obj = CheckCK3dEntity(bmfile, objid);
if (obj == nullptr) return false; if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_isVisible, obj->IsVisible()); BMPARAM_OUT_ASSIGN(out_isVisible, obj->IsVisible());
return true; return true;
} }
bool BM3dObject_SetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, is_visible)) { bool BM3dEntity_SetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, is_visible)) {
auto obj = CheckCK3dObject(bmfile, objid); auto obj = CheckCK3dEntity(bmfile, objid);
if (obj == nullptr) return false; if (obj == nullptr) return false;
obj->Show(is_visible ? LibCmo::CK2::CK_OBJECT_SHOWOPTION::CKSHOW : LibCmo::CK2::CK_OBJECT_SHOWOPTION::CKHIDE); obj->Show(is_visible ? LibCmo::CK2::CK_OBJECT_SHOWOPTION::CKSHOW : LibCmo::CK2::CK_OBJECT_SHOWOPTION::CKHIDE);
@@ -894,3 +912,131 @@ bool BM3dObject_SetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(boo
#pragma endregion #pragma endregion
#pragma region CK3dObject
//nothing
#pragma endregion
#pragma region CKLight
bool BMLight_GetType(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXLIGHT_TYPE, out_val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_val, obj->GetType());
return true;
}
bool BMLight_SetType(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXLIGHT_TYPE, val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
obj->SetType(val);
return true;
}
bool BMLight_GetColor(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxColor, out_val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_val, obj->GetColor());
return true;
}
bool BMLight_SetColor(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxColor, col)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
obj->SetColor(col);
return true;
}
bool BMLight_GetConstantAttenuation(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_val, obj->GetConstantAttenuation());
return true;
}
bool BMLight_SetConstantAttenuation(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
obj->SetConstantAttenuation(val);
return true;
}
bool BMLight_GetLinearAttenuation(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_val, obj->GetLinearAttenuation());
return true;
}
bool BMLight_SetLinearAttenuation(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
obj->SetLinearAttenuation(val);
return true;
}
bool BMLight_GetQuadraticAttenuation(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_val, obj->GetQuadraticAttenuation());
return true;
}
bool BMLight_SetQuadraticAttenuation(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
obj->SetQuadraticAttenuation(val);
return true;
}
bool BMLight_GetRange(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_val, obj->GetRange());
return true;
}
bool BMLight_SetRange(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
obj->SetRange(val);
return true;
}
bool BMLight_GetHotSpot(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_val, obj->GetHotSpot());
return true;
}
bool BMLight_SetHotSpot(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
obj->SetHotSpot(val);
return true;
}
bool BMLight_GetFalloff(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_val, obj->GetFalloff());
return true;
}
bool BMLight_SetFalloff(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
obj->SetFalloff(val);
return true;
}
bool BMLight_GetFalloffShape(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_val, obj->GetFalloffShape());
return true;
}
bool BMLight_SetFalloffShape(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val)) {
auto obj = CheckCKLight(bmfile, objid);
if (obj == nullptr) return false;
obj->SetFalloffShape(val);
return true;
}
#pragma endregion
#pragma region CKTargetLight
// nothing
#pragma endregion

View File

@@ -51,7 +51,7 @@ Each CK_ID also should be used with its corresponding BMFile*, because each BMfi
// Do nothing and hope for the best? // Do nothing and hope for the best?
#define BMAP_RAW_EXPORT #define BMAP_RAW_EXPORT
#define BMAP_RAW_IMPORT #define BMAP_RAW_IMPORT
#pragma error "Unknown dynamic link import/export semantics." #error "Unknown dynamic link import/export semantics."
#endif #endif
// Choosee import or export command according to special macro. // Choosee import or export command according to special macro.
@@ -81,7 +81,9 @@ Each CK_ID also should be used with its corresponding BMFile*, because each BMfi
/** Declare an input parameter */ /** Declare an input parameter */
#define BMPARAM_IN(_t, _name) _t _name #define BMPARAM_IN(_t, _name) _t _name
/** /**
@brief
Declare an output parameter. Declare an output parameter.
@details
A pointer will be added automatically for caller receive it. A pointer will be added automatically for caller receive it.
See BMPARAM_OUT_ASSIGN and BMPARAM_OUT_VAL to know how to use output param in function body. See BMPARAM_OUT_ASSIGN and BMPARAM_OUT_VAL to know how to use output param in function body.
@remark @remark
@@ -91,8 +93,8 @@ bool some_interface_func(BMPARAM_OUT(Type_t, param_name)) {
BMPARAM_OUT_ASSIGN(param_name, some_value); // assign to out param. BMPARAM_OUT_ASSIGN(param_name, some_value); // assign to out param.
return BMPARAM_OUT_VAL(param_name) != other_value; // use out param value. return BMPARAM_OUT_VAL(param_name) != other_value; // use out param value.
} }
@see BMPARAM_OUT_ASSIGN, BMPARAM_OUT_VAL
``` ```
@see BMPARAM_OUT_ASSIGN, BMPARAM_OUT_VAL
*/ */
#define BMPARAM_OUT(_t, _name) _t* _name #define BMPARAM_OUT(_t, _name) _t* _name
/** Assign value for out param in function body. */ /** Assign value for out param in function body. */
@@ -154,6 +156,9 @@ BMAP_EXPORT bool BMFile_CreateMaterial(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(Li
BMAP_EXPORT bool BMFile_GetTextureCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count)); BMAP_EXPORT bool BMFile_GetTextureCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
BMAP_EXPORT bool BMFile_GetTexture(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id)); BMAP_EXPORT bool BMFile_GetTexture(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
BMAP_EXPORT bool BMFile_CreateTexture(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id)); BMAP_EXPORT bool BMFile_CreateTexture(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
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));
#pragma endregion #pragma endregion
@@ -285,13 +290,52 @@ BMAP_EXPORT bool BMMesh_SetMaterialSlot(BMPARAM_OBJECT_DECL(bmfile, objid), BMPA
#pragma endregion #pragma endregion
#pragma region CK3dObject #pragma region CK3dEntity
BMAP_EXPORT bool BM3dObject_GetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxMatrix, out_mat)); BMAP_EXPORT bool BM3dEntity_GetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxMatrix, out_mat));
BMAP_EXPORT bool BM3dObject_SetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxMatrix, mat)); BMAP_EXPORT bool BM3dEntity_SetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxMatrix, mat));
BMAP_EXPORT bool BM3dObject_GetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_meshid)); BMAP_EXPORT bool BM3dEntity_GetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_meshid));
BMAP_EXPORT bool BM3dObject_SetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, meshid)); BMAP_EXPORT bool BM3dEntity_SetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, meshid));
BMAP_EXPORT bool BM3dObject_GetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_isVisible)); BMAP_EXPORT bool BM3dEntity_GetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_isVisible));
BMAP_EXPORT bool BM3dObject_SetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, is_visible)); BMAP_EXPORT bool BM3dEntity_SetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, is_visible));
#pragma endregion
#pragma region CK3dObject
// nothing
#pragma endregion
#pragma region CKLight
BMAP_EXPORT bool BMLight_GetType(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXLIGHT_TYPE, out_val));
BMAP_EXPORT bool BMLight_SetType(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXLIGHT_TYPE, val));
BMAP_EXPORT bool BMLight_GetColor(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxColor, out_val));
BMAP_EXPORT bool BMLight_SetColor(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxColor, col));
BMAP_EXPORT bool BMLight_GetConstantAttenuation(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val));
BMAP_EXPORT bool BMLight_SetConstantAttenuation(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val));
BMAP_EXPORT bool BMLight_GetLinearAttenuation(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val));
BMAP_EXPORT bool BMLight_SetLinearAttenuation(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val));
BMAP_EXPORT bool BMLight_GetQuadraticAttenuation(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val));
BMAP_EXPORT bool BMLight_SetQuadraticAttenuation(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val));
BMAP_EXPORT bool BMLight_GetRange(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val));
BMAP_EXPORT bool BMLight_SetRange(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val));
BMAP_EXPORT bool BMLight_GetHotSpot(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val));
BMAP_EXPORT bool BMLight_SetHotSpot(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val));
BMAP_EXPORT bool BMLight_GetFalloff(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val));
BMAP_EXPORT bool BMLight_SetFalloff(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val));
BMAP_EXPORT bool BMLight_GetFalloffShape(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val));
BMAP_EXPORT bool BMLight_SetFalloffShape(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val));
#pragma endregion
#pragma region CKTargetLight
// nothing
#pragma endregion #pragma endregion

View File

@@ -2,6 +2,247 @@
namespace BMap { namespace BMap {
#pragma region BMfile
BMFile::BMFile(LibCmo::CKSTRING temp_folder, LibCmo::CKSTRING texture_folder, NakedOutputCallback raw_callback, LibCmo::CKDWORD encoding_count, LibCmo::CKSTRING* encodings, bool is_loader) :
m_IsInitError(false), m_IsLoader(is_loader), m_HasLoaded(false), m_HasSaved(false), m_Context(nullptr) {
m_Context = new LibCmo::CK2::CKContext();
// binding callback with lambda wrapper.
// 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);
});
}
// set temp folder and texture folder
auto pm = m_Context->GetPathManager();
m_IsInitError = m_IsInitError || !pm->AddPath(texture_folder);
m_IsInitError = m_IsInitError || !pm->SetTempFolder(temp_folder);
// set encoding
LibCmo::XContainer::XArray<LibCmo::XContainer::XString> cache;
for (LibCmo::CKDWORD i = 0; i < encoding_count; ++i) {
if (encodings[i] != nullptr)
cache.emplace_back(encodings[i]);
}
m_Context->SetEncoding(cache);
m_IsInitError = m_IsInitError || !m_Context->IsValidEncoding();
// set default texture save mode is external
m_Context->SetGlobalImagesSaveOptions(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_EXTERNAL);
// set default file write mode is whole compressed
m_Context->SetFileWriteMode(LibCmo::CK2::CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED);
}
BMFile::~BMFile() {
delete m_Context;
}
#pragma region Safe Check Function
bool BMFile::IsInitError() {
return m_IsInitError;
}
bool BMFile::CanExecLoad() {
// no error, is loader, no prev load
return (!m_IsInitError && m_IsLoader && !m_HasLoaded);
}
bool BMFile::CanExecSave() {
// no error, is saver, no prev save
return (!m_IsInitError && !m_IsLoader && !m_HasSaved);
}
bool BMFile::CanExecLoaderVisitor() {
// no error, is loader, has loaded
return (!m_IsInitError && m_IsLoader && m_HasLoaded);
}
bool BMFile::CanExecSaverVisitor() {
// no error, is saver, not saveed yet
// same as CanExecSave
return (!m_IsInitError && !m_IsLoader && !m_HasSaved);
}
#pragma endregion
#pragma region Help Function
bool BMFile::Load(LibCmo::CKSTRING filename) {
if (!CanExecLoad()) return false;
// create temp ckfile and load
LibCmo::CK2::CKFileReader reader(m_Context);
LibCmo::CK2::CKERROR err = reader.DeepLoad(filename);
// detect error
if (err != LibCmo::CK2::CKERROR::CKERR_OK) {
// failed. clear document and return false
m_Context->ClearAll();
return false;
}
// sync data list to our list
m_ObjGroups.clear();
m_Obj3dObjects.clear();
m_ObjMeshes.clear();
m_ObjMaterials.clear();
m_ObjTextures.clear();
m_ObjTargetLights.clear();
for (const auto& fileobj : reader.GetFileObjects()) {
if (fileobj.ObjPtr == nullptr) continue;
switch (fileobj.ObjectCid) {
case LibCmo::CK2::CK_CLASSID::CKCID_GROUP:
m_ObjGroups.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT:
m_Obj3dObjects.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_MESH:
m_ObjMeshes.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_MATERIAL:
m_ObjMaterials.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE:
m_ObjTextures.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_TARGETLIGHT:
m_ObjTargetLights.emplace_back(fileobj.CreatedObjectId);
break;
default:
break; // skip unknow objects
}
}
m_HasLoaded = true;
return true;
}
bool BMFile::Save(LibCmo::CKSTRING filename, LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS texture_save_opt, bool use_compress, LibCmo::CKINT compress_level) {
if (!CanExecSave()) return false;
// create temp writer
LibCmo::CK2::CKFileWriter writer(m_Context);
// fill object data
for (const auto& id : m_ObjGroups) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id : m_Obj3dObjects) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id : m_ObjMeshes) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id : m_ObjMaterials) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id : m_ObjTextures) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id :m_ObjTargetLights) {
writer.AddSavedObject(m_Context->GetObject(id));
}
// set global texture save mode
m_Context->SetGlobalImagesSaveOptions(texture_save_opt);
// set compress level
if (use_compress) {
m_Context->SetFileWriteMode(LibCmo::CK2::CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED);
m_Context->SetCompressionLevel(compress_level);
} else {
m_Context->SetFileWriteMode(LibCmo::CK2::CK_FILE_WRITEMODE::CKFILE_UNCOMPRESSED);
}
// save to file and detect error
LibCmo::CK2::CKERROR err = writer.Save(filename);
// return with error detect.
m_HasSaved = true;
return err == LibCmo::CK2::CKERROR::CKERR_OK;
}
LibCmo::CK2::ObjImpls::CKObject* BMFile::GetObjectPtr(LibCmo::CK2::CK_ID objid) {
// we fetch object from CKContext to get better performance
LibCmo::CK2::ObjImpls::CKObject* obj = m_Context->GetObject(objid);
// however, we can not directly return the pointer fetched fron CKContext.
// BMFile only provide limited type visiting, we must make sure it provided ID also is existed in out stored list.
// so we check its type here. if type is not matched, we reset it to nullptr.
if (obj != nullptr) {
switch (obj->GetClassID()) {
case LibCmo::CK2::CK_CLASSID::CKCID_GROUP:
case LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT:
case LibCmo::CK2::CK_CLASSID::CKCID_MESH:
case LibCmo::CK2::CK_CLASSID::CKCID_MATERIAL:
case LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE:
case LibCmo::CK2::CK_CLASSID::CKCID_TARGETLIGHT:
break; // okey. do nothing
default:
// this object should not be exposed to outside, reset it to nullptr
obj = nullptr;
break;
}
}
// return result
return obj;
}
#pragma endregion
#pragma region Visitor
LibCmo::CKDWORD BMFile::CommonGetObjectCount(std::vector<LibCmo::CK2::CK_ID>& container) {
// only available in loader
if (!CanExecLoaderVisitor()) return 0;
return static_cast<LibCmo::CKDWORD>(container.size());
}
LibCmo::CK2::CK_ID BMFile::CommonGetObject(std::vector<LibCmo::CK2::CK_ID>& container, LibCmo::CKDWORD idx) {
// only available in loader
if (!CanExecLoaderVisitor()) return 0;
return container[idx];
}
LibCmo::CK2::CK_ID BMFile::CommonCreateObject(std::vector<LibCmo::CK2::CK_ID>& container, LibCmo::CK2::CK_CLASSID cid) {
// only available in saver
if (!CanExecSaverVisitor()) return 0;
// try create object and get its pointer
LibCmo::CK2::ObjImpls::CKObject* obj = m_Context->CreateObject(cid, nullptr);
// check creation validation
if (obj == nullptr) return 0;
// if success, write its id and emplace its id into list
LibCmo::CK2::CK_ID objid = obj->GetID();
container.emplace_back(objid);
return objid;
}
LibCmo::CKDWORD BMFile::GetGroupCount() { return CommonGetObjectCount(m_ObjGroups); }
LibCmo::CK2::CK_ID BMFile::GetGroup(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjGroups, idx); }
LibCmo::CK2::CK_ID BMFile::CreateGroup() { return CommonCreateObject(m_ObjGroups, LibCmo::CK2::CK_CLASSID::CKCID_GROUP); }
LibCmo::CKDWORD BMFile::Get3dObjectCount() { return CommonGetObjectCount(m_Obj3dObjects); }
LibCmo::CK2::CK_ID BMFile::Get3dObject(LibCmo::CKDWORD idx) { return CommonGetObject(m_Obj3dObjects, idx); }
LibCmo::CK2::CK_ID BMFile::Create3dObject() { return CommonCreateObject(m_Obj3dObjects, LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT); }
LibCmo::CKDWORD BMFile::GetMeshCount() { return CommonGetObjectCount(m_ObjMeshes); }
LibCmo::CK2::CK_ID BMFile::GetMesh(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjMeshes, idx); }
LibCmo::CK2::CK_ID BMFile::CreateMesh() { return CommonCreateObject(m_ObjMeshes, LibCmo::CK2::CK_CLASSID::CKCID_MESH); }
LibCmo::CKDWORD BMFile::GetMaterialCount() { return CommonGetObjectCount(m_ObjMaterials); }
LibCmo::CK2::CK_ID BMFile::GetMaterial(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjMaterials, idx); }
LibCmo::CK2::CK_ID BMFile::CreateMaterial() { return CommonCreateObject(m_ObjMaterials, LibCmo::CK2::CK_CLASSID::CKCID_MATERIAL); }
LibCmo::CKDWORD BMFile::GetTextureCount() { return CommonGetObjectCount(m_ObjTextures); }
LibCmo::CK2::CK_ID BMFile::GetTexture(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjTextures, idx); }
LibCmo::CK2::CK_ID BMFile::CreateTexture() { return CommonCreateObject(m_ObjTextures, LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE); }
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); }
#pragma endregion
#pragma endregion
#pragma region BMMeshTransition #pragma region BMMeshTransition
BMMeshTransition::TransitionVertex::TransitionVertex( BMMeshTransition::TransitionVertex::TransitionVertex(
@@ -229,149 +470,4 @@ namespace BMap {
#pragma endregion #pragma endregion
#pragma region BMfile
BMFile::BMFile(LibCmo::CKSTRING temp_folder, LibCmo::CKSTRING texture_folder, NakedOutputCallback raw_callback, LibCmo::CKDWORD encoding_count, LibCmo::CKSTRING* encodings, bool is_loader) :
m_IsInitError(false), m_IsLoader(is_loader), m_HasLoaded(false), m_HasSaved(false), m_Context(nullptr) {
m_Context = new LibCmo::CK2::CKContext();
// binding callback with lambda wrapper.
// 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);
});
}
// set temp folder and texture folder
auto pm = m_Context->GetPathManager();
m_IsInitError = m_IsInitError || !pm->AddPath(texture_folder);
m_IsInitError = m_IsInitError || !pm->SetTempFolder(temp_folder);
// set encoding
LibCmo::XContainer::XArray<LibCmo::XContainer::XString> cache;
for (LibCmo::CKDWORD i = 0; i < encoding_count; ++i) {
if (encodings[i] != nullptr)
cache.emplace_back(encodings[i]);
}
m_Context->SetEncoding(cache);
m_IsInitError = m_IsInitError || !m_Context->IsValidEncoding();
// set default texture save mode is external
m_Context->SetGlobalImagesSaveOptions(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_EXTERNAL);
// set default file write mode is whole compressed
m_Context->SetFileWriteMode(LibCmo::CK2::CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED);
}
BMFile::~BMFile() {
delete m_Context;
}
bool BMFile::Load(LibCmo::CKSTRING filename) {
if (!CanExecLoad()) return false;
// create temp ckfile and load
LibCmo::CK2::CKFileReader reader(m_Context);
LibCmo::CK2::CKERROR err = reader.DeepLoad(filename);
// detect error
if (err != LibCmo::CK2::CKERROR::CKERR_OK) {
// failed. clear document and return false
m_Context->ClearAll();
return false;
}
// sync data list to our list
m_ObjGroups.clear();
m_Obj3dObjects.clear();
m_ObjMeshs.clear();
m_ObjMaterials.clear();
m_ObjTextures.clear();
for (const auto& fileobj : reader.GetFileObjects()) {
if (fileobj.ObjPtr == nullptr) continue;
switch (fileobj.ObjectCid) {
case LibCmo::CK2::CK_CLASSID::CKCID_GROUP:
m_ObjGroups.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT:
m_Obj3dObjects.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_MESH:
m_ObjMeshs.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_MATERIAL:
m_ObjMaterials.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE:
m_ObjTextures.emplace_back(fileobj.CreatedObjectId);
break;
default:
break; // skip unknow objects
}
}
m_HasLoaded = true;
return true;
}
bool BMFile::Save(LibCmo::CKSTRING filename, LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS texture_save_opt, bool use_compress, LibCmo::CKINT compress_level) {
if (!CanExecSave()) return false;
// create temp writer
LibCmo::CK2::CKFileWriter writer(m_Context);
// fill object data
for (const auto& id : m_ObjGroups) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id : m_Obj3dObjects) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id : m_ObjMeshs) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id : m_ObjMaterials) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id : m_ObjTextures) {
writer.AddSavedObject(m_Context->GetObject(id));
}
// set global texture save mode
m_Context->SetGlobalImagesSaveOptions(texture_save_opt);
// set compress level
if (use_compress) {
m_Context->SetFileWriteMode(LibCmo::CK2::CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED);
m_Context->SetCompressionLevel(compress_level);
} else {
m_Context->SetFileWriteMode(LibCmo::CK2::CK_FILE_WRITEMODE::CKFILE_UNCOMPRESSED);
}
// save to file and detect error
LibCmo::CK2::CKERROR err = writer.Save(filename);
// return with error detect.
m_HasSaved = true;
return err == LibCmo::CK2::CKERROR::CKERR_OK;
}
LibCmo::CKDWORD BMFile::GetGroupCount() { return CommonGetObjectCount(m_ObjGroups); }
LibCmo::CK2::CK_ID BMFile::GetGroup(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjGroups, idx); }
LibCmo::CK2::CK_ID BMFile::CreateGroup() { return CommonCreateObject(m_ObjGroups, LibCmo::CK2::CK_CLASSID::CKCID_GROUP); }
LibCmo::CKDWORD BMFile::Get3dObjectCount() { return CommonGetObjectCount(m_Obj3dObjects); }
LibCmo::CK2::CK_ID BMFile::Get3dObject(LibCmo::CKDWORD idx) { return CommonGetObject(m_Obj3dObjects, idx); }
LibCmo::CK2::CK_ID BMFile::Create3dObject() { return CommonCreateObject(m_Obj3dObjects, LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT); }
LibCmo::CKDWORD BMFile::GetMeshCount() { return CommonGetObjectCount(m_ObjMeshs); }
LibCmo::CK2::CK_ID BMFile::GetMesh(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjMeshs, idx); }
LibCmo::CK2::CK_ID BMFile::CreateMesh() { return CommonCreateObject(m_ObjMeshs, LibCmo::CK2::CK_CLASSID::CKCID_MESH); }
LibCmo::CKDWORD BMFile::GetMaterialCount() { return CommonGetObjectCount(m_ObjMaterials); }
LibCmo::CK2::CK_ID BMFile::GetMaterial(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjMaterials, idx); }
LibCmo::CK2::CK_ID BMFile::CreateMaterial() { return CommonCreateObject(m_ObjMaterials, LibCmo::CK2::CK_CLASSID::CKCID_MATERIAL); }
LibCmo::CKDWORD BMFile::GetTextureCount() { return CommonGetObjectCount(m_ObjTextures); }
LibCmo::CK2::CK_ID BMFile::GetTexture(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjTextures, idx); }
LibCmo::CK2::CK_ID BMFile::CreateTexture() { return CommonCreateObject(m_ObjTextures, LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE); }
#pragma endregion
} }

View File

@@ -16,93 +16,95 @@ namespace BMap {
~BMFile(); ~BMFile();
YYCC_DEL_CLS_COPY_MOVE(BMFile); YYCC_DEL_CLS_COPY_MOVE(BMFile);
// ===== safe visit functions ===== // ===== Safe Check Function =====
/** /*
Safe Visit Function will make sure this class is visited with safe mode. Safe Check Function will make sure this class is visited in safe mode.
These function will block all other functions if this class init failed. Some of them are exposed to outside to report current status of this class, for example, whether there is a issue when initialize this class.
Or, block any more operations if this class has loaded or saved once. In this time you only can free this class And some of them are used by internal functions to make sure there is a safe environment to execute corresponding functions.
For example, #Load function will use #CanExecLoad to detect whether it can execute loading process.
*/ */
public: public:
bool IsInitError() { /**
return m_IsInitError; * @brief Check whether there is an error when initializing this class.
} * @details
* This class is exposed for outside code to check.
private: * Internal code should use one of following 4 private check functions to check environment.
bool CanExecLoad() { * @return True if there is an error when initializing this class.
// no error, is loader, no prev load */
return (!m_IsInitError && m_IsLoader && !m_HasLoaded); bool IsInitError();
}
bool CanExecSave() {
// no error, is saver, no prev save
return (!m_IsInitError && !m_IsLoader && !m_HasSaved);
}
bool CanExecLoaderVisitor() {
// no error, is loader, has loaded
return (!m_IsInitError && m_IsLoader && m_HasLoaded);
}
bool CanExecSaverVisitor() {
// no error, is saver, not saveed yet
// same as CanExecSave
return (!m_IsInitError && !m_IsLoader && !m_HasSaved);
}
private: private:
/** /**
* @brief True if an error occurs when initializing this class. * @brief Check whether it's okey to execute #Load function.
* @return True if it is okey.
*/ */
bool m_IsInitError; bool CanExecLoad();
/** /**
* @brief True if this class is a reader. * @brief Check whether it's okey to execute #Save function.
* @return True if it is okey.
*/ */
bool m_IsLoader; bool CanExecSave();
/** /**
* @brief True if this class has read. Only valid when this class is reader. * @brief Check whether it's okey to execute Loader-related function.
* @details
* Due to implementation, saving file and loading file are use the same class, BMFile to represent.
* So obviously you can visit loader-related function in a saver.
* This operation is illegal. So we need block these operation.
* This is what this function does. Provide the condition which raise blocking.
* @return True if it is okey.
*/ */
bool m_HasLoaded; bool CanExecLoaderVisitor();
/** /**
* @brief True if this class has written. Only valid when this class is writer. * @brief Check whether it's okey to execute Saver-related function.
* @return True if it is okey.
* @see CanExecLoaderVisitor
*/ */
bool m_HasSaved; bool CanExecSaverVisitor();
// ===== help functions ===== private:
bool m_IsInitError; /**< True if an error occurs when initializing this class. */
bool m_IsLoader; /**< True if this class is a reader. */
bool m_HasLoaded; /**< True if this class has read. It's undefined behavior when visiting this variable if this class is not reader. */
bool m_HasSaved; /**< True if this class has written. It's undefined behavior when visiting this variable if this class is not writer. */
// ===== Help Function =====
public: public:
/**
* @brief Load document to this class.
* @param[in] filename The path to file.
* @return True if no error, otherwise false.
*/
bool Load(LibCmo::CKSTRING filename); bool Load(LibCmo::CKSTRING filename);
/**
* @brief Save current class into document.
* @param[in] filename The path to file.
* @param[in] texture_save_opt Global texture save option
* @param[in] use_compress True if use compression when saving.
* @param[in] compress_level The compress level if you choose using compression in file.
* @return
*/
bool Save(LibCmo::CKSTRING filename, LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS texture_save_opt, bool use_compress, LibCmo::CKINT compress_level); bool Save(LibCmo::CKSTRING filename, LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS texture_save_opt, bool use_compress, LibCmo::CKINT compress_level);
LibCmo::CK2::ObjImpls::CKObject* GetObjectPtr(LibCmo::CK2::CK_ID objid) { /**
return m_Context->GetObject(objid);; * @brief Get object pointer from given ID.
} * @details
* This function is specially exposed to outside for detecting whether given ID is valid in BMFile.
* Also used by BMMeshTransition to get essential objects.
* @param[in] objid The ID of object.
* @return The pointer to given ID represented object. nullptr if not found.
*/
LibCmo::CK2::ObjImpls::CKObject* GetObjectPtr(LibCmo::CK2::CK_ID objid);
// ===== visitors ===== // ===== Visitor =====
private: private:
LibCmo::CKDWORD CommonGetObjectCount(std::vector<LibCmo::CK2::CK_ID>& container) { LibCmo::CKDWORD CommonGetObjectCount(std::vector<LibCmo::CK2::CK_ID>& container);
// only available in loader LibCmo::CK2::CK_ID CommonGetObject(std::vector<LibCmo::CK2::CK_ID>& container, LibCmo::CKDWORD idx);
if (!CanExecLoaderVisitor()) return 0; LibCmo::CK2::CK_ID CommonCreateObject(std::vector<LibCmo::CK2::CK_ID>& container, LibCmo::CK2::CK_CLASSID cid);
return static_cast<LibCmo::CKDWORD>(container.size());
}
LibCmo::CK2::CK_ID CommonGetObject(std::vector<LibCmo::CK2::CK_ID>& container, LibCmo::CKDWORD idx) {
// only available in loader
if (!CanExecLoaderVisitor()) return 0;
return container[idx];
}
LibCmo::CK2::CK_ID CommonCreateObject(std::vector<LibCmo::CK2::CK_ID>& container, LibCmo::CK2::CK_CLASSID cid) {
// only available in saver
if (!CanExecSaverVisitor()) return 0;
// try create object and get its pointer
LibCmo::CK2::ObjImpls::CKObject* obj = m_Context->CreateObject(cid, nullptr);
// check creation validation
if (obj == nullptr) return 0;
// if success, write its id and emplace its id into list
LibCmo::CK2::CK_ID objid = obj->GetID();
container.emplace_back(objid);
return objid;
}
public: public:
LibCmo::CKDWORD GetGroupCount(); LibCmo::CKDWORD GetGroupCount();
LibCmo::CK2::CK_ID GetGroup(LibCmo::CKDWORD idx); LibCmo::CK2::CK_ID GetGroup(LibCmo::CKDWORD idx);
@@ -119,15 +121,19 @@ namespace BMap {
LibCmo::CKDWORD GetTextureCount(); LibCmo::CKDWORD GetTextureCount();
LibCmo::CK2::CK_ID GetTexture(LibCmo::CKDWORD idx); LibCmo::CK2::CK_ID GetTexture(LibCmo::CKDWORD idx);
LibCmo::CK2::CK_ID CreateTexture(); LibCmo::CK2::CK_ID CreateTexture();
LibCmo::CKDWORD GetTargetLightCount();
LibCmo::CK2::CK_ID GetTargetLight(LibCmo::CKDWORD idx);
LibCmo::CK2::CK_ID CreateTargetLight();
private: private:
LibCmo::CK2::CKContext* m_Context; LibCmo::CK2::CKContext* m_Context;
std::vector<LibCmo::CK2::CK_ID> m_ObjGroups; std::vector<LibCmo::CK2::CK_ID> m_ObjGroups;
std::vector<LibCmo::CK2::CK_ID> m_Obj3dObjects; std::vector<LibCmo::CK2::CK_ID> m_Obj3dObjects;
std::vector<LibCmo::CK2::CK_ID> m_ObjMeshs; std::vector<LibCmo::CK2::CK_ID> m_ObjMeshes;
std::vector<LibCmo::CK2::CK_ID> m_ObjMaterials; std::vector<LibCmo::CK2::CK_ID> m_ObjMaterials;
std::vector<LibCmo::CK2::CK_ID> m_ObjTextures; std::vector<LibCmo::CK2::CK_ID> m_ObjTextures;
std::vector<LibCmo::CK2::CK_ID> m_ObjTargetLights;
}; };

View File

@@ -3,21 +3,22 @@ add_library(BMap SHARED "")
# Setup sources # Setup sources
target_sources(BMap target_sources(BMap
PRIVATE PRIVATE
BMap.cpp BMap/BMap.cpp
BMExports.cpp BMap/BMExports.cpp
) )
# Setup headers # Setup headers
target_sources(BMap target_sources(BMap
PRIVATE PUBLIC
FILE_SET HEADERS FILE_SET HEADERS
FILES FILES
BMap.hpp BMap/BMap.hpp
BMExports.hpp BMap/BMExports.hpp
) )
# Setup header infomation # Setup header infomation
target_include_directories(BMap target_include_directories(BMap
PRIVATE PUBLIC
"${CMAKE_CURRENT_LIST_DIR}" "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
) )
# Setup linked library infomation # Setup linked library infomation
target_link_libraries(BMap target_link_libraries(BMap
@@ -25,31 +26,42 @@ PRIVATE
YYCC::YYCCommonplace YYCC::YYCCommonplace
LibCmo LibCmo
) )
# Setup C++ standard
set_target_properties(BMap
PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED 20
CXX_EXTENSION OFF
)
# Setup project macros
target_compile_definitions(BMap
# Enable export macro # Enable export macro
target_compile_definitions(BMap
PRIVATE PRIVATE
BMAP_EXPORTING BMAP_EXPORTING
# Order Unicode charset for private using
PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:UNICODE>
$<$<CXX_COMPILER_ID:MSVC>:_UNICODE>
)
# Order build as UTF-8 in MSVC
target_compile_options(BMap
PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/utf-8>
) )
# Install BMap only on Release mode # Install binary and headers
install(TARGETS BMap install(TARGETS BMap
CONFIGURATIONS Release RelWithDebInfo MinSizeRel EXPORT BMapTargets
RUNTIME DESTINATION ${YYCC_INSTALL_BIN_PATH} LIBRARY DESTINATION ${NEMO_INSTALL_LIB_PATH}
ARCHIVE DESTINATION ${NEMO_INSTALL_LIB_PATH}
INCLUDES DESTINATION ${NEMO_INSTALL_INCLUDE_PATH}
FILE_SET HEADERS DESTINATION ${NEMO_INSTALL_INCLUDE_PATH}
)
# Install target
install(EXPORT BMapTargets
FILE BMapTargets.cmake
NAMESPACE NeMo::
DESTINATION ${NEMO_INSTALL_LIB_PATH}/cmake/BMap
)
# Package configuration file
write_basic_package_version_file(
BMapConfigVersion.cmake
VERSION ${PACKAGE_VERSION}
COMPATIBILITY SameMinorVersion
)
configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/../CMake/BMapConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/BMapConfig.cmake"
INSTALL_DESTINATION ${NEMO_INSTALL_LIB_PATH}/cmake/BMap
)
# Copy package files to install destination
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/BMapConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/BMapConfigVersion.cmake"
DESTINATION
${NEMO_INSTALL_LIB_PATH}/cmake/BMap
) )

View File

@@ -453,6 +453,28 @@ namespace BMapSharp {
[DllImport(g_DllName, EntryPoint = "BMFile_CreateTexture", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMFile_CreateTexture", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMFile_CreateTexture([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [Out, MarshalAs(UnmanagedType.U4)] out uint out_id); internal static extern bool BMFile_CreateTexture([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [Out, MarshalAs(UnmanagedType.U4)] out uint out_id);
/// <summary>BMFile_GetTargetLightCount</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="out_count">Type: LibCmo::CKDWORD. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMFile_GetTargetLightCount", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMFile_GetTargetLightCount([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [Out, MarshalAs(UnmanagedType.U4)] out uint out_count);
/// <summary>BMFile_GetTargetLight</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="idx">Type: LibCmo::CKDWORD. </param>
/// <param name="out_id">Type: LibCmo::CK2::CK_ID. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMFile_GetTargetLight", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMFile_GetTargetLight([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint idx, [Out, MarshalAs(UnmanagedType.U4)] out uint out_id);
/// <summary>BMFile_CreateTargetLight</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="out_id">Type: LibCmo::CK2::CK_ID. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMFile_CreateTargetLight", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMFile_CreateTargetLight([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [Out, MarshalAs(UnmanagedType.U4)] out uint out_id);
/// <summary>BMMeshTrans_New</summary> /// <summary>BMMeshTrans_New</summary>
/// <param name="out_trans">Type: BMap::BMMeshTransition*. This is OUT parameter. </param> /// <param name="out_trans">Type: BMap::BMMeshTransition*. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
@@ -1151,54 +1173,198 @@ namespace BMapSharp {
[DllImport(g_DllName, EntryPoint = "BMMesh_SetMaterialSlot", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMesh_SetMaterialSlot", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMesh_SetMaterialSlot([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint index, [In, MarshalAs(UnmanagedType.U4)] uint mtlid); internal static extern bool BMMesh_SetMaterialSlot([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint index, [In, MarshalAs(UnmanagedType.U4)] uint mtlid);
/// <summary>BM3dObject_GetWorldMatrix</summary> /// <summary>BM3dEntity_GetWorldMatrix</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="out_mat">Type: LibCmo::VxMath::VxMatrix. This is OUT parameter. </param> /// <param name="out_mat">Type: LibCmo::VxMath::VxMatrix. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BM3dObject_GetWorldMatrix", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BM3dEntity_GetWorldMatrix", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BM3dObject_GetWorldMatrix([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.Struct)] out VxMatrix out_mat); internal static extern bool BM3dEntity_GetWorldMatrix([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.Struct)] out VxMatrix out_mat);
/// <summary>BM3dObject_SetWorldMatrix</summary> /// <summary>BM3dEntity_SetWorldMatrix</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="mat">Type: LibCmo::VxMath::VxMatrix. </param> /// <param name="mat">Type: LibCmo::VxMath::VxMatrix. </param>
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BM3dObject_SetWorldMatrix", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BM3dEntity_SetWorldMatrix", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BM3dObject_SetWorldMatrix([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.Struct)] VxMatrix mat); internal static extern bool BM3dEntity_SetWorldMatrix([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.Struct)] VxMatrix mat);
/// <summary>BM3dObject_GetCurrentMesh</summary> /// <summary>BM3dEntity_GetCurrentMesh</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="out_meshid">Type: LibCmo::CK2::CK_ID. This is OUT parameter. </param> /// <param name="out_meshid">Type: LibCmo::CK2::CK_ID. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BM3dObject_GetCurrentMesh", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BM3dEntity_GetCurrentMesh", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BM3dObject_GetCurrentMesh([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_meshid); internal static extern bool BM3dEntity_GetCurrentMesh([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_meshid);
/// <summary>BM3dObject_SetCurrentMesh</summary> /// <summary>BM3dEntity_SetCurrentMesh</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="meshid">Type: LibCmo::CK2::CK_ID. </param> /// <param name="meshid">Type: LibCmo::CK2::CK_ID. </param>
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BM3dObject_SetCurrentMesh", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BM3dEntity_SetCurrentMesh", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BM3dObject_SetCurrentMesh([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint meshid); internal static extern bool BM3dEntity_SetCurrentMesh([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint meshid);
/// <summary>BM3dObject_GetVisibility</summary> /// <summary>BM3dEntity_GetVisibility</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="out_isVisible">Type: bool. This is OUT parameter. </param> /// <param name="out_isVisible">Type: bool. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BM3dObject_GetVisibility", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BM3dEntity_GetVisibility", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BM3dObject_GetVisibility([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U1)] out bool out_isVisible); internal static extern bool BM3dEntity_GetVisibility([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U1)] out bool out_isVisible);
/// <summary>BM3dObject_SetVisibility</summary> /// <summary>BM3dEntity_SetVisibility</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="is_visible">Type: bool. </param> /// <param name="is_visible">Type: bool. </param>
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BM3dObject_SetVisibility", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BM3dEntity_SetVisibility", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BM3dObject_SetVisibility([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U1)] bool is_visible); internal static extern bool BM3dEntity_SetVisibility([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U1)] bool is_visible);
/// <summary>BMLight_GetType</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="out_val">Type: LibCmo::VxMath::VXLIGHT_TYPE. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_GetType", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_GetType([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXLIGHT_TYPE out_val);
/// <summary>BMLight_SetType</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="val">Type: LibCmo::VxMath::VXLIGHT_TYPE. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_SetType", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_SetType([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXLIGHT_TYPE val);
/// <summary>BMLight_GetColor</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="out_val">Type: LibCmo::VxMath::VxColor. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_GetColor", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_GetColor([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.Struct)] out VxColor out_val);
/// <summary>BMLight_SetColor</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="col">Type: LibCmo::VxMath::VxColor. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_SetColor", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_SetColor([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.Struct)] VxColor col);
/// <summary>BMLight_GetConstantAttenuation</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="out_val">Type: LibCmo::CKFLOAT. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_GetConstantAttenuation", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_GetConstantAttenuation([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.R4)] out float out_val);
/// <summary>BMLight_SetConstantAttenuation</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="val">Type: LibCmo::CKFLOAT. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_SetConstantAttenuation", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_SetConstantAttenuation([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.R4)] float val);
/// <summary>BMLight_GetLinearAttenuation</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="out_val">Type: LibCmo::CKFLOAT. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_GetLinearAttenuation", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_GetLinearAttenuation([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.R4)] out float out_val);
/// <summary>BMLight_SetLinearAttenuation</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="val">Type: LibCmo::CKFLOAT. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_SetLinearAttenuation", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_SetLinearAttenuation([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.R4)] float val);
/// <summary>BMLight_GetQuadraticAttenuation</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="out_val">Type: LibCmo::CKFLOAT. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_GetQuadraticAttenuation", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_GetQuadraticAttenuation([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.R4)] out float out_val);
/// <summary>BMLight_SetQuadraticAttenuation</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="val">Type: LibCmo::CKFLOAT. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_SetQuadraticAttenuation", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_SetQuadraticAttenuation([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.R4)] float val);
/// <summary>BMLight_GetRange</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="out_val">Type: LibCmo::CKFLOAT. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_GetRange", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_GetRange([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.R4)] out float out_val);
/// <summary>BMLight_SetRange</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="val">Type: LibCmo::CKFLOAT. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_SetRange", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_SetRange([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.R4)] float val);
/// <summary>BMLight_GetHotSpot</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="out_val">Type: LibCmo::CKFLOAT. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_GetHotSpot", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_GetHotSpot([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.R4)] out float out_val);
/// <summary>BMLight_SetHotSpot</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="val">Type: LibCmo::CKFLOAT. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_SetHotSpot", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_SetHotSpot([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.R4)] float val);
/// <summary>BMLight_GetFalloff</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="out_val">Type: LibCmo::CKFLOAT. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_GetFalloff", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_GetFalloff([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.R4)] out float out_val);
/// <summary>BMLight_SetFalloff</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="val">Type: LibCmo::CKFLOAT. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_SetFalloff", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_SetFalloff([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.R4)] float val);
/// <summary>BMLight_GetFalloffShape</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="out_val">Type: LibCmo::CKFLOAT. This is OUT parameter. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_GetFalloffShape", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_GetFalloffShape([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.R4)] out float out_val);
/// <summary>BMLight_SetFalloffShape</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
/// <param name="val">Type: LibCmo::CKFLOAT. </param>
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMLight_SetFalloffShape", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMLight_SetFalloffShape([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.R4)] float val);
// ##### GENERATED FUNCTIONS END ##### // ##### GENERATED FUNCTIONS END #####

View File

@@ -352,7 +352,7 @@ namespace BMapSharp.BMapWrapper {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceMaterialSlotIndexs(getPointer(), getCKID(), out IntPtr out_mem)); BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceMaterialSlotIndexs(getPointer(), getCKID(), out IntPtr out_mem));
Utils.ShortAssigner(out_mem, GetFaceCount(), iem); Utils.ShortAssigner(out_mem, GetFaceCount(), iem);
} }
public uint GetMaterialSlotCount() => getGenericValue<uint>(BMap.BMMesh_GetMaterialSlotCount); public uint GetMaterialSlotCount() => getGenericValue<uint>(BMap.BMMesh_GetMaterialSlotCount);
public void SetMaterialSlotCount(uint count) => setGenericValue<uint>(BMap.BMMesh_SetMaterialSlotCount, count); public void SetMaterialSlotCount(uint count) => setGenericValue<uint>(BMap.BMMesh_SetMaterialSlotCount, count);
public IEnumerable<BMMaterial> GetMaterialSlots() { public IEnumerable<BMMaterial> GetMaterialSlots() {
@@ -375,24 +375,61 @@ namespace BMapSharp.BMapWrapper {
} }
public class BM3dObject : BMObject { public class BM3dEntity : BMObject {
internal BM3dObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { } internal BM3dEntity(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public VxMatrix GetWorldMatrix() => getGenericValue<VxMatrix>(BMap.BM3dObject_GetWorldMatrix); public VxMatrix GetWorldMatrix() => getGenericValue<VxMatrix>(BMap.BM3dEntity_GetWorldMatrix);
public void SetWorldMatrix(VxMatrix mat) => setGenericValue<VxMatrix>(BMap.BM3dObject_SetWorldMatrix, mat); public void SetWorldMatrix(VxMatrix mat) => setGenericValue<VxMatrix>(BMap.BM3dEntity_SetWorldMatrix, mat);
public BMMesh GetCurrentMesh() { public BMMesh GetCurrentMesh() {
BMapException.ThrowIfFailed(BMap.BM3dObject_GetCurrentMesh(getPointer(), getCKID(), out uint out_meshid)); BMapException.ThrowIfFailed(BMap.BM3dEntity_GetCurrentMesh(getPointer(), getCKID(), out uint out_meshid));
if (out_meshid == Utils.INVALID_CKID) return null; if (out_meshid == Utils.INVALID_CKID) return null;
else return new BMMesh(getPointer(), out_meshid); else return new BMMesh(getPointer(), out_meshid);
} }
public void SetCurrentMesh(BMMesh mesh) { public void SetCurrentMesh(BMMesh mesh) {
uint meshid = (mesh is null) ? Utils.INVALID_CKID : mesh.getCKID(); uint meshid = (mesh is null) ? Utils.INVALID_CKID : mesh.getCKID();
BMapException.ThrowIfFailed(BMap.BM3dObject_SetCurrentMesh(getPointer(), getCKID(), meshid)); BMapException.ThrowIfFailed(BMap.BM3dEntity_SetCurrentMesh(getPointer(), getCKID(), meshid));
} }
public bool GetVisibility() => getGenericValue<bool>(BMap.BM3dObject_GetVisibility); public bool GetVisibility() => getGenericValue<bool>(BMap.BM3dEntity_GetVisibility);
public void SetVisibility(bool visb) => setGenericValue<bool>(BMap.BM3dObject_SetVisibility, visb); public void SetVisibility(bool visb) => setGenericValue<bool>(BMap.BM3dEntity_SetVisibility, visb);
}
public class BM3dObject : BM3dEntity {
internal BM3dObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
}
public class BMLight : BM3dEntity {
internal BMLight(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
// Name `GetType` is conflict with C# base class function name.
// So we add a `Light` prefix for it.
public VXLIGHT_TYPE GetLightType() => getGenericValue<VXLIGHT_TYPE>(BMap.BMLight_GetType);
public void SetLightType(VXLIGHT_TYPE val) => setGenericValue<VXLIGHT_TYPE>(BMap.BMLight_SetType, val);
public VxColor GetColor() => getGenericValue<VxColor>(BMap.BMLight_GetColor);
public void SetColor(VxColor col) => setGenericValue<VxColor>(BMap.BMLight_SetColor, col);
public float GetConstantAttenuation() => getGenericValue<float>(BMap.BMLight_GetConstantAttenuation);
public void SetConstantAttenuation(float val) => setGenericValue<float>(BMap.BMLight_SetConstantAttenuation, val);
public float GetLinearAttenuation() => getGenericValue<float>(BMap.BMLight_GetLinearAttenuation);
public void SetLinearAttenuation(float val) => setGenericValue<float>(BMap.BMLight_SetLinearAttenuation, val);
public float GetQuadraticAttenuation() => getGenericValue<float>(BMap.BMLight_GetQuadraticAttenuation);
public void SetQuadraticAttenuation(float val) => setGenericValue<float>(BMap.BMLight_SetQuadraticAttenuation, val);
public float GetRange() => getGenericValue<float>(BMap.BMLight_GetRange);
public void SetRange(float val) => setGenericValue<float>(BMap.BMLight_SetRange, val);
public float GetHotSpot() => getGenericValue<float>(BMap.BMLight_GetHotSpot);
public void SetHotSpot(float val) => setGenericValue<float>(BMap.BMLight_SetHotSpot, val);
public float GetFalloff() => getGenericValue<float>(BMap.BMLight_GetFalloff);
public void SetFalloff(float val) => setGenericValue<float>(BMap.BMLight_SetFalloff, val);
public float GetFalloffShape() => getGenericValue<float>(BMap.BMLight_GetFalloffShape);
public void SetFalloffShape(float val) => setGenericValue<float>(BMap.BMLight_SetFalloffShape, val);
}
public class BMTargetLight : BMLight {
internal BMTargetLight(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
} }
public class BMGroup : BMObject { public class BMGroup : BMObject {
@@ -463,6 +500,10 @@ namespace BMapSharp.BMapWrapper {
getCKObjectCount(BMap.BMFile_GetGroupCount); getCKObjectCount(BMap.BMFile_GetGroupCount);
public IEnumerable<BMGroup> GetGroups() => public IEnumerable<BMGroup> GetGroups() =>
getCKObjects<BMGroup>(BMap.BMFile_GetGroupCount, BMap.BMFile_GetGroup, (bmf, id) => new BMGroup(bmf, id)); getCKObjects<BMGroup>(BMap.BMFile_GetGroupCount, BMap.BMFile_GetGroup, (bmf, id) => new BMGroup(bmf, id));
public uint GetTargetLightCount() =>
getCKObjectCount(BMap.BMFile_GetTargetLightCount);
public IEnumerable<BMTargetLight> GetTargetLights() =>
getCKObjects<BMTargetLight>(BMap.BMFile_GetTargetLightCount, BMap.BMFile_GetTargetLight, (bmf, id) => new BMTargetLight(bmf, id));
} }
@@ -504,6 +545,7 @@ namespace BMapSharp.BMapWrapper {
public BMMesh CreateMesh() => createCKObject<BMMesh>(BMap.BMFile_CreateMesh, (bmf, id) => new BMMesh(bmf, id)); public BMMesh CreateMesh() => createCKObject<BMMesh>(BMap.BMFile_CreateMesh, (bmf, id) => new BMMesh(bmf, id));
public BM3dObject Create3dObject() => createCKObject<BM3dObject>(BMap.BMFile_Create3dObject, (bmf, id) => new BM3dObject(bmf, id)); public BM3dObject Create3dObject() => createCKObject<BM3dObject>(BMap.BMFile_Create3dObject, (bmf, id) => new BM3dObject(bmf, id));
public BMGroup CreateGroup() => createCKObject<BMGroup>(BMap.BMFile_CreateGroup, (bmf, id) => new BMGroup(bmf, id)); public BMGroup CreateGroup() => createCKObject<BMGroup>(BMap.BMFile_CreateGroup, (bmf, id) => new BMGroup(bmf, id));
public BMTargetLight CreateTargetLight() => createCKObject<BMTargetLight>(BMap.BMFile_CreateTargetLight, (bmf, id) => new BMTargetLight(bmf, id));
} }
public sealed class BMMeshTrans : AbstractPointer { public sealed class BMMeshTrans : AbstractPointer {

View File

@@ -226,6 +226,13 @@ namespace BMapSharp.VirtoolsTypes {
_4_ARGB8888_CLUT = 31, /**< 4 bits indexed CLUT (ARGB) */ _4_ARGB8888_CLUT = 31, /**< 4 bits indexed CLUT (ARGB) */
} }
public enum VXLIGHT_TYPE : uint {
VX_LIGHTPOINT = 1, /**< The Light is a point of light */
VX_LIGHTSPOT = 2, /**< The light is a spotlight */
VX_LIGHTDIREC = 3, /**< The light is directional light : Lights comes from an infinite point so only direction of light can be given */
// VX_LIGHTPARA = 4UL, /**< Obsolete, do not use */
}
public enum VXTEXTURE_BLENDMODE : uint { public enum VXTEXTURE_BLENDMODE : uint {
VXTEXTUREBLEND_DECAL = 1, /**< Texture replace any material information */ VXTEXTUREBLEND_DECAL = 1, /**< Texture replace any material information */
VXTEXTUREBLEND_MODULATE = 2, /**< Texture and material are combine. Alpha information of the texture replace material alpha component. */ VXTEXTUREBLEND_MODULATE = 2, /**< Texture and material are combine. Alpha information of the texture replace material alpha component. */

View File

@@ -4,6 +4,10 @@
<ProjectReference Include="..\BMapSharp\BMapSharp.csproj" /> <ProjectReference Include="..\BMapSharp\BMapSharp.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
</ItemGroup>
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>

View File

@@ -3,11 +3,19 @@ using System;
using System.Text; using System.Text;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.CommandLine;
namespace BMapSharpTestbench { namespace BMapSharpTestbench {
internal class Program { internal class Program {
static void Main(string[] args) { static void Main(string[] args) {
// Parse arguments
var resolved_args = ResolveArguments(args);
if (resolved_args is null) {
// just silent quit
Environment.Exit(0);
}
// Check environment // Check environment
Console.OutputEncoding = Encoding.UTF8; Console.OutputEncoding = Encoding.UTF8;
if (!BMapSharp.BMapWrapper.Utils.IsBMapAvailable()) { if (!BMapSharp.BMapWrapper.Utils.IsBMapAvailable()) {
@@ -21,10 +29,10 @@ namespace BMapSharpTestbench {
Console.ReadKey(true); Console.ReadKey(true);
// Start testbench // Start testbench
string file_name = "Level_02.NMO"; string file_name = resolved_args.mFileName; // "LightCameraTest.nmo";
string temp_folder = "Temp"; string temp_folder = resolved_args.mTempFolder; // "Temp";
string texture_folder = "F:\\Ballance\\Ballance\\Textures"; string texture_folder = resolved_args.mTextureFolder; // "F:\\Ballance\\Ballance\\Textures";
string[] encodings = ["cp1252", "gb2312"]; string[] encodings = resolved_args.mEncodings; // ["cp1252", "gb2312"];
using (var reader = new BMapSharp.BMapWrapper.BMFileReader(file_name, temp_folder, texture_folder, encodings)) { using (var reader = new BMapSharp.BMapWrapper.BMFileReader(file_name, temp_folder, texture_folder, encodings)) {
TestCommon(reader); TestCommon(reader);
@@ -36,6 +44,53 @@ namespace BMapSharpTestbench {
} }
class BMapSharpArguments {
public string mFileName;
public string mTempFolder;
public string mTextureFolder;
public string[] mEncodings;
}
static BMapSharpArguments ResolveArguments(string[] args) {
// define arguments
var fileNameOpt = new Option<string>
("--file-path", "The path to input Virtools file.");
fileNameOpt.IsRequired = true;
var tempFolderOpt = new Option<string>
("--temp-dir", "The temp folder used by BMap.");
tempFolderOpt.IsRequired = true;
var textureFolderOpt = new Option<string>
("--texture-dir", "The texture folder containing Ballance texture resources.");
textureFolderOpt.IsRequired = true;
var encodingsOpt = new Option<IEnumerable<string>>
("--encodings", "The encodings used to parse the names stroed in input Virtools file.");
encodingsOpt.IsRequired = true;
encodingsOpt.Arity = ArgumentArity.OneOrMore;
encodingsOpt.AllowMultipleArgumentsPerToken = true;
// init root command
var rootCommand = new RootCommand("The testbench of BMapSharp.");
rootCommand.Add(fileNameOpt);
rootCommand.Add(tempFolderOpt);
rootCommand.Add(textureFolderOpt);
rootCommand.Add(encodingsOpt);
// init result container
BMapSharpArguments ret = new BMapSharpArguments();
// set handler
rootCommand.SetHandler((context) => {
ret.mFileName = context.ParseResult.GetValueForOption(fileNameOpt);
ret.mTempFolder = context.ParseResult.GetValueForOption(tempFolderOpt);
ret.mTextureFolder = context.ParseResult.GetValueForOption(textureFolderOpt);
ret.mEncodings = context.ParseResult.GetValueForOption(encodingsOpt).ToArray();
context.ExitCode = 61;
});
// execute root command and return value.
if (rootCommand.Invoke(args) != 61) return null;
return ret;
}
static void TestCommon(BMapSharp.BMapWrapper.BMFileReader reader) { static void TestCommon(BMapSharp.BMapWrapper.BMFileReader reader) {
// Console.WriteLine("===== Groups ====="); // Console.WriteLine("===== Groups =====");
// foreach (var gp in reader.GetGroups()) { // foreach (var gp in reader.GetGroups()) {
@@ -66,38 +121,38 @@ namespace BMapSharpTestbench {
// Console.WriteLine($"\tMaterial Slot Count: {mesh.GetMaterialSlotCount()}"); // Console.WriteLine($"\tMaterial Slot Count: {mesh.GetMaterialSlotCount()}");
// } // }
Console.WriteLine("===== Materials ====="); // Console.WriteLine("===== Materials =====");
foreach (var mtl in reader.GetMaterials()) { // foreach (var mtl in reader.GetMaterials()) {
Console.WriteLine(mtl.GetName()); // Console.WriteLine(mtl.GetName());
Console.WriteLine($"\tDiffuse: {mtl.GetDiffuse().ToManagedRGBA()}"); // Console.WriteLine($"\tDiffuse: {mtl.GetDiffuse().ToManagedRGBA()}");
Console.WriteLine($"\tAmbient: {mtl.GetAmbient().ToManagedRGBA()}"); // Console.WriteLine($"\tAmbient: {mtl.GetAmbient().ToManagedRGBA()}");
Console.WriteLine($"\tSpecular: {mtl.GetSpecular().ToManagedRGBA()}"); // Console.WriteLine($"\tSpecular: {mtl.GetSpecular().ToManagedRGBA()}");
Console.WriteLine($"\tEmissive: {mtl.GetEmissive().ToManagedRGBA()}"); // Console.WriteLine($"\tEmissive: {mtl.GetEmissive().ToManagedRGBA()}");
Console.WriteLine($"\tSpecular Power: {mtl.GetSpecularPower()}"); // Console.WriteLine($"\tSpecular Power: {mtl.GetSpecularPower()}");
Console.WriteLine($"\tTexture Border Color: {mtl.GetTextureBorderColor().ToManagedRGBA()}"); // Console.WriteLine($"\tTexture Border Color: {mtl.GetTextureBorderColor().ToManagedRGBA()}");
Console.WriteLine($"\tTexture Blend Mode: {mtl.GetTextureBlendMode()}"); // Console.WriteLine($"\tTexture Blend Mode: {mtl.GetTextureBlendMode()}");
Console.WriteLine($"\tTexture Min Mode: {mtl.GetTextureMinMode()}"); // Console.WriteLine($"\tTexture Min Mode: {mtl.GetTextureMinMode()}");
Console.WriteLine($"\tTexture Mag Mode: {mtl.GetTextureMagMode()}"); // Console.WriteLine($"\tTexture Mag Mode: {mtl.GetTextureMagMode()}");
Console.WriteLine($"\tSource Blend: {mtl.GetSourceBlend()}"); // Console.WriteLine($"\tSource Blend: {mtl.GetSourceBlend()}");
Console.WriteLine($"\tDest Blend: {mtl.GetDestBlend()}"); // Console.WriteLine($"\tDest Blend: {mtl.GetDestBlend()}");
Console.WriteLine($"\tFill Mode: {mtl.GetFillMode()}"); // Console.WriteLine($"\tFill Mode: {mtl.GetFillMode()}");
Console.WriteLine($"\tShade Mode: {mtl.GetShadeMode()}"); // Console.WriteLine($"\tShade Mode: {mtl.GetShadeMode()}");
Console.WriteLine($"\tAlpha Test Enabled: {mtl.GetAlphaTestEnabled()}"); // Console.WriteLine($"\tAlpha Test Enabled: {mtl.GetAlphaTestEnabled()}");
Console.WriteLine($"\tAlpha Blend Enabled: {mtl.GetAlphaBlendEnabled()}"); // Console.WriteLine($"\tAlpha Blend Enabled: {mtl.GetAlphaBlendEnabled()}");
Console.WriteLine($"\tPerspective Correction Enabled: {mtl.GetPerspectiveCorrectionEnabled()}"); // Console.WriteLine($"\tPerspective Correction Enabled: {mtl.GetPerspectiveCorrectionEnabled()}");
Console.WriteLine($"\tZ Write Enabled: {mtl.GetZWriteEnabled()}"); // Console.WriteLine($"\tZ Write Enabled: {mtl.GetZWriteEnabled()}");
Console.WriteLine($"\tTwo Sided Enabled: {mtl.GetTwoSidedEnabled()}"); // Console.WriteLine($"\tTwo Sided Enabled: {mtl.GetTwoSidedEnabled()}");
Console.WriteLine($"\tAlpha Ref: {mtl.GetAlphaRef()}"); // Console.WriteLine($"\tAlpha Ref: {mtl.GetAlphaRef()}");
Console.WriteLine($"\tAlpha Func: {mtl.GetAlphaFunc()}"); // Console.WriteLine($"\tAlpha Func: {mtl.GetAlphaFunc()}");
Console.WriteLine($"\tZ Func: {mtl.GetZFunc()}"); // Console.WriteLine($"\tZ Func: {mtl.GetZFunc()}");
} // }
// Console.WriteLine("===== Textures ====="); // Console.WriteLine("===== Textures =====");
// foreach (var tex in reader.GetTextures()) { // foreach (var tex in reader.GetTextures()) {
@@ -108,6 +163,24 @@ namespace BMapSharpTestbench {
// Console.WriteLine($"\tVideo Format: {tex.GetVideoFormat()}"); // Console.WriteLine($"\tVideo Format: {tex.GetVideoFormat()}");
// } // }
Console.WriteLine("===== Target Lights =====");
foreach (var lit in reader.GetTargetLights()) {
Console.WriteLine(lit.GetName());
Console.WriteLine($"\tVisibility: {lit.GetVisibility()}");
Console.WriteLine($"\tMatrix: {lit.GetWorldMatrix().ToManaged()}");
Console.WriteLine($"Type: {lit.GetLightType()}");
Console.WriteLine($"Color: {lit.GetColor().ToManagedRGBA()}");
Console.WriteLine($"Constant Attenuation: {lit.GetConstantAttenuation()}");
Console.WriteLine($"Linear Attenuation: {lit.GetLinearAttenuation()}");
Console.WriteLine($"Quadratic Attenuation: {lit.GetQuadraticAttenuation()}");
Console.WriteLine($"Range: {lit.GetRange()}");
Console.WriteLine($"Hot Spot: {lit.GetHotSpot()}");
Console.WriteLine($"Falloff: {lit.GetFalloff()}");
Console.WriteLine($"Falloff Shape: {lit.GetFalloffShape()}");
}
Console.WriteLine("===== END ====="); Console.WriteLine("===== END =====");
} }
@@ -119,7 +192,7 @@ namespace BMapSharpTestbench {
); );
return; return;
} }
// Prepare test variables // Prepare test variables
var all_3dobjects = new List<BM3dObject>(reader.Get3dObjects()); var all_3dobjects = new List<BM3dObject>(reader.Get3dObjects());
var first_3dobj = all_3dobjects[0]; var first_3dobj = all_3dobjects[0];

View File

@@ -5,3 +5,5 @@ The core of BMapSharp project is placed within `BMapSharp` subdirectory. This di
The native BMap library should be placed together with managed `BMapSharp` dynamic library. I use gitignore file to filter all native binary so you need put them manually. The native BMap library must be named as `BMap.dll` (in Windows), `BMap.so` (in Linux or BSD), or `BMap.dylib` (in macOS). If you still can not load BMap or your system is not listed above, you should name it as `BMap.bin`. The native BMap library should be placed together with managed `BMapSharp` dynamic library. I use gitignore file to filter all native binary so you need put them manually. The native BMap library must be named as `BMap.dll` (in Windows), `BMap.so` (in Linux or BSD), or `BMap.dylib` (in macOS). If you still can not load BMap or your system is not listed above, you should name it as `BMap.bin`.
The most content of `VirtoolsTypes.cs` is generated by EnumsMigration, and the most content of `BMap.cs` is generated by BMapBindings. You should watch these file changes if corresponding C++ code or structures are changed. The most content of `VirtoolsTypes.cs` is generated by EnumsMigration, and the most content of `BMap.cs` is generated by BMapBindings. You should watch these file changes if corresponding C++ code or structures are changed.
Since BMap 0.3.0, testbench use command line arguments, instead of hardcode variables in code, as the arguments of BMap. It is convenient that debug BMapSharp without any modification of source code. For a brief instruction, you may need to launch BMapSharpTestbench in following command (just an example. you can modify it as you wished): `dotnet run -- --file-path "LightCameraTest.nmo" --temp-dir "Temp" --texture-dir "F:/Ballance/Ballance/Textures" --encodings cp1252 gb2312`.

View File

@@ -227,6 +227,22 @@ BMFile_GetTexture = _create_bmap_func('BMFile_GetTexture', [bm_void_p, bm_CKDWOR
# @param out_id[out] Type: LibCmo::CK2::CK_ID. Use ctypes.byref(data) pass it. # @param out_id[out] Type: LibCmo::CK2::CK_ID. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False. # @return True if no error, otherwise False.
BMFile_CreateTexture = _create_bmap_func('BMFile_CreateTexture', [bm_void_p, bm_CKID_p]) BMFile_CreateTexture = _create_bmap_func('BMFile_CreateTexture', [bm_void_p, bm_CKID_p])
## BMFile_GetTargetLightCount
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param out_count[out] Type: LibCmo::CKDWORD. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False.
BMFile_GetTargetLightCount = _create_bmap_func('BMFile_GetTargetLightCount', [bm_void_p, bm_CKDWORD_p])
## BMFile_GetTargetLight
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param idx[in] Type: LibCmo::CKDWORD.
# @param out_id[out] Type: LibCmo::CK2::CK_ID. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False.
BMFile_GetTargetLight = _create_bmap_func('BMFile_GetTargetLight', [bm_void_p, bm_CKDWORD, bm_CKID_p])
## BMFile_CreateTargetLight
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param out_id[out] Type: LibCmo::CK2::CK_ID. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False.
BMFile_CreateTargetLight = _create_bmap_func('BMFile_CreateTargetLight', [bm_void_p, bm_CKID_p])
## BMMeshTrans_New ## BMMeshTrans_New
# @param out_trans[out] Type: BMap::BMMeshTransition*. Use ctypes.byref(data) pass it. # @param out_trans[out] Type: BMap::BMMeshTransition*. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False. # @return True if no error, otherwise False.
@@ -747,42 +763,150 @@ BMMesh_GetMaterialSlot = _create_bmap_func('BMMesh_GetMaterialSlot', [bm_void_p,
# @param mtlid[in] Type: LibCmo::CK2::CK_ID. # @param mtlid[in] Type: LibCmo::CK2::CK_ID.
# @return True if no error, otherwise False. # @return True if no error, otherwise False.
BMMesh_SetMaterialSlot = _create_bmap_func('BMMesh_SetMaterialSlot', [bm_void_p, bm_CKID, bm_CKDWORD, bm_CKID]) BMMesh_SetMaterialSlot = _create_bmap_func('BMMesh_SetMaterialSlot', [bm_void_p, bm_CKID, bm_CKDWORD, bm_CKID])
## BM3dObject_GetWorldMatrix ## BM3dEntity_GetWorldMatrix
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile. # @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing. # @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param out_mat[out] Type: LibCmo::VxMath::VxMatrix. Use ctypes.byref(data) pass it. # @param out_mat[out] Type: LibCmo::VxMath::VxMatrix. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False. # @return True if no error, otherwise False.
BM3dObject_GetWorldMatrix = _create_bmap_func('BM3dObject_GetWorldMatrix', [bm_void_p, bm_CKID, bm_VxMatrix_p]) BM3dEntity_GetWorldMatrix = _create_bmap_func('BM3dEntity_GetWorldMatrix', [bm_void_p, bm_CKID, bm_VxMatrix_p])
## BM3dObject_SetWorldMatrix ## BM3dEntity_SetWorldMatrix
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile. # @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing. # @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param mat[in] Type: LibCmo::VxMath::VxMatrix. # @param mat[in] Type: LibCmo::VxMath::VxMatrix.
# @return True if no error, otherwise False. # @return True if no error, otherwise False.
BM3dObject_SetWorldMatrix = _create_bmap_func('BM3dObject_SetWorldMatrix', [bm_void_p, bm_CKID, bm_VxMatrix]) BM3dEntity_SetWorldMatrix = _create_bmap_func('BM3dEntity_SetWorldMatrix', [bm_void_p, bm_CKID, bm_VxMatrix])
## BM3dObject_GetCurrentMesh ## BM3dEntity_GetCurrentMesh
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile. # @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing. # @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param out_meshid[out] Type: LibCmo::CK2::CK_ID. Use ctypes.byref(data) pass it. # @param out_meshid[out] Type: LibCmo::CK2::CK_ID. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False. # @return True if no error, otherwise False.
BM3dObject_GetCurrentMesh = _create_bmap_func('BM3dObject_GetCurrentMesh', [bm_void_p, bm_CKID, bm_CKID_p]) BM3dEntity_GetCurrentMesh = _create_bmap_func('BM3dEntity_GetCurrentMesh', [bm_void_p, bm_CKID, bm_CKID_p])
## BM3dObject_SetCurrentMesh ## BM3dEntity_SetCurrentMesh
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile. # @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing. # @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param meshid[in] Type: LibCmo::CK2::CK_ID. # @param meshid[in] Type: LibCmo::CK2::CK_ID.
# @return True if no error, otherwise False. # @return True if no error, otherwise False.
BM3dObject_SetCurrentMesh = _create_bmap_func('BM3dObject_SetCurrentMesh', [bm_void_p, bm_CKID, bm_CKID]) BM3dEntity_SetCurrentMesh = _create_bmap_func('BM3dEntity_SetCurrentMesh', [bm_void_p, bm_CKID, bm_CKID])
## BM3dObject_GetVisibility ## BM3dEntity_GetVisibility
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile. # @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing. # @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param out_isVisible[out] Type: bool. Use ctypes.byref(data) pass it. # @param out_isVisible[out] Type: bool. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False. # @return True if no error, otherwise False.
BM3dObject_GetVisibility = _create_bmap_func('BM3dObject_GetVisibility', [bm_void_p, bm_CKID, bm_bool_p]) BM3dEntity_GetVisibility = _create_bmap_func('BM3dEntity_GetVisibility', [bm_void_p, bm_CKID, bm_bool_p])
## BM3dObject_SetVisibility ## BM3dEntity_SetVisibility
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile. # @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing. # @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param is_visible[in] Type: bool. # @param is_visible[in] Type: bool.
# @return True if no error, otherwise False. # @return True if no error, otherwise False.
BM3dObject_SetVisibility = _create_bmap_func('BM3dObject_SetVisibility', [bm_void_p, bm_CKID, bm_bool]) BM3dEntity_SetVisibility = _create_bmap_func('BM3dEntity_SetVisibility', [bm_void_p, bm_CKID, bm_bool])
## BMLight_GetType
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param out_val[out] Type: LibCmo::VxMath::VXLIGHT_TYPE. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False.
BMLight_GetType = _create_bmap_func('BMLight_GetType', [bm_void_p, bm_CKID, bm_enum_p])
## BMLight_SetType
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param val[in] Type: LibCmo::VxMath::VXLIGHT_TYPE.
# @return True if no error, otherwise False.
BMLight_SetType = _create_bmap_func('BMLight_SetType', [bm_void_p, bm_CKID, bm_enum])
## BMLight_GetColor
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param out_val[out] Type: LibCmo::VxMath::VxColor. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False.
BMLight_GetColor = _create_bmap_func('BMLight_GetColor', [bm_void_p, bm_CKID, bm_VxColor_p])
## BMLight_SetColor
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param col[in] Type: LibCmo::VxMath::VxColor.
# @return True if no error, otherwise False.
BMLight_SetColor = _create_bmap_func('BMLight_SetColor', [bm_void_p, bm_CKID, bm_VxColor])
## BMLight_GetConstantAttenuation
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False.
BMLight_GetConstantAttenuation = _create_bmap_func('BMLight_GetConstantAttenuation', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
## BMLight_SetConstantAttenuation
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param val[in] Type: LibCmo::CKFLOAT.
# @return True if no error, otherwise False.
BMLight_SetConstantAttenuation = _create_bmap_func('BMLight_SetConstantAttenuation', [bm_void_p, bm_CKID, bm_CKFLOAT])
## BMLight_GetLinearAttenuation
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False.
BMLight_GetLinearAttenuation = _create_bmap_func('BMLight_GetLinearAttenuation', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
## BMLight_SetLinearAttenuation
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param val[in] Type: LibCmo::CKFLOAT.
# @return True if no error, otherwise False.
BMLight_SetLinearAttenuation = _create_bmap_func('BMLight_SetLinearAttenuation', [bm_void_p, bm_CKID, bm_CKFLOAT])
## BMLight_GetQuadraticAttenuation
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False.
BMLight_GetQuadraticAttenuation = _create_bmap_func('BMLight_GetQuadraticAttenuation', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
## BMLight_SetQuadraticAttenuation
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param val[in] Type: LibCmo::CKFLOAT.
# @return True if no error, otherwise False.
BMLight_SetQuadraticAttenuation = _create_bmap_func('BMLight_SetQuadraticAttenuation', [bm_void_p, bm_CKID, bm_CKFLOAT])
## BMLight_GetRange
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False.
BMLight_GetRange = _create_bmap_func('BMLight_GetRange', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
## BMLight_SetRange
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param val[in] Type: LibCmo::CKFLOAT.
# @return True if no error, otherwise False.
BMLight_SetRange = _create_bmap_func('BMLight_SetRange', [bm_void_p, bm_CKID, bm_CKFLOAT])
## BMLight_GetHotSpot
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False.
BMLight_GetHotSpot = _create_bmap_func('BMLight_GetHotSpot', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
## BMLight_SetHotSpot
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param val[in] Type: LibCmo::CKFLOAT.
# @return True if no error, otherwise False.
BMLight_SetHotSpot = _create_bmap_func('BMLight_SetHotSpot', [bm_void_p, bm_CKID, bm_CKFLOAT])
## BMLight_GetFalloff
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False.
BMLight_GetFalloff = _create_bmap_func('BMLight_GetFalloff', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
## BMLight_SetFalloff
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param val[in] Type: LibCmo::CKFLOAT.
# @return True if no error, otherwise False.
BMLight_SetFalloff = _create_bmap_func('BMLight_SetFalloff', [bm_void_p, bm_CKID, bm_CKFLOAT])
## BMLight_GetFalloffShape
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
# @return True if no error, otherwise False.
BMLight_GetFalloffShape = _create_bmap_func('BMLight_GetFalloffShape', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
## BMLight_SetFalloffShape
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
# @param val[in] Type: LibCmo::CKFLOAT.
# @return True if no error, otherwise False.
BMLight_SetFalloffShape = _create_bmap_func('BMLight_SetFalloffShape', [bm_void_p, bm_CKID, bm_CKFLOAT])
##### GENERATED FUNCTIONS END ##### ##### GENERATED FUNCTIONS END #####

View File

@@ -476,10 +476,10 @@ class BMMesh(BMObject):
except StopIteration: except StopIteration:
_Utils.raise_out_of_length_exception() _Utils.raise_out_of_length_exception()
class BM3dObject(BMObject): class BM3dEntity(BMObject):
def get_world_matrix(self) -> virtools_types.VxMatrix: def get_world_matrix(self) -> virtools_types.VxMatrix:
mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix() mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix()
bmap.BM3dObject_GetWorldMatrix(self._get_pointer(), self._get_ckid(), ctypes.byref(mat)) bmap.BM3dEntity_GetWorldMatrix(self._get_pointer(), self._get_ckid(), ctypes.byref(mat))
# use cast & pointer to get matrix data conveniently # use cast & pointer to get matrix data conveniently
flat: bmap.bm_CKFLOAT_p = ctypes.cast(ctypes.byref(mat), bmap.bm_CKFLOAT_p) flat: bmap.bm_CKFLOAT_p = ctypes.cast(ctypes.byref(mat), bmap.bm_CKFLOAT_p)
ret: virtools_types.VxMatrix = virtools_types.VxMatrix() ret: virtools_types.VxMatrix = virtools_types.VxMatrix()
@@ -489,11 +489,11 @@ class BM3dObject(BMObject):
def set_world_matrix(self, mat_: virtools_types.VxMatrix) -> None: def set_world_matrix(self, mat_: virtools_types.VxMatrix) -> None:
# star syntax expand the tuple as the argument. # star syntax expand the tuple as the argument.
mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix(*(mat_.to_const())) mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix(*(mat_.to_const()))
bmap.BM3dObject_SetWorldMatrix(self._get_pointer(), self._get_ckid(), mat) bmap.BM3dEntity_SetWorldMatrix(self._get_pointer(), self._get_ckid(), mat)
def get_current_mesh(self) -> BMMesh | None: def get_current_mesh(self) -> BMMesh | None:
ckid: bmap.bm_CKID = bmap.bm_CKID() ckid: bmap.bm_CKID = bmap.bm_CKID()
bmap.BM3dObject_GetCurrentMesh(self._get_pointer(), self._get_ckid(), ctypes.byref(ckid)) bmap.BM3dEntity_GetCurrentMesh(self._get_pointer(), self._get_ckid(), ctypes.byref(ckid))
if ckid.value == g_InvalidCKID: if ckid.value == g_InvalidCKID:
return None return None
else: else:
@@ -503,12 +503,60 @@ class BM3dObject(BMObject):
ckid: bmap.bm_CKID = bmap.bm_CKID(g_InvalidCKID) ckid: bmap.bm_CKID = bmap.bm_CKID(g_InvalidCKID)
if mesh is not None: if mesh is not None:
ckid = mesh._get_ckid() ckid = mesh._get_ckid()
bmap.BM3dObject_SetCurrentMesh(self._get_pointer(), self._get_ckid(), ckid) bmap.BM3dEntity_SetCurrentMesh(self._get_pointer(), self._get_ckid(), ckid)
def get_visibility(self) -> bool: def get_visibility(self) -> bool:
return self._get_bool_value(bmap.BM3dObject_GetVisibility) return self._get_bool_value(bmap.BM3dEntity_GetVisibility)
def set_visibility(self, visb_: bool) -> None: def set_visibility(self, visb_: bool) -> None:
self._set_bool_value(bmap.BM3dObject_SetVisibility, visb_) self._set_bool_value(bmap.BM3dEntity_SetVisibility, visb_)
class BM3dObject(BM3dEntity):
pass
class BMLight(BM3dEntity):
def get_type(self) -> virtools_types.VXLIGHT_TYPE:
return self._get_enum_value(virtools_types.VXLIGHT_TYPE, bmap.BMLight_GetType)
def set_type(self, data_: virtools_types.VXLIGHT_TYPE) -> None:
self._set_enum_value(bmap.BMLight_SetType, data_)
def get_color(self) -> virtools_types.VxColor:
return self._get_vxcolor_value(bmap.BMLight_GetColor)
def set_color(self, col: virtools_types.VxColor) -> None:
self._set_vxcolor_value(bmap.BMLight_SetColor, col)
def get_constant_attenuation(self) -> float:
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetConstantAttenuation)
def set_constant_attenuation(self, val_: float) -> None:
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetConstantAttenuation, val_)
def get_linear_attenuation(self) -> float:
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetLinearAttenuation)
def set_linear_attenuation(self, val_: float) -> None:
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetLinearAttenuation, val_)
def get_quadratic_attenuation(self) -> float:
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetQuadraticAttenuation)
def set_quadratic_attenuation(self, val_: float) -> None:
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetQuadraticAttenuation, val_)
def get_range(self) -> float:
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetRange)
def set_range(self, val_: float) -> None:
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetRange, val_)
def get_hot_spot(self) -> float:
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetHotSpot)
def set_hot_spot(self, val_: float) -> None:
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetHotSpot, val_)
def get_falloff(self) -> float:
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetFalloff)
def set_falloff(self, val_: float) -> None:
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetFalloff, val_)
def get_falloff_shape(self) -> float:
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetFalloffShape)
def set_falloff_shape(self, val_: float) -> None:
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetFalloffShape, val_)
class BMTargetLight(BMLight):
pass
class BMGroup(BMObject): class BMGroup(BMObject):
def add_object(self, member: BM3dObject) -> None: def add_object(self, member: BM3dObject) -> None:
@@ -603,6 +651,10 @@ class BMFileReader(_AbstractPointer):
return self.__get_ckobject_count(bmap.BMFile_GetGroupCount) return self.__get_ckobject_count(bmap.BMFile_GetGroupCount)
def get_groups(self) -> typing.Iterator[BMGroup]: def get_groups(self) -> typing.Iterator[BMGroup]:
return self.__get_ckobjects(BMGroup, bmap.BMFile_GetGroupCount, bmap.BMFile_GetGroup) return self.__get_ckobjects(BMGroup, bmap.BMFile_GetGroupCount, bmap.BMFile_GetGroup)
def get_target_light_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetTargetLightCount)
def get_target_lights(self) -> typing.Iterator[BMTargetLight]:
return self.__get_ckobjects(BMTargetLight, bmap.BMFile_GetTargetLightCount, bmap.BMFile_GetTargetLight)
class BMFileWriter(_AbstractPointer): class BMFileWriter(_AbstractPointer):
def __init__(self, temp_folder_: str, texture_folder_: str, encodings_: tuple[str]): def __init__(self, temp_folder_: str, texture_folder_: str, encodings_: tuple[str]):
@@ -663,6 +715,8 @@ class BMFileWriter(_AbstractPointer):
return self.__create_ckobject(BM3dObject, bmap.BMFile_Create3dObject) return self.__create_ckobject(BM3dObject, bmap.BMFile_Create3dObject)
def create_group(self) -> BMGroup: def create_group(self) -> BMGroup:
return self.__create_ckobject(BMGroup, bmap.BMFile_CreateGroup) return self.__create_ckobject(BMGroup, bmap.BMFile_CreateGroup)
def create_target_light(self) -> BMTargetLight:
return self.__create_ckobject(BMTargetLight, bmap.BMFile_CreateTargetLight)
class BMMeshTrans(_AbstractPointer): class BMMeshTrans(_AbstractPointer):
def __init__(self): def __init__(self):

View File

@@ -221,6 +221,15 @@ class VX_PIXELFORMAT(enum.IntEnum):
_4_ABGR8888_CLUT = 30 ##< 4 bits indexed CLUT (ABGR) _4_ABGR8888_CLUT = 30 ##< 4 bits indexed CLUT (ABGR)
_4_ARGB8888_CLUT = 31 ##< 4 bits indexed CLUT (ARGB) _4_ARGB8888_CLUT = 31 ##< 4 bits indexed CLUT (ARGB)
class VXLIGHT_TYPE(enum.IntEnum):
"""!
Light type
"""
VX_LIGHTPOINT = 1 ##< The Light is a point of light
VX_LIGHTSPOT = 2 ##< The light is a spotlight
VX_LIGHTDIREC = 3 ##< The light is directional light : Lights comes from an infinite point so only direction of light can be given
#VX_LIGHTPARA = 4 ##< Obsolete, do not use
class VXTEXTURE_BLENDMODE(enum.IntEnum): class VXTEXTURE_BLENDMODE(enum.IntEnum):
"""! """!
Blend Mode Flags Blend Mode Flags

View File

@@ -5,3 +5,5 @@ The real scripts are placed in sub PyBMap folder. This folder is served for test
The native BMap library should be placed in sub PyBMap folder, and I have used gitignore file to filter them. The native BMap library must be named as `BMap.dll` (in Windows), `BMap.so` (in Linux or BSD), or `BMap.dylib` (in macOS). If you still can not load BMap or your system is not listed above, you should name it as `BMap.bin`. The native BMap library should be placed in sub PyBMap folder, and I have used gitignore file to filter them. The native BMap library must be named as `BMap.dll` (in Windows), `BMap.so` (in Linux or BSD), or `BMap.dylib` (in macOS). If you still can not load BMap or your system is not listed above, you should name it as `BMap.bin`.
Please note the most content of `virtools_types.py` are generated by EnumsMigration sub-project. Additionally the most content of `bmap.py` is generated by BMapBindings. So if some structs are updated, do not forget checking these files. Please note the most content of `virtools_types.py` are generated by EnumsMigration sub-project. Additionally the most content of `bmap.py` is generated by BMapBindings. So if some structs are updated, do not forget checking these files.
Since BMap 0.3.0, testbench use command line arguments, instead of hardcode variables in code, as the arguments of BMap. It is convenient that debug BMapSharp without any modification of source code. For a brief instruction, you may need to launch BMapSharpTestbench in following command (just an example. you can modify it as you wished): `py testbench.py --file-path "LightCameraTest.nmo" --temp-dir "Temp" --texture-dir "F:/Ballance/Ballance/Textures" --encodings cp1252 gb2312`.

View File

@@ -1,13 +1,14 @@
import os import os
import argparse
import PyBMap.bmap_wrapper as bmap import PyBMap.bmap_wrapper as bmap
def main() -> None: def main(file_name: str, temp_folder: str, texture_folder: str, encodings: tuple[str, ...]) -> None:
input(f'Python PID is {os.getpid()}. Waiting for debugger, press any key to continue...') input(f'Python PID is {os.getpid()}. Waiting for debugger, press any key to continue...')
file_name: str = 'Level_02.NMO' # file_name: str = 'LightCameraTest.nmo'
temp_folder: str = 'Temp' # temp_folder: str = 'Temp'
texture_folder: str = 'F:\\Ballance\\Ballance\\Textures' # texture_folder: str = 'F:\\Ballance\\Ballance\\Textures'
encodings: tuple[str, ...] = ('cp1252', ) # encodings: tuple[str, ...] = ('cp1252', )
with bmap.BMFileReader(file_name, temp_folder, texture_folder, encodings) as reader: with bmap.BMFileReader(file_name, temp_folder, texture_folder, encodings) as reader:
test_common(reader) test_common(reader)
test_equatable(reader) test_equatable(reader)
@@ -38,37 +39,37 @@ def test_common(reader: bmap.BMFileReader):
# print(f'\tFace Count: {mesh.get_face_count()}') # print(f'\tFace Count: {mesh.get_face_count()}')
# print(f'\tMaterial Slot Count: {mesh.get_material_slot_count()}') # print(f'\tMaterial Slot Count: {mesh.get_material_slot_count()}')
print('===== Materials =====') # print('===== Materials =====')
for mtl in reader.get_materials(): # for mtl in reader.get_materials():
print(mtl.get_name()) # print(mtl.get_name())
print(f'\tDiffuse: {mtl.get_diffuse().to_const_rgba()}') # print(f'\tDiffuse: {mtl.get_diffuse().to_const_rgba()}')
print(f'\tAmbient: {mtl.get_ambient().to_const_rgba()}') # print(f'\tAmbient: {mtl.get_ambient().to_const_rgba()}')
print(f'\tSpecular: {mtl.get_specular().to_const_rgba()}') # print(f'\tSpecular: {mtl.get_specular().to_const_rgba()}')
print(f'\tEmissive: {mtl.get_emissive().to_const_rgba()}') # print(f'\tEmissive: {mtl.get_emissive().to_const_rgba()}')
print(f'\tSpecular Power: {mtl.get_specular_power()}') # print(f'\tSpecular Power: {mtl.get_specular_power()}')
print(f'\tTexture Border Color: {mtl.get_texture_border_color().to_const_rgba()}') # print(f'\tTexture Border Color: {mtl.get_texture_border_color().to_const_rgba()}')
print(f'\tTexture Blend Mode: {mtl.get_texture_blend_mode()}') # print(f'\tTexture Blend Mode: {mtl.get_texture_blend_mode()}')
print(f'\tTexture Min Mode: {mtl.get_texture_min_mode()}') # print(f'\tTexture Min Mode: {mtl.get_texture_min_mode()}')
print(f'\tTexture Mag Mode: {mtl.get_texture_mag_mode()}') # print(f'\tTexture Mag Mode: {mtl.get_texture_mag_mode()}')
print(f'\tSource Blend: {mtl.get_source_blend()}') # print(f'\tSource Blend: {mtl.get_source_blend()}')
print(f'\tDest Blend: {mtl.get_dest_blend()}') # print(f'\tDest Blend: {mtl.get_dest_blend()}')
print(f'\tFill Mode: {mtl.get_fill_mode()}') # print(f'\tFill Mode: {mtl.get_fill_mode()}')
print(f'\tShade Mode: {mtl.get_shade_mode()}') # print(f'\tShade Mode: {mtl.get_shade_mode()}')
print(f'\tAlpha Test Enabled: {mtl.get_alpha_test_enabled()}') # print(f'\tAlpha Test Enabled: {mtl.get_alpha_test_enabled()}')
print(f'\tAlpha Blend Enabled: {mtl.get_alpha_blend_enabled()}') # print(f'\tAlpha Blend Enabled: {mtl.get_alpha_blend_enabled()}')
print(f'\tPerspective Correction Enabled: {mtl.get_perspective_correction_enabled()}') # print(f'\tPerspective Correction Enabled: {mtl.get_perspective_correction_enabled()}')
print(f'\tZ Write Enabled: {mtl.get_z_write_enabled()}') # print(f'\tZ Write Enabled: {mtl.get_z_write_enabled()}')
print(f'\tTwo Sided Enabled: {mtl.get_two_sided_enabled()}') # print(f'\tTwo Sided Enabled: {mtl.get_two_sided_enabled()}')
print(f'\tAlpha Ref: {mtl.get_alpha_ref()}') # print(f'\tAlpha Ref: {mtl.get_alpha_ref()}')
print(f'\tAlpha Func: {mtl.get_alpha_func()}') # print(f'\tAlpha Func: {mtl.get_alpha_func()}')
print(f'\tZ Func: {mtl.get_z_func()}') # print(f'\tZ Func: {mtl.get_z_func()}')
# print('===== Textures =====') # print('===== Textures =====')
# for tex in reader.get_textures(): # for tex in reader.get_textures():
@@ -78,6 +79,23 @@ def test_common(reader: bmap.BMFileReader):
# print(f'\tSave Options: {tex.get_save_options()}') # print(f'\tSave Options: {tex.get_save_options()}')
# print(f'\tVideo Format: {tex.get_video_format()}') # print(f'\tVideo Format: {tex.get_video_format()}')
print('===== Target Lights =====')
for lit in reader.get_target_lights():
print(lit.get_name())
print(f'\tVisibility: {lit.get_visibility()}')
print(f'\tMatrix: {lit.get_world_matrix().to_const()}')
print(f'\tType: {lit.get_type()}')
print(f'\tColor: {lit.get_color().to_const_rgba()}')
print(f'\tConstant Attenuation: {lit.get_constant_attenuation()}')
print(f'\tLinear Attenuation: {lit.get_linear_attenuation()}')
print(f'\tQuadratic Attenuation: {lit.get_quadratic_attenuation()}')
print(f'\tRange: {lit.get_range()}')
print(f'\tHot Spot: {lit.get_hot_spot()}')
print(f'\tFalloff: {lit.get_falloff()}')
print(f'\tFalloff Shape: {lit.get_falloff_shape()}')
print('===== END =====') print('===== END =====')
def test_equatable(reader: bmap.BMFileReader): def test_equatable(reader: bmap.BMFileReader):
@@ -129,4 +147,32 @@ def test_equatable(reader: bmap.BMFileReader):
assert second_3dobj in test_dict assert second_3dobj in test_dict
if __name__ == '__main__': if __name__ == '__main__':
main() # parse argument
parser = argparse.ArgumentParser(
prog='PyBMap Testbench',
description='The testbench of PyBMap.'
)
parser.add_argument(
'--file-path',
action='store', dest='file_path', required=True,
help='The path to input Virtools file.'
)
parser.add_argument(
'--temp-dir',
action='store', dest='temp_dir', required=True,
help='The temp folder used by BMap.'
)
parser.add_argument(
'--texture-dir',
action='store', dest='texture_dir', required=True,
help='The texture folder containing Ballance texture resources.'
)
parser.add_argument(
'--encodings',
action='extend', nargs='+', dest='encodings', required=True,
help='The encodings used to parse the names stroed in input Virtools file.'
)
args = parser.parse_args()
# run main function
main(args.file_path, args.temp_dir, args.texture_dir, tuple(args.encodings))

View File

@@ -0,0 +1,7 @@
@PACKAGE_INIT@
# Include targets file
include("${CMAKE_CURRENT_LIST_DIR}/BMapTargets.cmake")
check_required_components(BMap)

52
CMake/FindSTB.cmake Normal file
View File

@@ -0,0 +1,52 @@
# - Find STB library
# Find the STB headers
#
# This module defines the following variables:
# STB_FOUND - True if STB was found
# STB_INCLUDE_DIRS - Location of the STB headers
#
# This module defines the following imported targets:
# STB::STB - Header-only interface library for STB
# STB_ROOT must be specified by the user
if (NOT DEFINED STB_ROOT)
set(STB_FOUND FALSE)
else ()
# Look for STB_image.h in the specified STB_ROOT directory
find_path(STB_INCLUDE_DIR
NAMES STB_image.h
HINTS ${STB_ROOT}
NO_DEFAULT_PATH
)
# Check find status
if(STB_INCLUDE_DIR)
set(STB_FOUND TRUE)
set(STB_INCLUDE_DIRS ${STB_INCLUDE_DIR})
else()
set(STB_FOUND FALSE)
endif()
# Hide intermediate variables
mark_as_advanced(STB_INCLUDE_DIR)
endif ()
# Check find result
if (STB_FOUND)
# Add library
message(STATUS "Found STB library")
# Add library
add_library(STB INTERFACE IMPORTED)
# Add alias to it
add_library(STB::STB ALIAS STB)
# Setup header files
set_target_properties(STB PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES
"${STB_INCLUDE_DIRS}"
)
else ()
# If it is required, show infomations.
if (std_FIND_REQUIRED)
message(FATAL_ERROR "Fail to find STB library.")
endif ()
endif ()

View File

@@ -1,9 +0,0 @@
if (WIN32)
# In Windows, we should not import Iconv.
# Send a notice to programmer.
message("Windows environment detected, skip finding Iconv!")
else ()
# In non-Windows, we simply import Iconv from CMake preset.
# It will produce Iconv::Iconv target for including and linking.
find_package(Iconv REQUIRED)
endif ()

View File

@@ -1,14 +0,0 @@
# Check stb path variable
if (NOT DEFINED STB_IMAGE_PATH)
message(FATAL_ERROR "You must set STB_IMAGE_PATH variable to the root directory of std-image repository.")
endif()
# Add library
add_library(stb-image INTERFACE IMPORTED)
# Add alias for it
add_library(stb::stb-image ALIAS stb-image)
# Setup header files
set_target_properties(stb-image PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES
"${STB_IMAGE_PATH}"
)

View File

@@ -1,15 +0,0 @@
# Check YYCC path environment variable
if (NOT DEFINED YYCC_PATH)
message(FATAL_ERROR "You must set YYCC_PATH variable to one of YYCC CMake distribution installation path.")
endif()
# Find YYCC library
# It will produce YYCC::YYCCommonplace target for including and linking.
#
# Please note we MUST set CMake variable YYCCommonplace_ROOT to make sure CMake can found YYCC in out given path.
# The cache status of YYCCommonplace_ROOT is doesn't matter.
# CMake will throw error if we use HINTS feature in find_package to find YYCC.
set(YYCCommonplace_ROOT ${YYCC_PATH} CACHE PATH
"The path to YYCC CMake distribution installation path.")
find_package(YYCCommonplace REQUIRED)

View File

@@ -1,34 +0,0 @@
if (WIN32)
# In Windows, we use custom way to import ZLib.
# Before using this CMake file in Windows, you should do following steps first.
# 1. Get ZLib repository: https://github.com/madler/zlib
# 2. Navigate to `contrib/vstudio` and choose a proper Visual Studio project according to your environment.
# 3. Open project file and build. Then you will get the built binary.
# 4. The directory binary located is the argument you should passed to ZLIB_BINARY_PATH, for example: `contrib/vstudio/vc14/x64/ZlibDllRelease`
# Check ZLib path variable
if (NOT DEFINED ZLIB_HEADER_PATH)
message(FATAL_ERROR "You must set ZLIB_HEADER_PATH to the root directory of ZLib repository.")
endif()
if (NOT DEFINED ZLIB_BINARY_PATH)
message(FATAL_ERROR "You must set ZLIB_BINARY_PATH to the directory where include binary built by contributed Visual Studio project.")
endif()
# Add imported library
add_library(ZLIB INTERFACE IMPORTED)
# Add alias for it to let it has the same behavior with CMake imported ZLib.
add_library(ZLIB::ZLIB ALIAS ZLIB)
# Setup header files
set_target_properties(ZLIB PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES
"${ZLIB_HEADER_PATH}"
)
# Setup lib files
set_target_properties(ZLIB PROPERTIES
INTERFACE_LINK_LIBRARIES
"${ZLIB_BINARY_PATH}/zlibwapi.lib"
)
else ()
# In non-Windows, we simply import ZLib from CMake preset.
# It will produce ZLIB::ZLIB target for including and linking.
find_package(ZLIB REQUIRED)
endif ()

View File

@@ -1,6 +1,8 @@
# Minimum required CMake version
cmake_minimum_required(VERSION 3.23) cmake_minimum_required(VERSION 3.23)
# Project definition
project(NeMo project(NeMo
VERSION 0.2.0 VERSION 0.4.0
LANGUAGES CXX LANGUAGES CXX
) )
@@ -9,6 +11,11 @@ option(NEMO_BUILD_UNVIRT "Build Unvirt, the console interface operator of LibCmo
option(NEMO_BUILD_BMAP "Build BMap, the example use of LibCmo which can read and write Ballance game map." OFF) option(NEMO_BUILD_BMAP "Build BMap, the example use of LibCmo which can read and write Ballance game map." OFF)
option(NEMO_BUILD_DOC "Build document of LibCmo and all related stuff." OFF) option(NEMO_BUILD_DOC "Build document of LibCmo and all related stuff." OFF)
# Set C++ standards
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Setup install path from CMake provided install path for convenient use. # Setup install path from CMake provided install path for convenient use.
include(GNUInstallDirs) include(GNUInstallDirs)
set(NEMO_INSTALL_INCLUDE_PATH ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH set(NEMO_INSTALL_INCLUDE_PATH ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH
@@ -20,11 +27,17 @@ set(NEMO_INSTALL_BIN_PATH ${CMAKE_INSTALL_BINDIR} CACHE PATH
set(NEMO_INSTALL_DOC_PATH ${CMAKE_INSTALL_DOCDIR} CACHE PATH set(NEMO_INSTALL_DOC_PATH ${CMAKE_INSTALL_DOCDIR} CACHE PATH
"Non-arch doc install path relative to CMAKE_INSTALL_PREFIX unless set to an absolute path.") "Non-arch doc install path relative to CMAKE_INSTALL_PREFIX unless set to an absolute path.")
# Import essential packages # Add our CMake in module found path
include(${CMAKE_CURRENT_LIST_DIR}/CMake/custom_import_zlib.cmake) set(CMAKE_MODULE_PATH
include(${CMAKE_CURRENT_LIST_DIR}/CMake/custom_import_iconv.cmake) "${CMAKE_CURRENT_LIST_DIR}/CMake"
include(${CMAKE_CURRENT_LIST_DIR}/CMake/custom_import_yycc.cmake) )
include(${CMAKE_CURRENT_LIST_DIR}/CMake/custom_import_stb.cmake) # Find required packages
find_package(ZLIB REQUIRED)
find_package(YYCCommonplace REQUIRED)
find_package(STB REQUIRED)
# Import package helper
include(CMakePackageConfigHelpers)
# If we are not in Windows environment, and we need to build shared library BMap, # If we are not in Windows environment, and we need to build shared library BMap,
# we should enable PIC (position independent code), otherwise build process will fail. # we should enable PIC (position independent code), otherwise build process will fail.
@@ -36,7 +49,7 @@ if ((NOT WIN32) AND NEMO_BUILD_BMAP)
set(CMAKE_POSITION_INDEPENDENT_CODE True) set(CMAKE_POSITION_INDEPENDENT_CODE True)
endif () endif ()
# Import build targets # Include build targets by options
add_subdirectory(LibCmo) add_subdirectory(LibCmo)
if (NEMO_BUILD_UNVIRT) if (NEMO_BUILD_UNVIRT)
add_subdirectory(Unvirt) add_subdirectory(Unvirt)
@@ -47,31 +60,3 @@ endif ()
if (NEMO_BUILD_DOC) if (NEMO_BUILD_DOC)
add_subdirectory(Documents) add_subdirectory(Documents)
endif () endif ()
# Install target and package
# Install target
install(EXPORT LibCmoTargets
FILE LibCmoTargets.cmake
NAMESPACE NeMo::
DESTINATION ${YYCC_INSTALL_LIB_PATH}/cmake/LibCmo
)
# Package configuration file
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
LibCmoConfigVersion.cmake
VERSION ${PACKAGE_VERSION}
COMPATIBILITY SameMinorVersion
)
configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/CMake/LibCmoConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LibCmo
)
# Copy package files to install destination
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfigVersion.cmake"
DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/LibCmo
)

View File

@@ -1,35 +1,43 @@
# Compile Manual # Compile Manual
## Choose Version
We suggest that you only use stable version (tagged commit).
The latest commit always present current works.
It means that it is not stable and work in progress.
## Requirements ## Requirements
This project require:
* CMake 3.23 at least. * CMake 3.23 at least.
* The common compiler supporting C++ 20 (GCC / Clang / MSVC). * The common compiler supporting C++ 23 (GCC / Clang / MSVC).
* Littile-endian architecture system. * Littile-endian architecture system.
* zlib. * zlib.
* iconv (non-Windows system required). * [stb](https://github.com/nothings/stb).
* [stb](https://github.com/nothings/stb): For image read and write. * [YYCCommonplace](https://github.com/yyc12345/YYCCommonplace).
* [YYCCommonplace](https://github.com/yyc12345/YYCCommonplace): My personal invented library concentrating some common functions for mine. * Doxygen (Required if you build documentation).
Since libcmo21 0.2.0, we only provide it in CMake build system. So Windows user should install CMake first or use Visual Studio directly (Visual Studio provides CMake build system supports).
## Preparations ## Preparations
### YYCCommonplace ### YYCCommonplace
You should clone YYCCommonplace and switch to the latest release tag (or specified commit hash provided with libcmo21 release infos if you are building for specific libcmo21 version). When configuring YYCCommonplace, you should notice following infos: Following these steps to prepare YYCCommonplace:
* Please make sure that you have specified C++ 20 explicitly by passing `-DCMAKE_CXX_STANDARD=20` in command line. This is crucial because libcmo21 use C++ 20, and YYCCommonplace's ABI is incompatible between C++ 17 version and C++ 20 version. 1. Clone YYCCommonplace first.
* If you need `BMap` in final libcmo21 built artifacts, and you are in non-Windows system now, please specify position independent code flag by passing `-DCMAKE_POSITION_INDEPENDENT_CODE=True` in command line. GCC and Clang will reject linking if you don't flag it. 1. Switch to the latest **release** tag, or **specified commit hash** provided with libcmo21 release infos if you are building for specific libcmo21 version.
1. Following compile manual provided by YYCCommonplace to configure, compile and install it.
After configuring, you can normally build YYCCommonplace like a common CMake project. > [!IMPORTANT]
> If you need `BMap` component in final libcmo21 built artifacts, and you are in non-Windows system now, please specify position independent code flag by passing `-DCMAKE_POSITION_INDEPENDENT_CODE=True` in command line when configuring YYCCommonplace. Otherwise GCC and Clang will reject linking.
Please note if your final program or dynamic library is provided for end user, please choose `RelWithDebInfo` build type (`Release` is not suggested because it will strip all debug infos and it is not good for bug reporter, which is embedded in program, to report crash). If final program is served for programmer debugging, please choose `Debug` build type.
### stb ### stb
You should clone stb repository first, then switch to a specific commit hash `2e2bef463a5b53ddf8bb788e25da6b8506314c08`. In ideally scenario, people like to choose the latest commit. However, I not frequently update this dependency. Following these steps to prepare stb:
1. Clone stb repository first.
1. Switch to a **specific commit hash** `2e2bef463a5b53ddf8bb788e25da6b8506314c08`. I do not frequently update this dependency so using the latest commit is inviable.
> [!NOTE]
> std is a header-only C project. So we don't need compile it. libcmo21 will use homemade CMake script to find it.
### zlib ### zlib
@@ -37,47 +45,109 @@ If you are in Windows, you should download zlib source code and build it with gi
If you are running on non-Windows system. You usually do not need to do anything. Because zlib development environment may be configured by your package manager correctly. If you are running on non-Windows system. You usually do not need to do anything. Because zlib development environment may be configured by your package manager correctly.
## Compile If you are in Windows, or in Linux but want to use specific zlib version due to various reasons, following these steps to prepare zlib:
### Directory Hierarchy 1. Download zlib source code from its official.
1. Extract it into a directory.
1. Enter this directory and create 2 subdirectory `build` and `install` for CMake build and install respectively.
1. Enter `build` directory and configure CMake with extra `-DCMAKE_CXX_STANDARD=23 -DZLIB_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=<path-to-install>` parameters. And `<path-to-install>` is the absolute path to your created `install` directory in previous step (Idk why `--prefix` argument is not works for zlib).
1. Use CMake to build zlib
1. Use CMake to install zlib into previous we created `install` directory.
First, create subdirectory `Bin/build` and `Bin/install` at the root directory of libcmo21. > [!NOTE]
> We use CMake, rather than any other to compile zlib because zlib provide it, and we also use CMake as our build system, so that we do not need to write any extra files for adaption.
### Configuration > [!CAUTION]
> Windows developer should highly notice that please do NOT use Visual Studio file located in `contrib/vstudio` directory to produce binary zlib on Windows. That project will produce `zlibwapi.dll` which is not our expected `zlib.dll`. Please use Visual Studio embedded CMake to configure zlib and compile it directly.
Then enter subdirectory `Bin/build` and use following command to configure CMake: ### Doxygen
- Windows (MSVC): `cmake -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_DOC=OFF -DSTB_IMAGE_PATH=<path-to-stb> -DYYCC_PATH=<path-to-yycc-install> -DZLIB_HEADER_PATH=<path-to-zlib-hdr> -DZLIB_BINARY_PATH=<path-to-zlib-bin> ../..` Doxygen is required only if you need to build documentation.
- non-Windows: `cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_DOC=OFF -DSTB_IMAGE_PATH=<path-to-stb> -DYYCC_PATH=<path-to-yycc-install> ../..` If you don't need this please skip this chapter.
The arguments in command should be replaced by: We use Doxygen 1.9.7.
It would be okey use other versions but I have not test on them.
* `<path-to-stb>`: The root directory of your cloned stb repository. YYCCommonplace use Doxygen as its documentation system.
* `<path-to-yycc-install>`: The directory to installed CMake package you chosen when building YYCCommonplace. So before compiling, you must make sure `doxygen` are presented in your environment.
* `<path-to-zlib-hdr>` (Windows only): The root directory of downloaded zlib source code.
* `<path-to-zlib-bin>` (Windows only): The directory where you can find built `zlibwapi.dll`.
The switches in command can be switched as you wish: ## Build and Install
* `NEMO_BUILD_UNVIRT`: Build `Unvirt`, a command line application debugging Virtools files. There are 2 different ways to build this project.
* `NEMO_BUILD_BMAP`: Build `BMap`, a dynamic library specific used for loading Ballance map file. If you are coming from my another project [BallanceBlenderPlugin](https://github.com/yyc12345/BallanceBlenderHelper), this is what you need. If you are the user of this project (just want this project to make something works), please choose "User Build".
* `NEMO_BUILD_DOC`: Build the document of libcmo21. If you are a developer (developer of this project, or use this project as dependency to develop your project), please choose "Developer Build".
### Build ### User Build
Execute following command to build libcmo21. "User Build" is basically how GitHub Action build this project.
* Windows: `cmake --build . --config RelWithDebInfo` Under **the root directory** of this project, execute:
* non-Windows: `cmake --build .`
### Build Type - `Script/windows_build.bat` on Windows
- or `Script/linux_build.sh` on Linux
- or `Script/macos_build.sh` on macOS
Like YYCCommonplace, we suggest `RelWithDebInfo` for end user. If you want to build for programmer debugging, please replace all `RelWithDebInfo` to `Debug`. The build type between YYCCommonplace and libcmo21 should keep same to reduce any possibility about ABI incompatible issue. The final built artifact is under `Bin/install` directory.
## Install ### Developer Build
Currently the CMake install script still has some bugs and can not work as expected. So as the alternative, just go into build directory and find your final program please. It's pretty simple. #### Configurable Variables
## Note First, there is a list listing all variables you may configure during compiling.
You may face issue when compiling this program on Linux or macOS because I develop this project on Windows frequently. The compatibility with Linux will only be checked just before releasing. And I don't have any Apple device to check the compatibility with macOS. So, for Linux issue, please report it directly and I will try to fix. For macOS bug, PR is welcomed. * `NEMO_BUILD_UNVIRT`: Set it to `ON` to build `Unvirt`. `ON` in default.
This is an interactive tool for loading, saving Virtools file.
It is extremely useful for debugging this project.
* `NEMO_BUILD_BMAP`: Set it to `ON` to build `BMap`. `OFF` in default.
It is a dynamic library specific used for loading Ballance map file.
If you are coming from my another project [BallanceBlenderPlugin](https://github.com/yyc12345/BallanceBlenderHelper), this is what you need.
* `NEMO_BUILD_DOC`: Set it to `ON` to build documentation. `OFF` in default.
It may be useful for the developer who firstly use this project in their own projects.
Please note that generated documentation is different in different platforms.
* `YYCCommonplace_ROOT`: Set to the install path of YYCCommonplace.
* `stb_ROOT`: Set to the root directory of stb.
* `ZLIB_ROOT`: Set to the install path of zlib.
If you are using zlib which is not build by your own, you usually do not need specify this variable.
#### Configure CMake
When configure CMake, you may use different options on different platforms.
Following list may help you.
- On Windows:
* `-A Win32` or `-A x64` to specify architecture.
- On Linux or other POSIX systems:
* `-DCMAKE_BUILD_TYPE=Debug` or `-DCMAKE_BUILD_TYPE=Release` to specify build type.
Additionally, you can attach any variables introduced above with `-D` option during CMake configurations.
> [!NOTE]
> Position independent code flag is automatically added if you enable `BMap` so you don't need manually specify it. You just need to make sure that all dependencies enable this.
#### Build with CMake
After configuration, you can use `cmake --build .` to build project,
with additional options on different platforms.
Following list may help you.
- On Windows:
* `--config Debug` or `--config Release` to specify build type.
- On Linux or other POSIX systems:
* None
#### Install with CMake
After building, you can use `cmake --install . --prefix <path-to-prefix>`
to install project into given path, with additional options on different platforms.
Following list may help you.
- On Windows:
* `--config Debug` or `--config Release` to specify build type.
- On Linux or other POSIX systems:
* None
## Compatibility Notes
You may face issue when compiling this program on Linux or macOS because I develop this project on Windows frequently.
The compatibility with Linux and macOS will only be checked just before releasing.
And, I don't have any Apple devices, so the compatibility with macOS is checked by GitHub Action.

View File

@@ -188,6 +188,7 @@ public class CSharpWriter {
break; break;
case "CK_TEXTURE_SAVEOPTIONS": case "CK_TEXTURE_SAVEOPTIONS":
case "VX_PIXELFORMAT": case "VX_PIXELFORMAT":
case "VXLIGHT_TYPE":
case "VXTEXTURE_BLENDMODE": case "VXTEXTURE_BLENDMODE":
case "VXTEXTURE_FILTERMODE": case "VXTEXTURE_FILTERMODE":
case "VXTEXTURE_ADDRESSMODE": case "VXTEXTURE_ADDRESSMODE":

View File

@@ -28,6 +28,7 @@ public class PythonWriter {
cache.put("VxMatrix", "VxMatrix"); cache.put("VxMatrix", "VxMatrix");
cache.put("CK_TEXTURE_SAVEOPTIONS", "enum"); cache.put("CK_TEXTURE_SAVEOPTIONS", "enum");
cache.put("VX_PIXELFORMAT", "enum"); cache.put("VX_PIXELFORMAT", "enum");
cache.put("VXLIGHT_TYPE", "enum");
cache.put("VXTEXTURE_BLENDMODE", "enum"); cache.put("VXTEXTURE_BLENDMODE", "enum");
cache.put("VXTEXTURE_FILTERMODE", "enum"); cache.put("VXTEXTURE_FILTERMODE", "enum");
cache.put("VXTEXTURE_ADDRESSMODE", "enum"); cache.put("VXTEXTURE_ADDRESSMODE", "enum");

View File

@@ -170,6 +170,14 @@ public class MainRunner {
PythonWriter.writeAccVal("dest/CK_BITMAPDATA_FLAGS.AccVal.py", single); PythonWriter.writeAccVal("dest/CK_BITMAPDATA_FLAGS.AccVal.py", single);
CSharpWriter.writeAccVal("dest/CK_BITMAPDATA_FLAGS.AccVal.cs", single); CSharpWriter.writeAccVal("dest/CK_BITMAPDATA_FLAGS.AccVal.cs", single);
single = organiseDefines("src/CK_CAMERA_PROJECTION.txt", "CK_CAMERA_PROJECTION");
CppWriter.writeEnum("dest/CK_CAMERA_PROJECTION.hpp", single);
PythonWriter.writeEnum("dest/CK_CAMERA_PROJECTION.py", single);
CSharpWriter.writeEnum("dest/CK_CAMERA_PROJECTION.cs", single);
CppWriter.writeAccVal("dest/CK_CAMERA_PROJECTION.AccVal.hpp", single, CommonHelper.CKParts.CK2);
PythonWriter.writeAccVal("dest/CK_CAMERA_PROJECTION.AccVal.py", single);
CSharpWriter.writeAccVal("dest/CK_CAMERA_PROJECTION.AccVal.cs", single);
// print message. // print message.
System.out.println("DONE!"); System.out.println("DONE!");
} }

View File

@@ -0,0 +1,4 @@
#define CK_PERSPECTIVEPROJECTION 1
#define CK_ORTHOGRAPHICPROJECTION 2

View File

@@ -41,6 +41,25 @@ typedef enum VX_PIXELFORMAT {
_4_ARGB8888_CLUT = 31 // 4 bits indexed CLUT (ARGB) _4_ARGB8888_CLUT = 31 // 4 bits indexed CLUT (ARGB)
} VX_PIXELFORMAT; } VX_PIXELFORMAT;
/******************************************************************
{filename:VXLIGHT_TYPE}
Summary: Light type.
Remarks:
+ Used by CKLight::SetType to specify the type of a light.
See also: CKLight::SetType,CKLight::GetType
******************************************************************/
typedef enum VXLIGHT_TYPE
{
VX_LIGHTPOINT = 1UL, // The Light is a point of light
VX_LIGHTSPOT = 2UL, // The light is a spotlight
VX_LIGHTDIREC = 3UL, // The light is directional light : Lights comes from an infinite point so only direction of light can be given
VX_LIGHTPARA = 4UL // Obsolete, do not use
} VXLIGHT_TYPE;
/***************************************************************** /*****************************************************************
{filename:VXTEXTURE_BLENDMODE} {filename:VXTEXTURE_BLENDMODE}
Summary: Blend Mode Flags Summary: Blend Mode Flags

View File

@@ -1,2 +1,3 @@
# Result # Result
*.hpp VxTypes.hpp
VxTypes.cpp

View File

@@ -1,3 +1,3 @@
# Vector Generator # Vector Generator
Vector types (LibCmo::Vector3 and etc) and Vector-like types (LibCmo::Color and etc) nearly have similar declaration except slight differences (basically is the count of factors). Manually writing these declarations is boring and easy to cause potential invisible bugs. So we use a Python script to generate these declarations batchly to prevent any defects indroduced above. Vector types (LibCmo::VxMath::VxVector3 and etc) and Vector-like types (LibCmo::VxMath::VxColor and etc) nearly have similar declaration except slight differences (basically is the count of factors). Manually writing these declarations is boring and easy to cause potential invisible bugs. So we use a Python script to generate these declarations batchly to prevent any defects indroduced above.

View File

@@ -0,0 +1,178 @@
{% import 'VxTypes.shared.jinja' as shared %}
{#
For friend operator overload, we do not need add CLASSNAME:: prefix for it.
Because they are not a part of that class.
#}
#pragma region {{ sname }}
{# Ctor type 1 - Default ctor -#}
{{ sname }}::{{ sname }}() : {{- shared.initialize_list_builder(svars, False) -}} {} {% if not is_vector %}// SET YOUR CUSTOM INIT{% endif %}
{#- Ctor type 2 - User specified ctor #}
{{ sname }}::{{ sname }}({{- shared.argument_list_builder(svars) -}}) : {{- shared.initialize_list_builder(svars, True) -}} {}
{#- Offset operator #}
CKFLOAT& {{ sname }}::operator[](size_t i) {
switch (i) {
{%- for item in svars %}
case {{ loop.index0 }}: return {{ item }};
{%- endfor %}
default: throw LogicException("Invalid index for {{ sname }}::operator[].");
}
}
const CKFLOAT& {{ sname }}::operator[](size_t i) const {
switch (i) {
{%- for item in svars %}
case {{ loop.index0 }}: return {{ item }};
{%- endfor %}
default: throw LogicException("Invalid index for {{ sname }}::operator[].");
}
}
{#- Equal operator #}
bool {{ sname }}::operator==(const {{ sname }}& rhs) const {
return (
{%- for item in svars -%}
{{ item }} == rhs.{{ item }} {%- if not loop.last %} && {% endif %}
{%- endfor -%}
);
}
{#- Spaceship operator #}
auto {{ sname }}::operator<=>(const {{ sname }}& rhs) const {
{%- for item in svars[:-1] %}
if (auto cmp = {{ item }} <=> rhs.{{ item }}; cmp != 0) return cmp;
{%- endfor %}
return {{ svars[-1] }} <=> rhs.{{ svars[-1] }};
}
{#- BEGIN VECTOR SPECIFIC #}
{%- if is_vector %}
{#- Add, minus operators #}
{#- Unary operators #}
{{ sname }} {{ sname }}::operator+() const {
return *this;
}
{{ sname }} {{ sname }}::operator-() const {
return {{ sname }}(
{%- for item in svars -%}
-{{ item }} {%- if not loop.last %}, {% endif %}
{%- endfor -%}
);
}
{#- Additive operators #}
{{ sname }}& {{ sname }}::operator+=(const {{ sname }}& rhs) {
{%- for item in svars %}
{{ item }} += rhs.{{ item }};
{%- endfor %}
return *this;
}
{{ sname }} operator+(const {{ sname }}& lhs, const {{ sname }}& rhs) {
return {{ sname }}(
{%- for item in svars -%}
lhs.{{ item }} + rhs.{{ item }} {%- if not loop.last %}, {% endif %}
{%- endfor -%}
);
}
{{ sname }}& {{ sname }}::operator-=(const {{ sname }}& rhs) {
{%- for item in svars %}
{{ item }} -= rhs.{{ item }};
{%- endfor %}
return *this;
}
{{ sname }} operator-(const {{ sname }}& lhs, const {{ sname }}& rhs) {
return {{ sname }}(
{%- for item in svars -%}
lhs.{{ item }} - rhs.{{ item }} {%- if not loop.last %}, {% endif %}
{%- endfor -%}
);
}
{#- Mul operator #}
{{ sname }}& {{ sname }}::operator*=(CKFLOAT rhs) {
{%- for item in svars %}
{{ item }} *= rhs;
{%- endfor %}
return *this;
}
{{ sname }} operator*(const {{ sname }}& lhs, CKFLOAT rhs) {
return {{ sname }}(
{%- for item in svars -%}
lhs.{{ item }} * rhs {%- if not loop.last %}, {% endif %}
{%- endfor -%}
);
}
{{ sname }} operator*(CKFLOAT lhs, const {{ sname }}& rhs) {
return {{ sname }}(
{%- for item in svars -%}
lhs * rhs.{{ item }} {%- if not loop.last %}, {% endif %}
{%- endfor -%}
);
}
CKFLOAT operator*(const {{ sname }}& lhs, const {{ sname }}& rhs) {
return (
{%- for item in svars -%}
lhs.{{ item }} * rhs.{{ item }} {%- if not loop.last %} + {% endif %}
{%- endfor -%}
);
}
{#- Div operator #}
{{ sname }}& {{ sname }}::operator/=(CKFLOAT rhs) {
if (rhs == 0.0f) return *this;
{%- for item in svars %}
{{ item }} /= rhs;
{%- endfor %}
return *this;
}
{{ sname }} operator/(const {{ sname }}& lhs, CKFLOAT rhs) {
if (rhs == 0.0f) return {{ sname }}();
else return {{ sname }}(
{%- for item in svars -%}
lhs.{{ item }} / rhs {%- if not loop.last %}, {% endif %}
{%- endfor -%}
);
}
{#- Length functions #}
CKFLOAT {{ sname }}::SquaredLength() const {
return (
{%- for item in svars -%}
{{ item }} * {{ item }} {%- if not loop.last %} + {% endif %}
{%- endfor -%}
);
}
CKFLOAT {{ sname }}::Length() const {
return std::sqrt(SquaredLength());
}
{#- Normalize functions #}
void {{ sname }}::Normalized() {
CKFLOAT len = Length();
if (len == 0.0f) return;
{%- for item in svars %}
{{ item }} /= len;
{%- endfor %}
}
{{ sname }} {{ sname }}::Normalize() const {
CKFLOAT len = Length();
if (len == 0.0f) return {{ sname }}();
else return {{ sname }}(
{%- for item in svars -%}
{{ item }} / len {%- if not loop.last %}, {% endif %}
{%- endfor -%}
);
}
{%- endif %}
{#- END VECTOR SPECIFIC #}
{#- User custom region #}
/* ===== BEGIN USER CUSTOM ===== */
/* ===== END USER CUSTOM ===== */
#pragma endregion

View File

@@ -0,0 +1,65 @@
{% import 'VxTypes.shared.jinja' as shared %}
struct {{ sname }} {
{#- Variable declaration #}
CKFLOAT {{ ", ".join(svars) }};
{#- Ctor type 1 - Default ctor #}
{{ sname }}();
{#- Ctor type 2 - User specified ctor #}
{{ sname }}({{- shared.argument_list_builder(svars) -}});
{#- Default copy ctor, move ctor, copy assigner, move assigner #}
YYCC_DEF_CLS_COPY_MOVE({{ sname }});
{#- Offset operator #}
CKFLOAT& operator[](size_t i);
const CKFLOAT& operator[](size_t i) const;
{#- Equal operator #}
bool operator==(const {{ sname }}& rhs) const;
{#- Spaceship operator #}
auto operator<=>(const {{ sname }}& rhs) const;
{#- BEGIN VECTOR SPECIFIC #}
{%- if is_vector %}
{#- Add, minus operators #}
{#- Unary operators #}
{{ sname }} operator+() const;
{{ sname }} operator-() const;
{#- Additive operators #}
{{ sname }}& operator+=(const {{ sname }}& rhs);
friend {{ sname }} operator+(const {{ sname }}& lhs, const {{ sname }}& rhs);
{{ sname }}& operator-=(const {{ sname }}& rhs);
friend {{ sname }} operator-(const {{ sname }}& lhs, const {{ sname }}& rhs);
{#- Mul operator #}
{{ sname }}& operator*=(CKFLOAT rhs);
friend {{ sname }} operator*(const {{ sname }}& lhs, CKFLOAT rhs);
friend {{ sname }} operator*(CKFLOAT lhs, const {{ sname }}& rhs);
friend CKFLOAT operator*(const {{ sname }}& lhs, const {{ sname }}& rhs);
{#- Div operator #}
{{ sname }}& operator/=(CKFLOAT rhs);
friend {{ sname }} operator/(const {{ sname }}& lhs, CKFLOAT rhs);
{#- Length functions #}
CKFLOAT SquaredLength() const;
CKFLOAT Length() const;
{#- Normalize functions #}
void Normalized();
{{ sname }} Normalize() const;
{%- endif %}
{#- END VECTOR SPECIFIC #}
{#- User custom region #}
/* ===== BEGIN USER CUSTOM ===== */
/* ===== END USER CUSTOM ===== */
};

View File

@@ -0,0 +1,21 @@
{#
The macro to generate C++ ctor argument list
It produce like this: `CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w`
#}
{% macro argument_list_builder(svars) %}
{%- for item in svars -%}
CKFLOAT _{{- item -}}{%- if not loop.last %}, {% endif -%}
{%- endfor -%}
{% endmacro %}
{#
The macro to generate C++ ctor initialize list
It produce like this: `x(0.0f), y(0.0f), z(0.0f), w(0.0f)`
or this: `x(_x), y(_y), z(_z), w(_w)`
according to user request.
#}
{% macro initialize_list_builder(svars, is_user) %}
{%- for item in svars -%}
{{- item -}}({%- if is_user -%}_{{- item -}}{%- else -%}0.0f{%- endif -%}){%- if not loop.last %}, {% endif -%}
{%- endfor -%}
{% endmacro %}

View File

@@ -0,0 +1,63 @@
import os
import io
import typing
import jinja2
g_HppTemplateFile: str = 'VxTypes.hpp.jinja'
g_CppTemplateFile: str = 'VxTypes.cpp.jinja'
g_ResultHppFile: str = 'VxTypes.hpp'
g_ResultCppFile: str = 'VxTypes.cpp'
def get_root_directory() -> str:
return os.path.dirname(__file__)
class TemplateRender:
m_Loader: jinja2.BaseLoader
m_Environment: jinja2.Environment
m_HppTemplate: jinja2.Template
m_CppTemplate: jinja2.Template
m_OutputHpp: io.TextIOWrapper
m_OutputCpp: io.TextIOWrapper
def __init__(self, output_hpp_path: str, output_cpp_path: str) -> None:
self.m_Loader = jinja2.FileSystemLoader(get_root_directory())
self.m_Environment = jinja2.Environment(loader=self.m_Loader)
self.m_HppTemplate = self.m_Environment.get_template(g_HppTemplateFile)
self.m_CppTemplate = self.m_Environment.get_template(g_CppTemplateFile)
self.m_OutputHpp = open(os.path.join(get_root_directory(), output_hpp_path), 'w', encoding='utf-8')
self.m_OutputCpp = open(os.path.join(get_root_directory(), output_cpp_path), 'w', encoding='utf-8')
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
self.m_OutputHpp.close()
self.m_OutputCpp.close()
def __render(self, sname: str, is_vector: bool, svars: tuple[str]) -> None:
template_argument: dict[str, typing.Any] = {
'sname': sname,
'is_vector': is_vector,
'svars': svars
}
self.m_OutputHpp.write(self.m_HppTemplate.render(**template_argument))
self.m_OutputCpp.write(self.m_CppTemplate.render(**template_argument))
def render_vector(self, sname: str, svars: tuple[str]) -> None:
self.__render(sname, True, svars)
def render_others(self, sname: str, svars: tuple[str]) -> None:
self.__render(sname, False, svars)
if __name__ == '__main__':
with TemplateRender(g_ResultHppFile, g_ResultCppFile) as render:
render.render_vector('VxVector2', ('x', 'y', ))
render.render_vector('VxVector3', ('x', 'y', 'z', ))
render.render_vector('VxVector4', ('x', 'y', 'z', 'w', ))
render.render_others('VxQuaternion', ('x', 'y', 'z', 'w', ))
render.render_others('VxColor', ('r', 'g', 'b', 'a', ))

View File

@@ -1,166 +0,0 @@
import os
def GetTmplDecl(svars: tuple[str]) -> str:
return f'CKFLOAT {", ".join(svars)};'
def GetTmplCtor1(sname: str, svars: tuple[str]) -> str:
return f'{sname}() : {", ".join(map(lambda x: f"{x}(0.0f)", svars))} {{}}'
def GetTmplCtor2(sname: str, svars: tuple[str]) -> str:
return f'{sname}({", ".join(map(lambda x: f"CKFLOAT _{x}", svars))}) : {", ".join(map(lambda x: f"{x}(_{x})", svars))} {{}}'
def GetTmplCopyCtor(sname: str, svars: tuple[str]) -> str:
return f'{sname}(const {sname}& rhs) : {", ".join(map(lambda x: f"{x}(rhs.{x})", svars))} {{}}'
def GetTmplMoveCtor(sname: str, svars: tuple[str]) -> str:
return f'{sname}({sname}&& rhs) : {", ".join(map(lambda x: f"{x}(rhs.{x})", svars))} {{}}'
def GetTmplOperAssignCopy(sname: str, svars: tuple[str]) -> str:
sp: str = '\n\t\t'
return f"""\t{sname}& operator=(const {sname}& rhs) {{
\t\t{sp.join(map(lambda x: f'{x} = rhs.{x};', svars))}
\t\treturn *this;
\t}}"""
def GetTmplOperAssignMove(sname: str, svars: tuple[str]) -> str:
sp: str = '\n\t\t'
return f"""\t{sname}& operator=({sname}&& rhs) {{
\t\t{sp.join(map(lambda x: f'{x} = rhs.{x};', svars))}
\t\treturn *this;
\t}}"""
def GetTmplOperOffset(sname: str, svars: tuple[str]) -> str:
sp: str = '\n\t\t\t'
return f"""\tCKFLOAT& operator[](size_t i) {{
\t\tswitch (i) {{
\t\t\t{sp.join(map(lambda x: f'case {x}: return {svars[x]};', range(len(svars))))}
\t\t\tdefault: throw LogicException("Invalid index for {sname}::operator[].");
\t\t}}
\t}}
\tconst CKFLOAT& operator[](size_t i) const {{
\t\tswitch (i) {{
\t\t\t{sp.join(map(lambda x: f'case {x}: return {svars[x]};', range(len(svars))))}
\t\t\tdefault: throw LogicException("Invalid index for {sname}::operator[].");
\t\t}}
\t}}"""
def GetTmplOperAddMinus(sname: str, svars: tuple[str], oper: str) -> str:
sp: str = '\n\t\t'
return f"""\t{sname}& operator{oper}=(const {sname}& rhs) {{
\t\t{sp.join(map(lambda x: f'{x} {oper}= rhs.{x};', svars))}
\t\treturn *this;
\t}}
\tfriend {sname} operator{oper}(const {sname}& lhs, const {sname}& rhs) {{
\t\treturn {sname}({', '.join(map(lambda x: f'lhs.{x} {oper} rhs.{x}', svars))});
\t}}"""
def GetTmplOperMul(sname: str, svars: tuple[str]) -> str:
sp: str = '\n\t\t'
return f"""\t{sname}& operator*=(CKFLOAT rhs) {{
\t\t{sp.join(map(lambda x: f'{x} *= rhs;', svars))}
\t\treturn *this;
\t}}
\tfriend {sname} operator*(const {sname}& lhs, CKFLOAT rhs) {{
\t\treturn {sname}({', '.join(map(lambda x: f'lhs.{x} * rhs', svars))});
\t}}
\tfriend {sname} operator*(CKFLOAT lhs, const {sname}& rhs) {{
\t\treturn {sname}({', '.join(map(lambda x: f'lhs * rhs.{x}', svars))});
\t}}
\tfriend CKFLOAT operator*(const {sname}& lhs, const {sname}& rhs) {{
\t\treturn ({' + '.join(map(lambda x: f'lhs.{x} * rhs.{x}', svars))});
\t}}"""
def GetTmplOperDiv(sname: str, svars: tuple[str]) -> str:
sp: str = '\n\t\t'
return f"""\t{sname}& operator/=(CKFLOAT rhs) {{
\t\tif (rhs == 0.0f) return *this;
\t\t{sp.join(map(lambda x: f'{x} /= rhs;', svars))}
\t\treturn *this;
\t}}
\tfriend {sname} operator/(const {sname}& lhs, CKFLOAT rhs) {{
\t\tif (rhs == 0.0f) return {sname}({', '.join(map(lambda x: '0.0f', range(len(svars))))});
\t\treturn {sname}({', '.join(map(lambda x: f'lhs.{x} / rhs', svars))});
\t}}"""
def GetTmplOperEqual(sname: str, svars: tuple[str]) -> str:
return f"""\tbool operator==(const {sname}& rhs) const {{
\t\treturn ({' && '.join(map(lambda x: f'{x} == rhs.{x}', svars))});
\t}}"""
def GetTmplOperSpaceship(sname: str, svars: tuple[str]) -> str:
sp: str = '\n\t\t'
return f"""\tauto operator<=>(const {sname}& rhs) const {{
\t\t{sp.join(map(lambda x: f'if (auto cmp = {x} <=> rhs.{x}; cmp != 0) return cmp;', svars[:-1]))}
\t\treturn {svars[-1]} <=> rhs.{svars[-1]};
\t}}"""
def GetTmplLength(sname: str, svars: tuple[str]) -> str:
return f"""\tCKFLOAT SquaredLength() const {{
\t\treturn ({' + '.join(map(lambda x: f'{x} * {x}', svars))});
\t}}
\tCKFLOAT Length() const {{
\t\treturn std::sqrt(SquaredLength());
\t}}"""
def GetTmplNormalize(sname: str, svars: tuple[str]) -> str:
sp: str = '\n\t\t'
return f"""\tvoid Normalized() {{
\t\tCKFLOAT len = Length();
\t\tif (len == 0.0f) return;
\t\t{sp.join(map(lambda x: f'{x} /= len;', svars))}
\t}}
\t{sname} Normalize() const {{
\t\tCKFLOAT len = Length();
\t\tif (len == 0.0f) return {sname}();
\t\treturn {sname}({', '.join(map(lambda x: f'{x} / len', svars))});
\t}}"""
def GetTmplVector(sname: str, svars: tuple[str]) -> str:
return f"""
struct {sname} {{
\t{GetTmplDecl(svars)}
\t{GetTmplCtor1(sname, svars)}
\t{GetTmplCtor2(sname, svars)}
\tYYCC_DEF_CLS_COPY_MOVE({sname});
{GetTmplOperOffset(sname, svars)}
{GetTmplOperAddMinus(sname, svars, '+')}
{GetTmplOperAddMinus(sname, svars, '-')}
{GetTmplOperMul(sname, svars)}
{GetTmplOperDiv(sname, svars)}
{GetTmplOperEqual(sname, svars)}
{GetTmplOperSpaceship(sname, svars)}
{GetTmplLength(sname, svars)}
{GetTmplNormalize(sname, svars)}
}};
"""
def GetTmplOthers(sname: str, svars: tuple[str]) -> str:
return f"""
struct {sname} {{
\t{GetTmplDecl(svars)}
\t{GetTmplCtor1(sname, svars)} // set your custom init.
\t{GetTmplCtor2(sname, svars)}
\tYYCC_DEF_CLS_COPY_MOVE({sname});
{GetTmplOperOffset(sname, svars)}
{GetTmplOperEqual(sname, svars)}
{GetTmplOperSpaceship(sname, svars)}
}};
"""
# use YYCC_DEF_CLS_COPY_MOVE instead of these outputs.
#\t{GetTmplCopyCtor(sname, svars)}
#\t{GetTmplMoveCtor(sname, svars)}
#{GetTmplOperAssignCopy(sname, svars)}
#{GetTmplOperAssignMove(sname, svars)}
if __name__ == '__main__':
# get file path
self_path: str = os.path.dirname(__file__)
cpp_file: str = os.path.join(self_path, 'VxTypes.hpp')
# generate files
with open(cpp_file, 'w', encoding='utf-8') as fs:
fs.write(GetTmplVector('VxVector2', ('x', 'y', )))
fs.write(GetTmplVector('VxVector3', ('x', 'y', 'z', )))
fs.write(GetTmplVector('VxVector4', ('x', 'y', 'z', 'w', )))
fs.write(GetTmplOthers('VxQuaternion', ('x', 'y', 'z', 'w', )))
fs.write(GetTmplOthers('VxColor', ('r', 'g', 'b', 'a', )))

View File

@@ -1,85 +1,101 @@
# Configure version file
configure_file(
${CMAKE_CURRENT_LIST_DIR}/LibCmo/VTVersion.hpp.in
${CMAKE_CURRENT_LIST_DIR}/LibCmo/VTVersion.hpp
@ONLY
)
# Create static library # Create static library
add_library(LibCmo STATIC "") add_library(LibCmo STATIC "")
# Setup static library sources # Setup static library sources
target_sources(LibCmo target_sources(LibCmo
PRIVATE PRIVATE
# Assistant source files # NeMo Shared
VTEncoding.cpp LibCmo/VTUtils.cpp
VTImage.cpp LibCmo/VTImage.cpp
# CK2 # CK2
CK2/CKBitmapData.cpp LibCmo/CK2/CKBitmapData.cpp
CK2/CKContext.cpp LibCmo/CK2/CKContext.cpp
CK2/CKFileOthers.cpp LibCmo/CK2/CKFileOthers.cpp
CK2/CKFileReader.cpp LibCmo/CK2/CKFileReader.cpp
CK2/CKFileWriter.cpp LibCmo/CK2/CKFileWriter.cpp
CK2/CKGlobals.cpp LibCmo/CK2/CKGlobals.cpp
CK2/CKStateChunkOthers.cpp LibCmo/CK2/CKStateChunkOthers.cpp
CK2/CKStateChunkReader.cpp LibCmo/CK2/CKStateChunkReader.cpp
CK2/CKStateChunkWriter.cpp LibCmo/CK2/CKStateChunkWriter.cpp
# CK2 Data Handler # CK2 Data Handler
CK2/DataHandlers/CKBitmapHandler.cpp LibCmo/CK2/DataHandlers/CKBitmapHandler.cpp
# CK2 Manager # CK2 Manager
CK2/MgrImpls/CKBaseManager.cpp LibCmo/CK2/MgrImpls/CKBaseManager.cpp
CK2/MgrImpls/CKObjectManager.cpp LibCmo/CK2/MgrImpls/CKObjectManager.cpp
CK2/MgrImpls/CKPathManager.cpp LibCmo/CK2/MgrImpls/CKPathManager.cpp
# CK2 Object # CK2 Object
CK2/ObjImpls/CK3dEntity.cpp LibCmo/CK2/ObjImpls/CK3dEntity.cpp
CK2/ObjImpls/CKBeObject.cpp LibCmo/CK2/ObjImpls/CKBeObject.cpp
CK2/ObjImpls/CKGroup.cpp LibCmo/CK2/ObjImpls/CKGroup.cpp
CK2/ObjImpls/CKMaterial.cpp LibCmo/CK2/ObjImpls/CKMaterial.cpp
CK2/ObjImpls/CKMesh.cpp LibCmo/CK2/ObjImpls/CKMesh.cpp
CK2/ObjImpls/CKObject.cpp LibCmo/CK2/ObjImpls/CKObject.cpp
CK2/ObjImpls/CKTexture.cpp LibCmo/CK2/ObjImpls/CKTexture.cpp
LibCmo/CK2/ObjImpls/CKLight.cpp
LibCmo/CK2/ObjImpls/CKTargetLight.cpp
LibCmo/CK2/ObjImpls/CKCamera.cpp
LibCmo/CK2/ObjImpls/CKTargetCamera.cpp
# VxMath # VxMath
VxMath/VxMemoryMappedFile.cpp LibCmo/VxMath/VxMemoryMappedFile.cpp
VxMath/VxMath.cpp LibCmo/VxMath/VxTypes.cpp
LibCmo/VxMath/VxMath.cpp
# X Container # X Container
XContainer/XTypes.cpp LibCmo/XContainer/XTypes.cpp
) )
# Setup static library headers # Setup static library headers
target_sources(LibCmo target_sources(LibCmo
PUBLIC PUBLIC
FILE_SET HEADERS FILE_SET HEADERS
FILES FILES
# Asststant header files # NeMo Shared
VTInternal.hpp
VTEncoding.hpp
VTUtils.hpp
VTAll.hpp VTAll.hpp
LibCmo/VTVersion.hpp
LibCmo/VTInternal.hpp
LibCmo/VTUtils.hpp
# CK2 # CK2
CK2/CKDefines.hpp LibCmo/CK2/CKDefines.hpp
CK2/CKEnums.hpp LibCmo/CK2/CKEnums.hpp
CK2/CKGlobals.hpp LibCmo/CK2/CKGlobals.hpp
CK2/CKIdentifiers.hpp LibCmo/CK2/CKIdentifiers.hpp
CK2/CKTypes.hpp LibCmo/CK2/CKTypes.hpp
CK2/CKBitmapData.hpp LibCmo/CK2/CKBitmapData.hpp
CK2/CKContext.hpp LibCmo/CK2/CKContext.hpp
CK2/CKFile.hpp LibCmo/CK2/CKFile.hpp
CK2/CKStateChunk.hpp LibCmo/CK2/CKStateChunk.hpp
# CK2 Data Handler # CK2 Data Handler
CK2/DataHandlers/CKBitmapHandler.hpp LibCmo/CK2/DataHandlers/CKBitmapHandler.hpp
# CK2 Manager # CK2 Manager
CK2/MgrImpls/CKBaseManager.hpp LibCmo/CK2/MgrImpls/CKBaseManager.hpp
CK2/MgrImpls/CKObjectManager.hpp LibCmo/CK2/MgrImpls/CKObjectManager.hpp
CK2/MgrImpls/CKPathManager.hpp LibCmo/CK2/MgrImpls/CKPathManager.hpp
# CK2 Object # CK2 Object
CK2/ObjImpls/CK3dEntity.hpp LibCmo/CK2/ObjImpls/CK3dEntity.hpp
CK2/ObjImpls/CKBeObject.hpp LibCmo/CK2/ObjImpls/CKBeObject.hpp
CK2/ObjImpls/CKGroup.hpp LibCmo/CK2/ObjImpls/CKGroup.hpp
CK2/ObjImpls/CKMaterial.hpp LibCmo/CK2/ObjImpls/CKMaterial.hpp
CK2/ObjImpls/CKMesh.hpp LibCmo/CK2/ObjImpls/CKMesh.hpp
CK2/ObjImpls/CKObject.hpp LibCmo/CK2/ObjImpls/CKObject.hpp
CK2/ObjImpls/CKTexture.hpp LibCmo/CK2/ObjImpls/CKTexture.hpp
CK2/ObjImpls/CK3dObject.hpp LibCmo/CK2/ObjImpls/CK3dObject.hpp
CK2/ObjImpls/CKRenderObject.hpp LibCmo/CK2/ObjImpls/CKRenderObject.hpp
CK2/ObjImpls/CKSceneObject.hpp LibCmo/CK2/ObjImpls/CKSceneObject.hpp
LibCmo/CK2/ObjImpls/CKLight.hpp
LibCmo/CK2/ObjImpls/CKTargetLight.hpp
LibCmo/CK2/ObjImpls/CKCamera.hpp
LibCmo/CK2/ObjImpls/CKTargetCamera.hpp
# VxMath # VxMath
VxMath/VxTypes.hpp LibCmo/VxMath/VxTypes.hpp
VxMath/VxMath.hpp LibCmo/VxMath/VxMath.hpp
VxMath/VxEnums.hpp LibCmo/VxMath/VxEnums.hpp
VxMath/VxMemoryMappedFile.hpp LibCmo/VxMath/VxMemoryMappedFile.hpp
# X Container # X Container
XContainer/XTypes.hpp LibCmo/XContainer/XTypes.hpp
) )
# Setup include and linked library infomation # Setup include and linked library infomation
target_include_directories(LibCmo target_include_directories(LibCmo
@@ -92,32 +108,13 @@ PUBLIC
YYCC::YYCCommonplace YYCC::YYCCommonplace
PRIVATE PRIVATE
ZLIB::ZLIB ZLIB::ZLIB
stb::stb-image STB::STB
)
if (NOT WIN32)
target_link_libraries(LibCmo PRIVATE Iconv::Iconv)
endif ()
# Setup C++ standard
set_target_properties(LibCmo
PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED 20
CXX_EXTENSION OFF
) )
target_compile_definitions(LibCmo target_compile_definitions(LibCmo
# Expose LibCmo build type # Expose LibCmo build type
PUBLIC PUBLIC
"$<$<CONFIG:Debug>:LIBCMO_BUILD_DEBUG>" "$<$<CONFIG:Debug>:LIBCMO_BUILD_DEBUG>"
"$<$<CONFIG:Release,RelWithDebInfo,MinSize>:LIBCMO_BUILD_RELEASE>" "$<$<CONFIG:Release,RelWithDebInfo,MinSize>:LIBCMO_BUILD_RELEASE>"
# Unicode charset for private using
PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:UNICODE>
$<$<CXX_COMPILER_ID:MSVC>:_UNICODE>
)
target_compile_options(LibCmo
# Order build as UTF-8 in MSVC
PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/utf-8>
) )
# Install binary and headers # Install binary and headers
@@ -128,3 +125,28 @@ install(TARGETS LibCmo
INCLUDES DESTINATION ${NEMO_INSTALL_INCLUDE_PATH} INCLUDES DESTINATION ${NEMO_INSTALL_INCLUDE_PATH}
FILE_SET HEADERS DESTINATION ${NEMO_INSTALL_INCLUDE_PATH} FILE_SET HEADERS DESTINATION ${NEMO_INSTALL_INCLUDE_PATH}
) )
# Install target
install(EXPORT LibCmoTargets
FILE LibCmoTargets.cmake
NAMESPACE NeMo::
DESTINATION ${NEMO_INSTALL_LIB_PATH}/cmake/LibCmo
)
# Package configuration file
write_basic_package_version_file(
LibCmoConfigVersion.cmake
VERSION ${PACKAGE_VERSION}
COMPATIBILITY SameMinorVersion
)
configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/../CMake/LibCmoConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfig.cmake"
INSTALL_DESTINATION ${NEMO_INSTALL_LIB_PATH}/cmake/LibCmo
)
# Copy package files to install destination
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfigVersion.cmake"
DESTINATION
${NEMO_INSTALL_LIB_PATH}/cmake/LibCmo
)

2
LibCmo/LibCmo/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
# Ignore CMake generated version header
VTVersion.hpp

View File

@@ -264,8 +264,7 @@ namespace LibCmo::CK2 {
va_list argptr; va_list argptr;
va_start(argptr, fmt); va_start(argptr, fmt);
XContainer::XString result; XContainer::XString result(YYCC::StringHelper::VPrintf(fmt, argptr));
YYCC::StringHelper::VPrintf(fmt, argptr);
va_end(argptr); va_end(argptr);
// use c_str(), not XContainer::NSXString::ToCKSTRING because we want make sure this paramter is not nullptr. // use c_str(), not XContainer::NSXString::ToCKSTRING because we want make sure this paramter is not nullptr.

View File

@@ -141,6 +141,28 @@ namespace LibCmo::CK2 {
CKFileExtension m_Ext; /**< File Extension of the image being described by this structure */ CKFileExtension m_Ext; /**< File Extension of the image being described by this structure */
}; };
/**
* @brief Light Structure passed to CKRasterizerContext::SetLight()
* @details
* This struct is a part of CKRasterizer.
* I put it in there just for the convenience of CKLight.
*/
struct CKLightData {
VxMath::VXLIGHT_TYPE m_Type; /**< Point, Spot, Directionnal */
VxMath::VxColor m_Diffuse; /**< Diffuse Color */
VxMath::VxColor m_Specular; /**< Specular Color (Unused...) */
VxMath::VxColor m_Ambient; /**< Ambient Color (Unused...) */
VxMath::VxVector3 m_Position; /**< World Position */
VxMath::VxVector3 m_Direction; /**< Direction */
CKFLOAT m_Range; /**< Range */
CKFLOAT m_Falloff;
CKFLOAT m_Attenuation0;
CKFLOAT m_Attenuation1;
CKFLOAT m_Attenuation2;
CKFLOAT m_InnerSpotCone; /**< Only for spot lights */
CKFLOAT m_OuterSpotCone; /**< Only for spot lights */
};
#pragma endregion #pragma endregion

View File

@@ -256,4 +256,9 @@ namespace LibCmo::CK2 {
CKBITMAPDATA_DYNAMIC = 64, CKBITMAPDATA_DYNAMIC = 64,
}; };
enum class CK_CAMERA_PROJECTION : CKDWORD {
CK_PERSPECTIVEPROJECTION = 1,
CK_ORTHOGRAPHICPROJECTION = 2,
};
} }

View File

@@ -44,9 +44,9 @@ namespace LibCmo::CK2 {
const void* GetPtr(CKINT extraoff = 0) { return (this->m_MemBegin + m_MemPos + extraoff); } const void* GetPtr(CKINT extraoff = 0) { return (this->m_MemBegin + m_MemPos + extraoff); }
void* GetMutablePtr(CKINT extraoff = 0) { return (this->m_MemBegin + m_MemPos + extraoff); } void* GetMutablePtr(CKINT extraoff = 0) { return (this->m_MemBegin + m_MemPos + extraoff); }
void* GetBase(void) { return this->m_MemBegin; } void* GetBase() { return this->m_MemBegin; }
CKDWORD GetSize(void) { return this->m_MemSize; } CKDWORD GetSize() { return this->m_MemSize; }
CKDWORD GetCursor(void) { return this->m_MemPos; } CKDWORD GetCursor() { return this->m_MemPos; }
void MoveCursor(CKINT off) { this->m_MemPos += off; } void MoveCursor(CKINT off) { this->m_MemPos += off; }
void SetCursor(CKDWORD off) { this->m_MemPos = off; } void SetCursor(CKDWORD off) { this->m_MemPos = off; }
void Read(void* data, CKDWORD data_size) { void Read(void* data, CKDWORD data_size) {

View File

@@ -89,20 +89,49 @@ namespace LibCmo::CK2 {
// reset crc field of header // reset crc field of header
rawHeader.Crc = 0u; rawHeader.Crc = 0u;
// compute crc // Compute and check CRC in theory (< Virtools 4.0)
CKDWORD gotten_crc = CKComputeDataCRC(&rawHeader, CKSizeof(CKRawFileInfo), 0u); CKDWORD gotten_crc = CKComputeDataCRC(&rawHeader, CKSizeof(CKRawFileInfo), 0u);
parser->SetCursor(sizeof(CKRawFileInfo)); parser->SetCursor(CKSizeof(CKRawFileInfo));
gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_FileInfo.Hdr1PackSize, gotten_crc); gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_FileInfo.Hdr1PackSize, gotten_crc);
parser->MoveCursor(this->m_FileInfo.Hdr1PackSize); parser->MoveCursor(this->m_FileInfo.Hdr1PackSize);
gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_FileInfo.DataPackSize, gotten_crc); gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_FileInfo.DataPackSize, gotten_crc);
if (gotten_crc != this->m_FileInfo.Crc) { if (gotten_crc != this->m_FileInfo.Crc) {
this->m_Ctx->OutputToConsole(u8"Virtools file CRC error."); // MARK:
return CKERROR::CKERR_FILECRCERROR; // If the CRC check failed, there is another way to compute CRC. (>= Virtools 4.0)
// This is a patch for Dassault stupid programmer.
//
// After Virtools 4.0, Dassault use a new way to compute the CRC of file.
// Dassault introduces a new class called CKMemoryBufferWriter which use file and memory map to handle big file properly.
// This algorithm splits the whole data body into 8 MB chunks and calculate them one by one to avoid instantaneous memory occupation.
// However, there is a bug in virtual function CKMemoryBufferWriter::ComputeCRC.
// It takes `PreviousCRC` as argument but never use it in function.
// In this function, the start value of CRC compution is hardcoded 0.
// So, although Dassault programmer try to compute CRC for file header, header part and daat part in code, it actually only compute CRC for data part!
// I 100% sure this is the mistake of Dassault stupid programmer and this bug cause more horrible result.
//
// In Virtools 2.1, engine will check CRC of file first. If no matched CRC, engine will reject loading file.
// So the obvious result is that we can not load file saved by Virtools 4.0 in Virtools 2.1.
// But this is not the point which makes me indignant.
// The real weird point is that we can use Virtools 3.5 to open file saved by Virtools 4.0, but why?
// After some researches, I found that the programmer of Dassault totally removed CRC check when loading file, since some version which I don't know, to suppress this bug!
// This is totally cheat and commercial-oriented behavior!
// I guess Dassault programmer also found that they can not load new created file in old Virtools.
// But they didn't find out what cause this bug, and just directly remove the whole of CRC checker to resolve this bug!
// I can't believe that this thing happens on such official software.
// This is the point which makes me indignant.
gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_FileInfo.DataPackSize, 0u);
// Both CRC compute methods are failed. This file may be really broken.
// Report exception directly.
if (gotten_crc != this->m_FileInfo.Crc) {
this->m_Ctx->OutputToConsole(u8"Virtools file CRC error.");
return CKERROR::CKERR_FILECRCERROR;
}
} }
// reset cursor // reset cursor
parser->SetCursor(sizeof(CKRawFileInfo)); parser->SetCursor(CKSizeof(CKRawFileInfo));
// compare size to decide wheher use compress feature // compare size to decide wheher use compress feature
if (this->m_FileInfo.Hdr1PackSize != this->m_FileInfo.Hdr1UnPackSize) { if (this->m_FileInfo.Hdr1PackSize != this->m_FileInfo.Hdr1UnPackSize) {
@@ -189,7 +218,7 @@ namespace LibCmo::CK2 {
if (this->m_FileInfo.FileVersion >= 8) { if (this->m_FileInfo.FileVersion >= 8) {
// file ver >= 8, use header offset // file ver >= 8, use header offset
// because it have compress feature // because it have compress feature
ParserPtr->SetCursor(this->m_FileInfo.Hdr1PackSize + sizeof(CKRawFileInfo)); ParserPtr->SetCursor(this->m_FileInfo.Hdr1PackSize + CKSizeof(CKRawFileInfo));
} else { } else {
// otherwise, sync with current parser. // otherwise, sync with current parser.
ParserPtr->SetCursor(parser->GetCursor()); ParserPtr->SetCursor(parser->GetCursor());
@@ -397,7 +426,7 @@ namespace LibCmo::CK2 {
} }
// ========== finalize work ========== // ========== finalize work ==========
// set done flag and return // set done flag and return
this->m_Done = true; this->m_Done = true;

View File

@@ -20,6 +20,10 @@
#include "ObjImpls/CKTexture.hpp" #include "ObjImpls/CKTexture.hpp"
#include "ObjImpls/CKMaterial.hpp" #include "ObjImpls/CKMaterial.hpp"
#include "ObjImpls/CKMesh.hpp" #include "ObjImpls/CKMesh.hpp"
#include "ObjImpls/CKLight.hpp"
#include "ObjImpls/CKTargetLight.hpp"
#include "ObjImpls/CKCamera.hpp"
#include "ObjImpls/CKTargetCamera.hpp"
namespace LibCmo::CK2 { namespace LibCmo::CK2 {
@@ -439,6 +443,10 @@ CKClassRegister(cid, parentCid, \
EasyClassReg(ObjImpls::CKTexture, CK_CLASSID::CKCID_TEXTURE, CK_CLASSID::CKCID_BEOBJECT, "Texture"); EasyClassReg(ObjImpls::CKTexture, CK_CLASSID::CKCID_TEXTURE, CK_CLASSID::CKCID_BEOBJECT, "Texture");
EasyClassRegWithNotify(ObjImpls::CKMaterial, CK_CLASSID::CKCID_MATERIAL, CK_CLASSID::CKCID_BEOBJECT, "Material", { CK_CLASSID::CKCID_TEXTURE }); EasyClassRegWithNotify(ObjImpls::CKMaterial, CK_CLASSID::CKCID_MATERIAL, CK_CLASSID::CKCID_BEOBJECT, "Material", { CK_CLASSID::CKCID_TEXTURE });
EasyClassRegWithNotify(ObjImpls::CKMesh, CK_CLASSID::CKCID_MESH, CK_CLASSID::CKCID_BEOBJECT, "Mesh", { CK_CLASSID::CKCID_MATERIAL }); EasyClassRegWithNotify(ObjImpls::CKMesh, CK_CLASSID::CKCID_MESH, CK_CLASSID::CKCID_BEOBJECT, "Mesh", { CK_CLASSID::CKCID_MATERIAL });
EasyClassReg(ObjImpls::CKLight, CK_CLASSID::CKCID_LIGHT, CK_CLASSID::CKCID_3DENTITY, "Light");
EasyClassReg(ObjImpls::CKCamera, CK_CLASSID::CKCID_CAMERA, CK_CLASSID::CKCID_3DENTITY, "Camera");
EasyClassRegWithNotify(ObjImpls::CKTargetLight, CK_CLASSID::CKCID_TARGETLIGHT, CK_CLASSID::CKCID_LIGHT, "Target Light", { CK_CLASSID::CKCID_3DENTITY });
EasyClassRegWithNotify(ObjImpls::CKTargetCamera, CK_CLASSID::CKCID_TARGETCAMERA, CK_CLASSID::CKCID_CAMERA, "Target Camera", { CK_CLASSID::CKCID_3DENTITY });
#undef EasyClassReg #undef EasyClassReg
#undef EasyClassRegWithNotify #undef EasyClassRegWithNotify

View File

@@ -265,8 +265,8 @@ namespace LibCmo::CK2 {
#pragma region Read Function #pragma region Read Function
public: public:
void StartRead(void); void StartRead();
void StopRead(void); void StopRead();
/* ========== Identifier Functions ==========*/ /* ========== Identifier Functions ==========*/
@@ -556,7 +556,7 @@ namespace LibCmo::CK2 {
/* /*
* Actually this function mix various functions, including CloseChunk(), UpdateSize() and etc. * Actually this function mix various functions, including CloseChunk(), UpdateSize() and etc.
*/ */
void StopWrite(void); void StopWrite();
/* ========== Identifier Functions ==========*/ /* ========== Identifier Functions ==========*/

View File

@@ -4,7 +4,7 @@
namespace LibCmo::CK2 { namespace LibCmo::CK2 {
void CKStateChunk::StartRead(void) { void CKStateChunk::StartRead() {
if (this->m_Parser.m_Status != CKStateChunkStatus::IDLE) return; if (this->m_Parser.m_Status != CKStateChunkStatus::IDLE) return;
this->m_Parser.m_CurrentPos = 0u; this->m_Parser.m_CurrentPos = 0u;
@@ -13,7 +13,7 @@ namespace LibCmo::CK2 {
this->m_Parser.m_Status = CKStateChunkStatus::READ; this->m_Parser.m_Status = CKStateChunkStatus::READ;
} }
void CKStateChunk::StopRead(void) { void CKStateChunk::StopRead() {
if (this->m_Parser.m_Status != CKStateChunkStatus::READ) return; if (this->m_Parser.m_Status != CKStateChunkStatus::READ) return;
this->m_Parser.m_CurrentPos = 0u; this->m_Parser.m_CurrentPos = 0u;
@@ -220,7 +220,7 @@ namespace LibCmo::CK2 {
return true; return true;
} }
//CKStateChunk* CKStateChunk::ReadSubChunk(void) { //CKStateChunk* CKStateChunk::ReadSubChunk() {
// CKStateChunk* subchunk = nullptr; // CKStateChunk* subchunk = nullptr;
// // get size and do a enough space check // // get size and do a enough space check

View File

@@ -32,7 +32,7 @@ namespace LibCmo::CK2 {
this->m_Parser.m_Status = CKStateChunkStatus::WRITE; this->m_Parser.m_Status = CKStateChunkStatus::WRITE;
} }
void CKStateChunk::StopWrite(void) { void CKStateChunk::StopWrite() {
if (this->m_Parser.m_Status != CKStateChunkStatus::WRITE) return; if (this->m_Parser.m_Status != CKStateChunkStatus::WRITE) return;
// update buffer size // update buffer size

View File

@@ -157,7 +157,7 @@ namespace LibCmo::CK2::ObjImpls {
// read matrix // read matrix
// reset // reset
m_WorldMatrix.ResetToIdentity(); m_WorldMatrix.SetIdentity();
// force read as vector3 // force read as vector3
chunk->ReadStruct(reinterpret_cast<VxMath::VxVector3*>(&m_WorldMatrix[0])); chunk->ReadStruct(reinterpret_cast<VxMath::VxVector3*>(&m_WorldMatrix[0]));
chunk->ReadStruct(reinterpret_cast<VxMath::VxVector3*>(&m_WorldMatrix[1])); chunk->ReadStruct(reinterpret_cast<VxMath::VxVector3*>(&m_WorldMatrix[1]));

View File

@@ -11,7 +11,7 @@ namespace LibCmo::CK2::ObjImpls {
virtual ~CK3dEntity(); virtual ~CK3dEntity();
YYCC_DEL_CLS_COPY_MOVE(CK3dEntity); YYCC_DEL_CLS_COPY_MOVE(CK3dEntity);
virtual CK_CLASSID GetClassID(void) override { virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_3DENTITY; return CK_CLASSID::CKCID_3DENTITY;
} }
@@ -48,6 +48,8 @@ namespace LibCmo::CK2::ObjImpls {
CKDWORD m_ZOrder; // replace the whole heavy CKSceneGraphNode CKDWORD m_ZOrder; // replace the whole heavy CKSceneGraphNode
VxMath::VX_MOVEABLE_FLAGS m_MoveableFlags; VxMath::VX_MOVEABLE_FLAGS m_MoveableFlags;
// MARK: This field is called m_EntityFlags in reverse project.
// I change this because I want to give it a more explicit name to make it is different with other flags.
CK_3DENTITY_FLAGS m_3dEntityFlags; CK_3DENTITY_FLAGS m_3dEntityFlags;
}; };

View File

@@ -13,7 +13,7 @@ namespace LibCmo::CK2::ObjImpls {
virtual ~CK3dObject() {} virtual ~CK3dObject() {}
YYCC_DEL_CLS_COPY_MOVE(CK3dObject); YYCC_DEL_CLS_COPY_MOVE(CK3dObject);
virtual CK_CLASSID GetClassID(void) override { virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_3DOBJECT; return CK_CLASSID::CKCID_3DOBJECT;
} }
// CK3dObject do not implement any load/save functions // CK3dObject do not implement any load/save functions

View File

@@ -11,7 +11,7 @@ namespace LibCmo::CK2::ObjImpls {
virtual ~CKBeObject(); virtual ~CKBeObject();
YYCC_DEL_CLS_COPY_MOVE(CKBeObject); YYCC_DEL_CLS_COPY_MOVE(CKBeObject);
virtual CK_CLASSID GetClassID(void) override { virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_BEOBJECT; return CK_CLASSID::CKCID_BEOBJECT;
} }

View File

@@ -0,0 +1,155 @@
#include "CKCamera.hpp"
#include "../CKStateChunk.hpp"
namespace LibCmo::CK2::ObjImpls {
// Convenient macro to mark this object is not UPTODATE.
#define REMOVE_UPTODATE_FLAG { \
CK_OBJECT_FLAGS obj_flags = GetObjectFlags(); \
YYCC::EnumHelper::Remove(obj_flags, CK_OBJECT_FLAGS::CK_OBJECT_UPTODATE); \
SetObjectFlags(obj_flags); \
}
CKCamera::CKCamera(CKContext* ctx, CK_ID ckid, CKSTRING name) :
CK3dEntity(ctx, ckid, name),
m_ProjectType(CK_CAMERA_PROJECTION::CK_PERSPECTIVEPROJECTION),
m_Fov(0.5f), m_OrthographicZoom(1.0f),
m_Width(4), m_Height(3),
m_FrontPlane(1.0f), m_BackPlane(4000.0f) {
REMOVE_UPTODATE_FLAG;
}
CKCamera::~CKCamera() {}
bool CKCamera::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) {
bool suc = CK3dEntity::Save(chunk, file, flags);
if (!suc) return false;
// Save main data
{
chunk->WriteIdentifier(CK_STATESAVEFLAGS_CAMERA::CK_STATESAVE_CAMERAONLY);
chunk->WriteStruct(m_ProjectType);
chunk->WriteStruct(m_Fov);
chunk->WriteStruct(m_OrthographicZoom);
// Build width and height compound.
CKDWORD widht_and_height = m_Width & 0x0000FFFFu;
widht_and_height |= (m_Height << 16) & 0xFFFF0000u;
chunk->WriteStruct(widht_and_height);
chunk->WriteStruct(m_FrontPlane);
chunk->WriteStruct(m_BackPlane);
}
chunk->SetClassId(CK_CLASSID::CKCID_CAMERA);
return true;
}
bool CKCamera::Load(CKStateChunk* chunk, CKFileVisitor* file) {
bool suc = CK3dEntity::Load(chunk, file);
if (!suc) return false;
// MARK: Drop the support for very old file format.
if (chunk->GetDataVersion() < CK_STATECHUNK_DATAVERSION::CHUNK_MAJORCHANGE_VERSION) {
return false;
}
// Read main data
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_CAMERA::CK_STATESAVE_CAMERAONLY)) {
chunk->ReadStruct(m_ProjectType);
chunk->ReadStruct(m_Fov);
chunk->ReadStruct(m_OrthographicZoom);
// Width and Height is stored in one DWORD
// Higher WORD is height and lower WORD is width.
// HIGH >>> height (2 bytes), width (2 bytes) <<< LOW
CKDWORD widht_and_height;
chunk->ReadStruct(widht_and_height);
m_Width = widht_and_height & 0x0000FFFFu;
m_Height = (widht_and_height & 0xFFFF0000u) >> 16;
chunk->ReadStruct(m_FrontPlane);
chunk->ReadStruct(m_BackPlane);
}
REMOVE_UPTODATE_FLAG;
return true;
}
#pragma region Class Operations
CK_CAMERA_PROJECTION CKCamera::GetProjectionType() const {
return m_ProjectType;
}
void CKCamera::SetProjectionType(CK_CAMERA_PROJECTION proj) {
m_ProjectType = proj;
REMOVE_UPTODATE_FLAG;
}
CKFLOAT CKCamera::GetOrthographicZoom() const {
return m_OrthographicZoom;
}
void CKCamera::SetOrthographicZoom(CKFLOAT zoom) {
m_OrthographicZoom = zoom;
REMOVE_UPTODATE_FLAG;
}
CKFLOAT CKCamera::GetFrontPlane() const {
return m_FrontPlane;
}
CKFLOAT CKCamera::GetBackPlane() const {
return m_BackPlane;
}
CKFLOAT CKCamera::GetFov() const {
return m_Fov;
}
void CKCamera::SetFrontPlane(CKFLOAT front) {
m_FrontPlane = front;
REMOVE_UPTODATE_FLAG;
}
void CKCamera::SetBackPlane(CKFLOAT back) {
m_BackPlane = back;
REMOVE_UPTODATE_FLAG;
}
void CKCamera::SetFov(CKFLOAT fov) {
m_Fov = fov;
REMOVE_UPTODATE_FLAG;
}
void CKCamera::GetAspectRatio(CKDWORD& width, CKDWORD& height) const {
width = m_Width;
height = m_Height;
}
void CKCamera::SetAspectRatio(CKDWORD width, CKDWORD height) {
m_Width = width;
m_Height = height;
REMOVE_UPTODATE_FLAG;
}
void CKCamera::ComputeProjectionMatrix(VxMath::VxMatrix& mat) const {
CKFLOAT aspect = static_cast<CKFLOAT>(m_Width) / m_Height;
if (m_ProjectType == CK_CAMERA_PROJECTION::CK_PERSPECTIVEPROJECTION) {
mat.Perspective(m_Fov, aspect, m_FrontPlane, m_BackPlane);
} else {
mat.Orthographic(m_OrthographicZoom, aspect, m_FrontPlane, m_BackPlane);
}
}
//void CKCamera::ResetRoll() {}
//void CKCamera::Roll(CKFLOAT angle) {}
CK3dEntity* CKCamera::GetTarget() const {
// Not supported, return nullptr anyway.
return nullptr;
}
void CKCamera::SetTarget(CK3dEntity* target) {
// Do nothing because no support.
}
#pragma endregion
// Undef convenient macro
#undef REMOVE_UPTODATE_FLAG
}

View File

@@ -0,0 +1,58 @@
#pragma once
#include "../../VTInternal.hpp"
#include "CK3dEntity.hpp"
namespace LibCmo::CK2::ObjImpls {
class CKCamera : public CK3dEntity {
public:
CKCamera(CKContext* ctx, CK_ID ckid, CKSTRING name);
virtual ~CKCamera();
YYCC_DEL_CLS_COPY_MOVE(CKCamera);
virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_CAMERA;
}
// 2 RW funcions
virtual bool Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) override;
virtual bool Load(CKStateChunk* chunk, CKFileVisitor* file) override;
CK_CAMERA_PROJECTION GetProjectionType() const;
void SetProjectionType(CK_CAMERA_PROJECTION proj);
CKFLOAT GetOrthographicZoom() const;
void SetOrthographicZoom(CKFLOAT zoom);
CKFLOAT GetFrontPlane() const;
CKFLOAT GetBackPlane() const;
CKFLOAT GetFov() const;
void SetFrontPlane(CKFLOAT front);
void SetBackPlane(CKFLOAT back);
void SetFov(CKFLOAT fov);
void GetAspectRatio(CKDWORD& width, CKDWORD& height) const;
void SetAspectRatio(CKDWORD width, CKDWORD height);
void ComputeProjectionMatrix(VxMath::VxMatrix& mat) const;
// TODO: Finish CKCamera roll feature because it now involve some functions which is not implemented in CK3dEntity.
// Roll Angle
//void ResetRoll();
//void Roll(CKFLOAT angle);
// Target access
virtual CK3dEntity* GetTarget() const;
virtual void SetTarget(CK3dEntity* target);
protected:
CKFLOAT m_Fov;
CKFLOAT m_FrontPlane, m_BackPlane;
CK_CAMERA_PROJECTION m_ProjectType;
CKFLOAT m_OrthographicZoom;
CKDWORD m_Width, m_Height;
};
}

View File

@@ -11,7 +11,7 @@ namespace LibCmo::CK2::ObjImpls {
virtual ~CKGroup(); virtual ~CKGroup();
YYCC_DEL_CLS_COPY_MOVE(CKGroup); YYCC_DEL_CLS_COPY_MOVE(CKGroup);
virtual CK_CLASSID GetClassID(void) override { virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_GROUP; return CK_CLASSID::CKCID_GROUP;
} }

View File

@@ -0,0 +1,232 @@
#include "CKLight.hpp"
#include "../CKStateChunk.hpp"
#include <numbers>
namespace LibCmo::CK2::ObjImpls {
CKLight::CKLight(CKContext* ctx, CK_ID ckid, CKSTRING name) :
CK3dEntity(ctx, ckid, name),
m_LightData(), m_LightFlags(LightFlags::Active), m_LightPower(1.0f) {
// Setup light data
m_LightData.m_Type = VxMath::VXLIGHT_TYPE::VX_LIGHTPOINT;
m_LightData.m_Diffuse = VxMath::VxColor(1.0f, 1.0f, 1.0f);
m_LightData.m_Specular = VxMath::VxColor(0);
m_LightData.m_Ambient = VxMath::VxColor(0.0f, 0.0f, 0.0f);
m_LightData.m_Range = 5000.0f;
m_LightData.m_Falloff = 1.0f;
m_LightData.m_Attenuation0 = 1.0f;
m_LightData.m_Attenuation1 = 0.0f;
m_LightData.m_Attenuation2 = 0.0f;
m_LightData.m_InnerSpotCone = 40.0f / 180.0f * std::numbers::pi_v<float>; // MARK: Original value is 0.69813174f. Perhaps 40 deg in rad.
m_LightData.m_OuterSpotCone = 45.0f / 180.0f * std::numbers::pi_v<float>; // MARK: Original value is 0.78539819f. Perhaps 45 deg in rad.
}
CKLight::~CKLight() {}
bool CKLight::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) {
bool suc = CK3dEntity::Save(chunk, file, flags);
if (!suc) return false;
// Save main data
{
chunk->WriteIdentifier(CK_STATESAVEFLAGS_LIGHT::CK_STATESAVE_LIGHTDATA);
// Combine light type and flags data.
CKDWORD light_type_and_flags = static_cast<CKDWORD>(m_LightFlags) & 0xFFFFFF00u;
light_type_and_flags |= static_cast<CKDWORD>(m_LightData.m_Type) & 0xFFu;
chunk->WriteStruct(light_type_and_flags);
// Save diffuse color with constant 1.0 alpha factor.
chunk->WriteStruct(m_LightData.m_Diffuse.ToARGB() | 0xFF000000u);
chunk->WriteStruct(m_LightData.m_Attenuation0);
chunk->WriteStruct(m_LightData.m_Attenuation1);
chunk->WriteStruct(m_LightData.m_Attenuation2);
chunk->WriteStruct(m_LightData.m_Range);
if (m_LightData.m_Type == VxMath::VXLIGHT_TYPE::VX_LIGHTSPOT) {
chunk->WriteStruct(m_LightData.m_OuterSpotCone);
chunk->WriteStruct(m_LightData.m_InnerSpotCone);
chunk->WriteStruct(m_LightData.m_Falloff);
}
}
// Save light power
if (m_LightPower != 1.0f) {
chunk->WriteIdentifier(CK_STATESAVEFLAGS_LIGHT::CK_STATESAVE_LIGHTDATA2);
chunk->WriteStruct(m_LightPower);
}
chunk->SetClassId(CK_CLASSID::CKCID_LIGHT);
return true;
}
bool CKLight::Load(CKStateChunk* chunk, CKFileVisitor* file) {
bool suc = CK3dEntity::Load(chunk, file);
if (!suc) return false;
// MARK: I drop the read process for too low version.
// return false anyway.
if (chunk->GetDataVersion() < CK_STATECHUNK_DATAVERSION::CHUNK_MAJORCHANGE_VERSION) {
return false;
}
// Read main data
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_LIGHT::CK_STATESAVE_LIGHTDATA)) {
// Read a DWORD storing light type and flags
// Because the lowest byte in light flags always is 0x00,
// so Virtools use it to store light type.
// After removing light type component, the rest of data is light flags.
// (do not need any SHIFT! It's okey that just set the lowest byte to zero.)
CKDWORD light_type_and_flags;
chunk->ReadStruct(light_type_and_flags);
m_LightData.m_Type = static_cast<VxMath::VXLIGHT_TYPE>(light_type_and_flags & 0xFFu);
m_LightFlags = static_cast<LightFlags>(light_type_and_flags & 0xFFFFFF00u);
CKDWORD dword_diffuse;
chunk->ReadStruct(dword_diffuse);
m_LightData.m_Diffuse = VxMath::VxColor(dword_diffuse);
chunk->ReadStruct(m_LightData.m_Attenuation0);
chunk->ReadStruct(m_LightData.m_Attenuation1);
chunk->ReadStruct(m_LightData.m_Attenuation2);
chunk->ReadStruct(m_LightData.m_Range);
if (m_LightData.m_Type == VxMath::VXLIGHT_TYPE::VX_LIGHTSPOT) {
chunk->ReadStruct(m_LightData.m_OuterSpotCone);
chunk->ReadStruct(m_LightData.m_InnerSpotCone);
chunk->ReadStruct(m_LightData.m_Falloff);
}
}
// Read light power
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_LIGHT::CK_STATESAVE_LIGHTDATA2)) {
chunk->ReadStruct(m_LightPower);
} else {
m_LightPower = 1.0f;
}
// Correct light type to prevent accident out of range value.
switch (m_LightData.m_Type) {
case VxMath::VXLIGHT_TYPE::VX_LIGHTPOINT:
case VxMath::VXLIGHT_TYPE::VX_LIGHTSPOT:
case VxMath::VXLIGHT_TYPE::VX_LIGHTDIREC:
case VxMath::VXLIGHT_TYPE::VX_LIGHTPARA:
// do nothing
break;
default:
// reset it to point
m_LightData.m_Type = VxMath::VXLIGHT_TYPE::VX_LIGHTPOINT;
break;
}
return true;
}
#pragma region Class Operations
VxMath::VXLIGHT_TYPE CKLight::GetType() const {
return m_LightData.m_Type;
}
void CKLight::SetType(VxMath::VXLIGHT_TYPE light_type) {
m_LightData.m_Type = light_type;
}
const VxMath::VxColor& CKLight::GetColor() const {
return m_LightData.m_Diffuse;
}
void CKLight::SetColor(const VxMath::VxColor& c) {
m_LightData.m_Diffuse = c;
}
CKFLOAT CKLight::GetConstantAttenuation() const {
return m_LightData.m_Attenuation0;
}
CKFLOAT CKLight::GetLinearAttenuation() const {
return m_LightData.m_Attenuation1;
}
CKFLOAT CKLight::GetQuadraticAttenuation() const {
return m_LightData.m_Attenuation2;
}
void CKLight::SetConstantAttenuation(CKFLOAT value) {
m_LightData.m_Attenuation0 = value;
}
void CKLight::SetLinearAttenuation(CKFLOAT value) {
m_LightData.m_Attenuation1 = value;
}
void CKLight::SetQuadraticAttenuation(CKFLOAT value) {
m_LightData.m_Attenuation2 = value;
}
CKFLOAT CKLight::GetRange() const {
return m_LightData.m_Range;
}
void CKLight::SetRange(CKFLOAT value) {
m_LightData.m_Range = value;
}
CKFLOAT CKLight::GetHotSpot() const {
return m_LightData.m_InnerSpotCone;
}
CKFLOAT CKLight::GetFalloff() const {
return m_LightData.m_OuterSpotCone;
}
CKFLOAT CKLight::GetFalloffShape() const {
return m_LightData.m_Falloff;
}
void CKLight::SetHotSpot(CKFLOAT value) {
m_LightData.m_InnerSpotCone = value;
}
void CKLight::SetFalloff(CKFLOAT value) {
m_LightData.m_OuterSpotCone = value;
}
void CKLight::SetFalloffShape(CKFLOAT value) {
m_LightData.m_Falloff = value;
}
bool CKLight::GetActivity() const {
return YYCC::EnumHelper::Has(m_LightFlags, LightFlags::Active);
}
void CKLight::Active(bool active) {
if (active) {
YYCC::EnumHelper::Add(m_LightFlags, LightFlags::Active);
} else {
YYCC::EnumHelper::Remove(m_LightFlags, LightFlags::Active);
}
}
bool CKLight::GetSpecularFlag() const {
return YYCC::EnumHelper::Has(m_LightFlags, LightFlags::Specular);
}
void CKLight::SetSpecularFlag(bool specular) {
if (specular) {
YYCC::EnumHelper::Add(m_LightFlags, LightFlags::Specular);
} else {
YYCC::EnumHelper::Remove(m_LightFlags, LightFlags::Specular);
}
}
CK3dEntity* CKLight::GetTarget() const {
// Normal light do not support target.
// So it always return nullptr.
return nullptr;
}
void CKLight::SetTarget(CK3dEntity* target) {
// Normal light do not support target.
// So, do nothing.
}
CKFLOAT CKLight::GetLightPower() const {
return m_LightPower;
}
void CKLight::SetLightPower(CKFLOAT power) {
m_LightPower = power;
}
#pragma endregion
}

View File

@@ -0,0 +1,75 @@
#pragma once
#include "../../VTInternal.hpp"
#include "CK3dEntity.hpp"
namespace LibCmo::CK2::ObjImpls {
class CKLight : public CK3dEntity {
public:
CKLight(CKContext* ctx, CK_ID ckid, CKSTRING name);
virtual ~CKLight();
YYCC_DEL_CLS_COPY_MOVE(CKLight);
virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_LIGHT;
}
// 2 RW funcions
virtual bool Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) override;
virtual bool Load(CKStateChunk* chunk, CKFileVisitor* file) override;
// Type
VxMath::VXLIGHT_TYPE GetType() const;
void SetType(VxMath::VXLIGHT_TYPE light_type);
const VxMath::VxColor& GetColor() const;
void SetColor(const VxMath::VxColor& c);
CKFLOAT GetConstantAttenuation() const;
CKFLOAT GetLinearAttenuation() const;
CKFLOAT GetQuadraticAttenuation() const;
void SetConstantAttenuation(CKFLOAT value);
void SetLinearAttenuation(CKFLOAT value);
void SetQuadraticAttenuation(CKFLOAT value);
// Range
CKFLOAT GetRange() const;
void SetRange(CKFLOAT value);
// Spotlight options
CKFLOAT GetHotSpot() const;
CKFLOAT GetFalloff() const;
CKFLOAT GetFalloffShape() const;
void SetHotSpot(CKFLOAT value);
void SetFalloff(CKFLOAT value);
void SetFalloffShape(CKFLOAT value);
// Activity options
bool GetActivity() const;
void Active(bool active);
bool GetSpecularFlag() const;
void SetSpecularFlag(bool specular);
// Target access
virtual CK3dEntity* GetTarget() const;
virtual void SetTarget(CK3dEntity* target);
CKFLOAT GetLightPower() const;
void SetLightPower(CKFLOAT power = 1.0f);
protected:
enum class LightFlags : CKDWORD {
None = 0,
Active = 0x100u, /**< if set, this light is active. */
Specular = 0x200u, /**< if set, this light has specular flag. */
};
CKLightData m_LightData;
// MARK: This variable is called in m_Flags in reverse code.
LightFlags m_LightFlags;
CKFLOAT m_LightPower;
};
}

View File

@@ -12,7 +12,7 @@ namespace LibCmo::CK2::ObjImpls {
virtual ~CKMaterial(); virtual ~CKMaterial();
YYCC_DEL_CLS_COPY_MOVE(CKMaterial); YYCC_DEL_CLS_COPY_MOVE(CKMaterial);
virtual CK_CLASSID GetClassID(void) override { virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_MATERIAL; return CK_CLASSID::CKCID_MATERIAL;
} }

View File

@@ -573,7 +573,7 @@ namespace LibCmo::CK2::ObjImpls {
// get diff by distance // get diff by distance
VxMath::VxVector3 diff = m_VertexNormal[vid] - generated[vid]; VxMath::VxVector3 diff = m_VertexNormal[vid] - generated[vid];
// abs the diff and add into accumulated diff // abs the diff and add into accumulated diff
VxMath::NSVxVector::Abs(diff); VxMath::NSVxVector::Absolute(diff);
accnml += diff; accnml += diff;
} }

View File

@@ -21,7 +21,7 @@ namespace LibCmo::CK2::ObjImpls {
virtual ~CKMesh(); virtual ~CKMesh();
YYCC_DEL_CLS_COPY_MOVE(CKMesh); YYCC_DEL_CLS_COPY_MOVE(CKMesh);
virtual CK_CLASSID GetClassID(void) override { virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_MESH; return CK_CLASSID::CKCID_MESH;
} }

View File

@@ -16,16 +16,16 @@ namespace LibCmo::CK2::ObjImpls {
#pragma region Non-virtual Functions #pragma region Non-virtual Functions
CK_ID CKObject::GetID(void) const { CK_ID CKObject::GetID() const {
return m_ID; return m_ID;
} }
CKSTRING CKObject::GetName(void) const { CKSTRING CKObject::GetName() const {
return XContainer::NSXString::ToCKSTRING(m_Name); return XContainer::NSXString::ToCKSTRING(m_Name);
} }
void CKObject::SetName(CKSTRING u8_name) { void CKObject::SetName(CKSTRING u8_name) {
XContainer::NSXString::FromCKSTRING(m_Name, u8_name); XContainer::NSXString::FromCKSTRING(m_Name, u8_name);
} }
CK_OBJECT_FLAGS CKObject::GetObjectFlags(void) const { CK_OBJECT_FLAGS CKObject::GetObjectFlags() const {
return m_ObjectFlags; return m_ObjectFlags;
} }
void CKObject::SetObjectFlags(CK_OBJECT_FLAGS flags) { void CKObject::SetObjectFlags(CK_OBJECT_FLAGS flags) {

View File

@@ -42,15 +42,15 @@ namespace LibCmo::CK2::ObjImpls {
virtual ~CKObject(); virtual ~CKObject();
YYCC_DEL_CLS_COPY_MOVE(CKObject); YYCC_DEL_CLS_COPY_MOVE(CKObject);
CK_ID GetID(void) const; CK_ID GetID() const;
CKSTRING GetName(void) const; CKSTRING GetName() const;
void SetName(CKSTRING u8_name); void SetName(CKSTRING u8_name);
CK_OBJECT_FLAGS GetObjectFlags(void) const; CK_OBJECT_FLAGS GetObjectFlags() const;
void SetObjectFlags(CK_OBJECT_FLAGS flags); void SetObjectFlags(CK_OBJECT_FLAGS flags);
bool IsToBeDeleted() const; bool IsToBeDeleted() const;
CKContext* GetCKContext() const; CKContext* GetCKContext() const;
virtual CK_CLASSID GetClassID(void) { virtual CK_CLASSID GetClassID() {
return CK_CLASSID::CKCID_OBJECT; return CK_CLASSID::CKCID_OBJECT;
} }

View File

@@ -13,7 +13,7 @@ namespace LibCmo::CK2::ObjImpls {
virtual ~CKRenderObject() {} virtual ~CKRenderObject() {}
YYCC_DEL_CLS_COPY_MOVE(CKRenderObject); YYCC_DEL_CLS_COPY_MOVE(CKRenderObject);
virtual CK_CLASSID GetClassID(void) override { virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_RENDEROBJECT; return CK_CLASSID::CKCID_RENDEROBJECT;
} }

View File

@@ -13,7 +13,7 @@ namespace LibCmo::CK2::ObjImpls {
virtual ~CKSceneObject() {} virtual ~CKSceneObject() {}
YYCC_DEL_CLS_COPY_MOVE(CKSceneObject); YYCC_DEL_CLS_COPY_MOVE(CKSceneObject);
virtual CK_CLASSID GetClassID(void) override { virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_SCENEOBJECT; return CK_CLASSID::CKCID_SCENEOBJECT;
} }
// CKSceneObject do not override any RW functions. // CKSceneObject do not override any RW functions.

View File

@@ -0,0 +1,91 @@
#include "CKTargetCamera.hpp"
#include "../CKStateChunk.hpp"
#include "../CKContext.hpp"
namespace LibCmo::CK2::ObjImpls {
// MARK: THIS CODE IS BARELY FULL COPY OF CKTargetLight.
// Please sync them if you modify one of them!
CKTargetCamera::CKTargetCamera(CKContext* ctx, CK_ID ckid, CKSTRING name) :
CKCamera(ctx, ckid, name), m_Target3dEntity(0) {}
CKTargetCamera::~CKTargetCamera() {}
void CKTargetCamera::PreDelete() {
// Remove associated target
SetTarget(nullptr);
}
void CKTargetCamera::CheckPostDeletion() {
CKCamera::CheckPostDeletion();
// Remove target if is not existing.
CKObject* target = m_Context->GetObject(m_Target3dEntity);
if (target == nullptr) {
m_Target3dEntity = 0;
}
}
bool CKTargetCamera::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) {
bool suc = CKCamera::Save(chunk, file, flags);
if (!suc) return false;
// Save target
{
chunk->WriteIdentifier(CK_STATESAVEFLAGS_CAMERA::CK_STATESAVE_TCAMERATARGET);
CKObject* target = m_Context->GetObject(m_Target3dEntity);
chunk->WriteObjectPointer(target);
}
chunk->SetClassId(CK_CLASSID::CKCID_TARGETCAMERA);
return true;
}
bool CKTargetCamera::Load(CKStateChunk* chunk, CKFileVisitor* file) {
bool suc = CKCamera::Load(chunk, file);
if (!suc) return false;
// Read target
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_CAMERA::CK_STATESAVE_TCAMERATARGET)) {
chunk->ReadObjectID(m_Target3dEntity);
}
return true;
}
CK3dEntity* CKTargetCamera::GetTarget() const {
return static_cast<CK3dEntity*>(m_Context->GetObject(m_Target3dEntity));
}
void CKTargetCamera::SetTarget(CK3dEntity* target) {
// The target can not be self.
if (target == this) return;
// First remove current target
CK3dEntity* old_target = static_cast<CK3dEntity*>(m_Context->GetObject(m_Target3dEntity));
if (old_target != nullptr) {
CK_3DENTITY_FLAGS old_target_flags = old_target->GetEntityFlags();
YYCC::EnumHelper::Remove(old_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_TARGETCAMERA);
YYCC::EnumHelper::Add(old_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_FRAME);
old_target->SetEntityFlags(old_target_flags);
}
// Then add specified target
if (target != nullptr) {
CK_3DENTITY_FLAGS new_target_flags = target->GetEntityFlags();
YYCC::EnumHelper::Add(new_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_TARGETCAMERA);
YYCC::EnumHelper::Remove(new_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_FRAME);
target->SetEntityFlags(new_target_flags);
}
// Get CK_ID of new target
CK_ID target_id = 0;
if (target != nullptr)
target_id = target->GetID();
// Assign target id.
m_Target3dEntity = target_id;
}
}

View File

@@ -0,0 +1,33 @@
#pragma once
#include "../../VTInternal.hpp"
#include "CKCamera.hpp"
namespace LibCmo::CK2::ObjImpls {
class CKTargetCamera : public CKCamera {
public:
CKTargetCamera(CKContext* ctx, CK_ID ckid, CKSTRING name);
virtual ~CKTargetCamera();
YYCC_DEL_CLS_COPY_MOVE(CKTargetCamera);
virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_TARGETCAMERA;
}
virtual void PreDelete() override;
virtual void CheckPostDeletion() override;
// 2 RW funcions
virtual bool Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) override;
virtual bool Load(CKStateChunk* chunk, CKFileVisitor* file) override;
virtual CK3dEntity* GetTarget() const override;
virtual void SetTarget(CK3dEntity* target) override;
protected:
CK_ID m_Target3dEntity;
};
}

View File

@@ -0,0 +1,95 @@
#include "CKTargetLight.hpp"
#include "../CKStateChunk.hpp"
#include "../CKContext.hpp"
namespace LibCmo::CK2::ObjImpls {
// MARK: THIS CODE IS BARELY FULL COPY OF CKTargetCamera.
// Please sync them if you modify one of them!
CKTargetLight::CKTargetLight(CKContext* ctx, CK_ID ckid, CKSTRING name) :
CKLight(ctx, ckid, name), m_Target3dEntity(0) {}
CKTargetLight::~CKTargetLight() {}
void CKTargetLight::PreDelete() {
// MARK: In original code, there is no such override.
// Following statement is written in a function called "vector deleting destructor".
// Idk what it is. There is no resetting target code in its dtor and elsewhere.
// I think this is crucial, so I add this overload as my understandings.
// Remove associated target
SetTarget(nullptr);
}
void CKTargetLight::CheckPostDeletion() {
CKLight::CheckPostDeletion();
// Remove target if is not existing.
CKObject* target = m_Context->GetObject(m_Target3dEntity);
if (target == nullptr) {
m_Target3dEntity = 0;
}
}
bool CKTargetLight::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) {
bool suc = CKLight::Save(chunk, file, flags);
if (!suc) return false;
// Save target
{
chunk->WriteIdentifier(CK_STATESAVEFLAGS_LIGHT::CK_STATESAVE_TLIGHTTARGET);
CKObject* target = m_Context->GetObject(m_Target3dEntity);
chunk->WriteObjectPointer(target);
}
chunk->SetClassId(CK_CLASSID::CKCID_TARGETLIGHT);
return true;
}
bool CKTargetLight::Load(CKStateChunk* chunk, CKFileVisitor* file) {
bool suc = CKLight::Load(chunk, file);
if (!suc) return false;
// Read target
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_LIGHT::CK_STATESAVE_TLIGHTTARGET)) {
chunk->ReadObjectID(m_Target3dEntity);
}
return true;
}
CK3dEntity* CKTargetLight::GetTarget() const {
return static_cast<CK3dEntity*>(m_Context->GetObject(m_Target3dEntity));
}
void CKTargetLight::SetTarget(CK3dEntity* target) {
// The target can not be self.
if (target == this) return;
// First remove current target
CK3dEntity* old_target = static_cast<CK3dEntity*>(m_Context->GetObject(m_Target3dEntity));
if (old_target != nullptr) {
CK_3DENTITY_FLAGS old_target_flags = old_target->GetEntityFlags();
YYCC::EnumHelper::Remove(old_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_TARGETLIGHT);
YYCC::EnumHelper::Add(old_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_FRAME);
old_target->SetEntityFlags(old_target_flags);
}
// Then add specified target
if (target != nullptr) {
CK_3DENTITY_FLAGS new_target_flags = target->GetEntityFlags();
YYCC::EnumHelper::Add(new_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_TARGETLIGHT);
YYCC::EnumHelper::Remove(new_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_FRAME);
target->SetEntityFlags(new_target_flags);
}
// Get CK_ID of new target
CK_ID target_id = 0;
if (target != nullptr)
target_id = target->GetID();
// Assign target id.
m_Target3dEntity = target_id;
}
}

View File

@@ -0,0 +1,33 @@
#pragma once
#include "../../VTInternal.hpp"
#include "CKLight.hpp"
namespace LibCmo::CK2::ObjImpls {
class CKTargetLight : public CKLight {
public:
CKTargetLight(CKContext* ctx, CK_ID ckid, CKSTRING name);
virtual ~CKTargetLight();
YYCC_DEL_CLS_COPY_MOVE(CKTargetLight);
virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_TARGETLIGHT;
}
virtual void PreDelete() override;
virtual void CheckPostDeletion() override;
// 2 RW funcions
virtual bool Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) override;
virtual bool Load(CKStateChunk* chunk, CKFileVisitor* file) override;
virtual CK3dEntity* GetTarget() const override;
virtual void SetTarget(CK3dEntity* target) override;
protected:
CK_ID m_Target3dEntity;
};
}

View File

@@ -12,7 +12,7 @@ namespace LibCmo::CK2::ObjImpls {
virtual ~CKTexture(); virtual ~CKTexture();
YYCC_DEL_CLS_COPY_MOVE(CKTexture); YYCC_DEL_CLS_COPY_MOVE(CKTexture);
virtual CK_CLASSID GetClassID(void) override { virtual CK_CLASSID GetClassID() override {
return CK_CLASSID::CKCID_TEXTURE; return CK_CLASSID::CKCID_TEXTURE;
} }

View File

@@ -4,9 +4,9 @@
* \file * \file
* The top header file for LibCom self development. * The top header file for LibCom self development.
* Every C++ header or source file located in this project should include this first * Every C++ header or source file located in this project should include this first
* except the headers including this file. * except the headers included in this file.
* The header files included by this header should be carefully managed, * The header files included by this header should be carefully managed,
* to make sure there are no include loop and each header files can works correctly. * to make sure there are no include loop and each header files can work correctly.
* *
* This header should only be used as internal header file. * This header should only be used as internal header file.
* It only contains all necessary stuff used by this project self. * It only contains all necessary stuff used by this project self.
@@ -17,18 +17,16 @@
* So they will use native type, not CK type for declaration and implementation. * So they will use native type, not CK type for declaration and implementation.
* Take VTEncoding.hpp for example, All string used in it is \c std::u8string, not LibCmo::XContainer::XString. * Take VTEncoding.hpp for example, All string used in it is \c std::u8string, not LibCmo::XContainer::XString.
* The file starts with \c CK, \c Vx, and \c X is a part of Virtools SDK. * The file starts with \c CK, \c Vx, and \c X is a part of Virtools SDK.
* They should use Virtools type anywhere, except that Virtools type can not fulfill their requirement. * They should use Virtools type anywhere, except that Virtools type can not fulfill their requirements.
*/ */
// The version info header of LibCmo
#include "VTVersion.hpp"
// The base header of LibCmo. // The base header of LibCmo.
// It provides various convenient stuff, for example: // It provides various convenient stuff, for example:
// - General LibCmo specific custom exception. // - General LibCmo specific custom exception.
// - Enum Helper for convenient C++ enum class type logic operations. // - Enum Helper for convenient C++ enum class type logic operations.
#include "VTUtils.hpp" #include "VTUtils.hpp"
// Platform independent encoding system.
// Use native Win32 functions in Windows,
// or Iconv in non-Windows to provide encoding convertion services.
#include "VTEncoding.hpp"
// Include CK2 types first. // Include CK2 types first.
// Because it also include some types or structs used by other module. // Because it also include some types or structs used by other module.
@@ -54,6 +52,3 @@
// Last, load some custom struct used in program. // Last, load some custom struct used in program.
#include "CK2/CKDefines.hpp" #include "CK2/CKDefines.hpp"

View File

@@ -0,0 +1,7 @@
#include "VTUtils.hpp"
// Check YYCC library version
#include <yycc/macro/version_cmp.hpp>
#if YYCC_VERCMP_NE(YYCC_VER_MAJOR, YYCC_VER_MINOR, YYCC_VER_PATCH, 2, 0, 0)
#error "YYCC library version is not matched with our expected version. Please check your library configuration."
#endif

View File

@@ -5,11 +5,8 @@
#error "You must define ONE of LIBCMO_BUILD_DEBUG and LIBCMO_BUILD_RELEASE to indicate build type!" #error "You must define ONE of LIBCMO_BUILD_DEBUG and LIBCMO_BUILD_RELEASE to indicate build type!"
#endif #endif
// Include YYCC helper library and check its version // Include YYCC library core header for all headers
#include <YYCCommonplace.hpp> #include <yycc.hpp>
#if YYCC_VERCMP_NE(YYCC_VER_MAJOR, YYCC_VER_MINOR, YYCC_VER_PATCH, 1, 3, 0)
#error "YYCC library version is not matched with our expected version. Please check your library configuration."
#endif
// Header for this namespace implementation // Header for this namespace implementation
#include <string> #include <string>

View File

@@ -0,0 +1,6 @@
#pragma once
#define LIBCMO_VER_MAJOR @PROJECT_VERSION_MAJOR@
#define LIBCMO_VER_MINOR @PROJECT_VERSION_MINOR@
#define LIBCMO_VER_PATCH @PROJECT_VERSION_PATCH@
#define LIBCMO_VER_STR "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@"

View File

@@ -45,6 +45,21 @@ namespace LibCmo::VxMath {
_4_ARGB8888_CLUT = 31, /**< 4 bits indexed CLUT (ARGB) */ _4_ARGB8888_CLUT = 31, /**< 4 bits indexed CLUT (ARGB) */
}; };
/**
{filename:VXLIGHT_TYPE}
Summary: Light type.
Remarks:
+ Used by CKLight::SetType to specify the type of a light.
See also: CKLight::SetType,CKLight::GetType
*/
enum class VXLIGHT_TYPE : CKDWORD {
VX_LIGHTPOINT = 1UL, /**< The Light is a point of light */
VX_LIGHTSPOT = 2UL, /**< The light is a spotlight */
VX_LIGHTDIREC = 3UL, /**< The light is directional light : Lights comes from an infinite point so only direction of light can be given */
VX_LIGHTPARA = 4UL, /**< Obsolete, do not use */
};
/** /**
Summary: Blend Mode Flags Summary: Blend Mode Flags
Remarks: Remarks:

View File

@@ -134,39 +134,4 @@ namespace LibCmo::VxMath {
#pragma endregion #pragma endregion
#pragma region Patched
namespace NSVxVector {
float DotProduct(const VxVector2& lhs, const VxVector2& rhs) {
return lhs * rhs;
}
float DotProduct(const VxVector3& lhs, const VxVector3& rhs) {
return lhs * rhs;
}
float DotProduct(const VxVector4& lhs, const VxVector4& rhs) {
return lhs * rhs;
}
VxVector3 CrossProduct(const VxVector3& lhs, const VxVector3& rhs) {
return VxVector3(
lhs.y * rhs.z - lhs.z * rhs.y,
lhs.z * rhs.x - lhs.x * rhs.z,
lhs.x * rhs.y - lhs.y * rhs.x
);
}
void Abs(VxVector3& lhs) {
lhs.x = std::fabs(lhs.x);
lhs.y = std::fabs(lhs.y);
lhs.z = std::fabs(lhs.z);
}
}
#pragma endregion
} }

View File

@@ -95,56 +95,5 @@ namespace LibCmo::VxMath {
*/ */
void VxDoAlphaBlit(VxImageDescEx* dst_desc, const CKBYTE* AlphaValues); void VxDoAlphaBlit(VxImageDescEx* dst_desc, const CKBYTE* AlphaValues);
// ========== Patch Section ==========
/**
* @brief The patch namespace for VxVector-like classes
* @details This namespace provides VxVector-like classes member functions which presented in original Virtools SDK.
* These functions are put in public namespace in original Virtools SDK.
* We just organise them into an unique namespace.
*/
namespace NSVxVector {
/**
* @brief Dot product 2 2d vectors.
* @param[in] lhs The left side vector of dot product symbol.
* @param[in] rhs The right side vector of dot product symbol.
* @return The float pointing result of dot product.
*/
CKFLOAT DotProduct(const VxVector2& lhs, const VxVector2& rhs);
/**
* @brief Dot product 2 3d vectors.
* @param[in] lhs The left side vector of dot product symbol.
* @param[in] rhs The right side vector of dot product symbol.
* @return The float pointing result of dot product.
*/
CKFLOAT DotProduct(const VxVector3& lhs, const VxVector3& rhs);
/**
* @brief Dot product 2 4d vectors.
* @param[in] lhs The left side vector of dot product symbol.
* @param[in] rhs The right side vector of dot product symbol.
* @return The float pointing result of dot product.
*/
CKFLOAT DotProduct(const VxVector4& lhs, const VxVector4& rhs);
/**
* @brief Cross product 2 3d vectors.
* @param[in] lhs The left side vector of cross product symbol.
* @param[in] rhs The right side vector of cross product symbol.
* @return The 3d vector result of cross product.
*/
VxVector3 CrossProduct(const VxVector3& lhs, const VxVector3& rhs);
/**
* @brief Set all factor in vector to its absolute value.
* @param[in,out] lhs The vector for processing.
* @remarks This function is rarely used.
* Please note this function is not calculate the absolute value of vector.
*/
void Abs(VxVector3& lhs);
}
} }

View File

@@ -128,7 +128,7 @@ namespace LibCmo::VxMath {
this->m_bIsValid = true; this->m_bIsValid = true;
} }
VxMemoryMappedFile::~VxMemoryMappedFile(void) { VxMemoryMappedFile::~VxMemoryMappedFile() {
if (this->m_bIsValid) { if (this->m_bIsValid) {
// only success mapping need free // only success mapping need free
this->m_bIsValid = false; this->m_bIsValid = false;

Some files were not shown because too many files have changed in this diff Show More