Compare commits

35 Commits

Author SHA1 Message Date
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
305c0b1b65 doc: fix README 2024-11-08 15:17:45 +08:00
6f7202a86b feat: improve BMap bindings.
- Add IEquatable<T> interface for BMapSharp 2 abstract base classes to make they can be used in HashSet or Dictionary.
- Add corresponding testbench for this new added interface to make sure it works.
- Also add set and dict test for PyBMap although it has been proven works.
2024-11-08 14:58:50 +08:00
512729ed05 feat: improve PyBMap
- re-raise exception for run out of next() function to make end user know this is their fault, not PyBMap.
- write some primitive type getter setter for short code and less latent bugs.
- remove bmfile parameter in BMMeshTrans::Parse.
2024-11-07 20:56:16 +08:00
e2e7121c16 feat: update PyBMap and its testbench
- update PyBMap testbench according to BMapSharp testbench.
- use some wrapper function to fetch commonly used type in PyBMap to reduce line count.
- re-place some utils functions in PyBMap.
2024-11-07 17:28:11 +08:00
9dd46b88d9 dep: update stb.
- use a nasty way to update stb-image library (do not use new resize library, use moved depracted one. because idk how to program with new one. that lack doc).
2024-11-04 17:19:51 +08:00
7e7b21544d chore: update build script. 2024-11-04 14:58:53 +08:00
e72102496b fix: update YYCC dependency
- move EnumsHelper into YYCC because it is widely used.
- rename all calling to EnumsHelper due to this modification.
- add version checker in code to make sure that user use correct YYCC library to compile.
- modify some include syntax because the include directory layout changes of YYCC.
- update CMake script to resolve the bug that we can not export LibCmo (thanks doyaGu and BLumia).
2024-11-03 19:05:27 +08:00
73f1a1f829 fix: fix fatal layout issue about VxColor.
- fix wrong memory layout of VxColor.
2024-11-01 13:31:03 +08:00
33dc9a54be feat: finish BMapSharp
- basically finish BMapSharp bindings however done test does not cover all scenarios.
2024-11-01 11:13:05 +08:00
6eb95ddd1f feat: update BMapSharp
- finish BMMesh bindings.
- finish a half of BMMeshTrans bindings.
- use getGenericValue and setGenericValue for most bindings.
2024-11-01 10:48:45 +08:00
e8fedc8bff feat: update BMapSharp
- update virtools type defines in BMapSharp. expand its ctor for convenient usage.
- finish BMMaterial bindings.
- create a generic value getter setter for convenient calling.
- fix codegen error of BMapSharp (accident fallthrough for CKBYTE type and wrong marshal type for enum type).
2024-10-31 17:15:06 +08:00
74268d4ad4 feat: update BMapSharp
- finish BMTexture bindings and quater of BMMaterial.
- fix compile manual.
2024-10-30 15:41:17 +08:00
f7644319f0 doc: update build manual 2024-10-29 17:44:55 +08:00
73cda9f905 feat: update BMapSharp
- add struct assigner and iterator but still has bugs (struct padding issue)
- add function bindings for BM3dObject and BMGroup.
- add basic ctor and dtor for BMMeshTrans.
2024-10-29 15:12:00 +08:00
4d04b38d52 feat: continue improving BMapSharp.
- add BMFileWriter in BMapSharp.
2024-10-27 11:41:49 +08:00
623334f863 feat: update BMapSharp.
- update the function calling in BMapSharp.BMFileReader. (hope JIT can optimize my bad code served for beauty)
- remove outdated content in COMPILE.md
2024-10-24 16:39:11 +08:00
f781bcd63d doc: fix compile manual
- move compile infos into an individual file.
- remove outdated compile manual, use latest one instead.
2024-10-18 15:04:54 +08:00
b319e0fcb6 feat: finish basic function of BMapSharp.
- fix weird C sharp behavior about calling FreeNativeData without calling ManagedToNative, which cause segment fault.
- disable unhandled exception handler in debug mode for BMap.
- change all associated code involving these issues.
2024-10-05 11:58:25 +08:00
3566efa36a feat: update custom marshaler in BMapSharp 2024-10-04 21:45:04 +08:00
96 changed files with 5283 additions and 1980 deletions

3
.gitignore vendored
View File

@ -5,6 +5,9 @@
*.nms *.nms
*.vmo *.vmo
# Ignore CMake generated version header
LibCmo/VTVersion.hpp
# Ignore temporary Visual Studio files and folders # Ignore temporary Visual Studio files and folders
temp/ temp/
out/ out/

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
@ -55,7 +58,7 @@ bool BMInit() {
if (CheckInited()) return false; if (CheckInited()) return false;
// register exception handler if we are in Windows. // register exception handler if we are in Windows.
#if YYCC_OS == YYCC_OS_WINDOWS #if defined(LIBCMO_BUILD_RELEASE) && (YYCC_OS == YYCC_OS_WINDOWS)
YYCC::ExceptionHelper::Register(); YYCC::ExceptionHelper::Register();
#endif #endif
@ -89,7 +92,7 @@ bool BMDispose() {
LibCmo::CK2::CKShutdown(); LibCmo::CK2::CKShutdown();
// unregister exception handler if we are in Windows // unregister exception handler if we are in Windows
#if YYCC_OS == YYCC_OS_WINDOWS #if defined(LIBCMO_BUILD_RELEASE) && (YYCC_OS == YYCC_OS_WINDOWS)
YYCC::ExceptionHelper::Unregister(); YYCC::ExceptionHelper::Unregister();
#endif #endif
@ -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

@ -18,8 +18,6 @@ FILES
target_include_directories(BMap target_include_directories(BMap
PRIVATE PRIVATE
"${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}"
YYCC::YYCCommonplace
LibCmo
) )
# Setup linked library infomation # Setup linked library infomation
target_link_libraries(BMap target_link_libraries(BMap
@ -52,6 +50,6 @@ PRIVATE
# Install BMap only on Release mode # Install BMap only on Release mode
install(TARGETS BMap install(TARGETS BMap
CONFIGURATIONS Release CONFIGURATIONS Release RelWithDebInfo MinSizeRel
RUNTIME DESTINATION ${YYCC_INSTALL_BIN_PATH} RUNTIME DESTINATION ${YYCC_INSTALL_BIN_PATH}
) )

View File

@ -0,0 +1,364 @@
root = true
# All files
[*]
indent_style = space
# Xml files
[*.xml]
indent_size = 2
# C# files
[*.cs]
#### Core EditorConfig Options ####
# Indentation and spacing
indent_size = 4
tab_width = 4
# New line preferences
end_of_line = crlf
insert_final_newline = false
#### .NET Coding Conventions ####
[*.{cs,vb}]
# Organize usings
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
file_header_template = unset
# this. and Me. preferences
dotnet_style_qualification_for_event = false:silent
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_property = false:silent
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
# Expression-level preferences
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_object_initializer = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
# Field preferences
dotnet_style_readonly_field = true:warning
# Parameter preferences
dotnet_code_quality_unused_parameters = all:suggestion
# Suppression preferences
dotnet_remove_unnecessary_suppression_exclusions = none
#### C# Coding Conventions ####
[*.cs]
# var preferences
csharp_style_var_elsewhere = false:silent
csharp_style_var_for_built_in_types = false:silent
csharp_style_var_when_type_is_apparent = false:silent
# Expression-bodied members
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_lambdas = true:suggestion
csharp_style_expression_bodied_local_functions = false:silent
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
# Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_prefer_not_pattern = true:suggestion
csharp_style_prefer_pattern_matching = true:silent
csharp_style_prefer_switch_expression = true:suggestion
# Null-checking preferences
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_prefer_static_local_function = true:warning
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
# Code-block preferences
csharp_prefer_braces = true:silent
csharp_prefer_simple_using_statement = true:suggestion
# Expression-level preferences
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_prefer_index_operator = true:suggestion
csharp_style_prefer_range_operator = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:silent
#### C# Formatting Rules ####
# New line preferences
csharp_new_line_before_catch = false
csharp_new_line_before_else = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
#### Naming styles ####
[*.{cs,vb}]
# Naming rules
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.symbols = types_and_namespaces
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.interfaces_should_be_ipascalcase.severity = suggestion
dotnet_naming_rule.interfaces_should_be_ipascalcase.symbols = interfaces
dotnet_naming_rule.interfaces_should_be_ipascalcase.style = ipascalcase
dotnet_naming_rule.type_parameters_should_be_tpascalcase.severity = suggestion
dotnet_naming_rule.type_parameters_should_be_tpascalcase.symbols = type_parameters
dotnet_naming_rule.type_parameters_should_be_tpascalcase.style = tpascalcase
dotnet_naming_rule.methods_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.methods_should_be_pascalcase.symbols = methods
dotnet_naming_rule.methods_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.properties_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.properties_should_be_pascalcase.symbols = properties
dotnet_naming_rule.properties_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.events_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.events_should_be_pascalcase.symbols = events
dotnet_naming_rule.events_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.local_variables_should_be_camelcase.severity = suggestion
dotnet_naming_rule.local_variables_should_be_camelcase.symbols = local_variables
dotnet_naming_rule.local_variables_should_be_camelcase.style = camelcase
dotnet_naming_rule.local_constants_should_be_camelcase.severity = suggestion
dotnet_naming_rule.local_constants_should_be_camelcase.symbols = local_constants
dotnet_naming_rule.local_constants_should_be_camelcase.style = camelcase
dotnet_naming_rule.parameters_should_be_camelcase.severity = suggestion
dotnet_naming_rule.parameters_should_be_camelcase.symbols = parameters
dotnet_naming_rule.parameters_should_be_camelcase.style = camelcase
dotnet_naming_rule.public_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.public_fields_should_be_pascalcase.symbols = public_fields
dotnet_naming_rule.public_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.private_fields_should_be__camelcase.severity = suggestion
dotnet_naming_rule.private_fields_should_be__camelcase.symbols = private_fields
dotnet_naming_rule.private_fields_should_be__camelcase.style = _camelcase
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.severity = suggestion
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.symbols = private_static_fields
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = s_camelcase
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.symbols = public_constant_fields
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.symbols = private_constant_fields
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.symbols = public_static_readonly_fields
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.symbols = private_static_readonly_fields
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.enums_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.enums_should_be_pascalcase.symbols = enums
dotnet_naming_rule.enums_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.local_functions_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.local_functions_should_be_pascalcase.symbols = local_functions
dotnet_naming_rule.local_functions_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.non_field_members_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascalcase.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase
# Symbol specifications
dotnet_naming_symbols.interfaces.applicable_kinds = interface
dotnet_naming_symbols.interfaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interfaces.required_modifiers =
dotnet_naming_symbols.enums.applicable_kinds = enum
dotnet_naming_symbols.enums.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.enums.required_modifiers =
dotnet_naming_symbols.events.applicable_kinds = event
dotnet_naming_symbols.events.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.events.required_modifiers =
dotnet_naming_symbols.methods.applicable_kinds = method
dotnet_naming_symbols.methods.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.methods.required_modifiers =
dotnet_naming_symbols.properties.applicable_kinds = property
dotnet_naming_symbols.properties.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.properties.required_modifiers =
dotnet_naming_symbols.public_fields.applicable_kinds = field
dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal
dotnet_naming_symbols.public_fields.required_modifiers =
dotnet_naming_symbols.private_fields.applicable_kinds = field
dotnet_naming_symbols.private_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
dotnet_naming_symbols.private_fields.required_modifiers =
dotnet_naming_symbols.private_static_fields.applicable_kinds = field
dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
dotnet_naming_symbols.private_static_fields.required_modifiers = static
dotnet_naming_symbols.types_and_namespaces.applicable_kinds = namespace, class, struct, interface, enum
dotnet_naming_symbols.types_and_namespaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types_and_namespaces.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
dotnet_naming_symbols.type_parameters.applicable_kinds = namespace
dotnet_naming_symbols.type_parameters.applicable_accessibilities = *
dotnet_naming_symbols.type_parameters.required_modifiers =
dotnet_naming_symbols.private_constant_fields.applicable_kinds = field
dotnet_naming_symbols.private_constant_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
dotnet_naming_symbols.private_constant_fields.required_modifiers = const
dotnet_naming_symbols.local_variables.applicable_kinds = local
dotnet_naming_symbols.local_variables.applicable_accessibilities = local
dotnet_naming_symbols.local_variables.required_modifiers =
dotnet_naming_symbols.local_constants.applicable_kinds = local
dotnet_naming_symbols.local_constants.applicable_accessibilities = local
dotnet_naming_symbols.local_constants.required_modifiers = const
dotnet_naming_symbols.parameters.applicable_kinds = parameter
dotnet_naming_symbols.parameters.applicable_accessibilities = *
dotnet_naming_symbols.parameters.required_modifiers =
dotnet_naming_symbols.public_constant_fields.applicable_kinds = field
dotnet_naming_symbols.public_constant_fields.applicable_accessibilities = public, internal
dotnet_naming_symbols.public_constant_fields.required_modifiers = const
dotnet_naming_symbols.public_static_readonly_fields.applicable_kinds = field
dotnet_naming_symbols.public_static_readonly_fields.applicable_accessibilities = public, internal
dotnet_naming_symbols.public_static_readonly_fields.required_modifiers = readonly, static
dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readonly, static
dotnet_naming_symbols.local_functions.applicable_kinds = local_function
dotnet_naming_symbols.local_functions.applicable_accessibilities = *
dotnet_naming_symbols.local_functions.required_modifiers =
# Naming styles
dotnet_naming_style.pascalcase.required_prefix =
dotnet_naming_style.pascalcase.required_suffix =
dotnet_naming_style.pascalcase.word_separator =
dotnet_naming_style.pascalcase.capitalization = pascal_case
dotnet_naming_style.ipascalcase.required_prefix = I
dotnet_naming_style.ipascalcase.required_suffix =
dotnet_naming_style.ipascalcase.word_separator =
dotnet_naming_style.ipascalcase.capitalization = pascal_case
dotnet_naming_style.tpascalcase.required_prefix = T
dotnet_naming_style.tpascalcase.required_suffix =
dotnet_naming_style.tpascalcase.word_separator =
dotnet_naming_style.tpascalcase.capitalization = pascal_case
dotnet_naming_style._camelcase.required_prefix = _
dotnet_naming_style._camelcase.required_suffix =
dotnet_naming_style._camelcase.word_separator =
dotnet_naming_style._camelcase.capitalization = camel_case
dotnet_naming_style.camelcase.required_prefix =
dotnet_naming_style.camelcase.required_suffix =
dotnet_naming_style.camelcase.word_separator =
dotnet_naming_style.camelcase.capitalization = camel_case
dotnet_naming_style.s_camelcase.required_prefix = s_
dotnet_naming_style.s_camelcase.required_suffix =
dotnet_naming_style.s_camelcase.word_separator =
dotnet_naming_style.s_camelcase.capitalization = camel_case

View File

@ -19,40 +19,48 @@ namespace BMapSharp {
public static class BMap { public static class BMap {
/// <summary>The callback function of BMap.</summary> #region Custom Marshalers
/// <param name="msg">The message content need to be printed.</param>
public delegate void OutputCallback([In, MarshalAs(UnmanagedType.LPUTF8Str)] string msg); // References:
// https://stackoverflow.com/questions/18498452/how-do-i-write-a-custom-marshaler-which-allows-data-to-flow-from-native-to-manag
// https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-runtime-interopservices-icustommarshaler
//
// NOTE: I do not create a member to store the object we are marshaling.
// Because my binding do not have In, Out parameter. All parameters are In OR Out.
// So there is no reason to keep that member.
// IDK why Microsoft try to call ICustomMarshaler.CleanUpNativeData without calling ICustomMarshaler.MarshalManagedToNative.
// It is trying to free the pointer managed by LibCmo self (for example, it will try to free we got string when getting object name)!
// So as the compromise, we use "cookie" feature to explicit specify the marshaler In/Out behavior when getting it.
[Flags]
internal enum MarshalerType {
None = 0b0,
In = 0b1,
Out = 0b10
}
/// <summary>The custom marshaler for BMap string array.</summary> /// <summary>The custom marshaler for BMap string array.</summary>
public class BMStringArrayMarshaler : ICustomMarshaler { public class BMStringArrayMarshaler : ICustomMarshaler {
// References: private static readonly BMStringArrayMarshaler g_InInstance = new BMStringArrayMarshaler(MarshalerType.In);
// https://stackoverflow.com/questions/18498452/how-do-i-write-a-custom-marshaler-which-allows-data-to-flow-from-native-to-manag private static readonly BMStringArrayMarshaler g_OutInstance = new BMStringArrayMarshaler(MarshalerType.Out);
// https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-runtime-interopservices-icustommarshaler public static ICustomMarshaler GetInstance(string pstrCookie) {
// if (pstrCookie == "In") return g_InInstance;
// NOTE: I do not create a member to store the object we are marshaling. else if (pstrCookie == "Out") return g_OutInstance;
// Because my binding do not have In, Out parameter. All parameters are In OR Out. else throw new MarshalDirectiveException("Not supported cookie string for BMStringArrayMarshaler.");
// So there is no reason to keep that member. }
private static readonly BMStringArrayMarshaler g_Instance = new BMStringArrayMarshaler(); private readonly MarshalerType m_MarshalerType;
public static ICustomMarshaler GetInstance(string pstrCookie) => g_Instance; private BMStringArrayMarshaler(MarshalerType marshaler_type) {
m_MarshalerType = marshaler_type;
}
// For respecting the standard of BMap, // For respecting the standard of BMap,
// the native memory we created is a simple array and each item is a pointer to a NULL-terminated UTF8 string. // the native memory we created is a simple array and each item is a pointer to a NULL-terminated UTF8 string.
// Please note the array self is not NULL-terminated because its length is provided by another argument in function calling. // Please note the array self is also NULL-terminated otherwise we don't know its length.
// However, this memory layout is not good for our marshaling.
// We can not know the size of array we created. Because we need iterate it when freeing or fetching data.
// We also can not know the size of string we created because we need read them when parsing them to C# string.
//
// So the solution we made is adding an uint32_t header before the array to indicate the size of array.
// And also add an uint32_t header for each string to indicate the length of string (in bytes, NULL exclusive).
// So the pointer put in array is not the address we allocated, it has an offset.
// Also we return native pointer is not the address we allocated, it also has an offset.
private static readonly int szLengthHeaderSize = Marshal.SizeOf<int>();
private static readonly int szArrayItemSize = Marshal.SizeOf<IntPtr>();
private static readonly int szStringItemSize = Marshal.SizeOf<byte>();
public IntPtr MarshalManagedToNative(object ManagedObj) { public IntPtr MarshalManagedToNative(object ManagedObj) {
// Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return IntPtr.Zero;
// Check nullptr object. // Check nullptr object.
if (ManagedObj is null) return IntPtr.Zero; if (ManagedObj is null) return IntPtr.Zero;
// Check argument type. // Check argument type.
@ -62,66 +70,50 @@ namespace BMapSharp {
// Allocate string items first // Allocate string items first
int szArrayItemCount = castManagedObj.Length; int szArrayItemCount = castManagedObj.Length;
IntPtr[] apStrings = new IntPtr[szArrayItemCount]; int szArrayItemSize = Marshal.SizeOf<IntPtr>();
IntPtr[] apString = new IntPtr[szArrayItemCount];
for (int i = 0; i < szArrayItemCount; ++i) { for (int i = 0; i < szArrayItemCount; ++i) {
// Encode string first. // Check null string
byte[] encString = Encoding.UTF8.GetBytes(castManagedObj[i]); string stringObj = castManagedObj[i];
// Allocate string memory with extra NULL terminal. if (stringObj is null) apString[i] = IntPtr.Zero;
int szStringItemCount = encString.Length; else apString[i] = BMStringMarshaler.ToNative(stringObj);
IntPtr pString = Marshal.AllocHGlobal(szStringItemSize * (szStringItemCount + 1) + szLengthHeaderSize);
// Setup length field
Marshal.WriteInt32(pString, 0, szStringItemCount);
// Copy string data with offset.
IntPtr pFakeString = pString + szLengthHeaderSize;
Marshal.Copy(encString, 0, pFakeString, szStringItemCount);
// Set NULL terminal.
Marshal.WriteByte(pFakeString, szStringItemSize * szStringItemCount, 0);
// Set item in string pointer
apStrings[i] = pFakeString;
} }
// Allocate array pointer now. // Allocate array pointer now.
IntPtr pArray = Marshal.AllocHGlobal(szArrayItemSize * szArrayItemCount + szLengthHeaderSize); IntPtr pArray = Marshal.AllocHGlobal(szArrayItemSize * (szArrayItemCount + 1));
// Setup length field // Copy string pointer data
Marshal.WriteInt32(pArray, 0, szArrayItemCount); Marshal.Copy(apString, 0, pArray, szArrayItemCount);
// Copy string pointer data with offset. // Setup NULL ternimal
IntPtr pFakeArray = pArray + szLengthHeaderSize; Marshal.WriteIntPtr(pArray + (szArrayItemSize * szArrayItemCount), IntPtr.Zero);
Marshal.Copy(apStrings, 0, pFakeArray, szArrayItemCount);
// Return value // Return value
return pFakeArray; return pArray;
} }
public object MarshalNativeToManaged(IntPtr pNativeData) { public object MarshalNativeToManaged(IntPtr pNativeData) {
// Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.Out)) return null;
// Check nullptr // Check nullptr
if (pNativeData == IntPtr.Zero) return null; if (pNativeData == IntPtr.Zero) return null;
// Get real array pointer // Get the length of array
IntPtr pFakeArray = pNativeData; int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData);
IntPtr pArray = pFakeArray - szLengthHeaderSize; int szArrayItemSize = Marshal.SizeOf<IntPtr>();
// Prepare array cache and read it.
// Get the count of array and read string pointers IntPtr[] apString = new IntPtr[szArrayItemCount];
int szArrayItemCount = Marshal.ReadInt32(pArray, 0); Marshal.Copy(pNativeData, apString, 0, szArrayItemCount);
IntPtr[] apStrings = new IntPtr[szArrayItemCount];
Marshal.Copy(pFakeArray, apStrings, 0, szArrayItemCount);
// Iterate the array and process each string one by one. // Iterate the array and process each string one by one.
string[] ret = new string[szArrayItemCount]; string[] ret = new string[szArrayItemCount];
for (int i = 0; i < szArrayItemCount; ++i) { for (int i = 0; i < szArrayItemCount; ++i) {
// Get string pointer // Get string pointer
IntPtr pFakeString = apStrings[i]; IntPtr pString = apString[i];
if (pFakeString == IntPtr.Zero) { if (pString == IntPtr.Zero) {
ret[i] = null; ret[i] = null;
continue; continue;
} }
IntPtr pString = pFakeString - szLengthHeaderSize; // Extract string
// Read string length ret[i] = BMStringMarshaler.ToManaged(pString);
int szStringItemCount = Marshal.ReadInt32(pString, 0);
// Read string body
byte[] encString = new byte[szStringItemCount];
Marshal.Copy(pFakeString, encString, 0, szStringItemCount);
// Decode string with UTF8
ret[i] = Encoding.UTF8.GetString(encString);
} }
// Return result // Return result
@ -129,30 +121,26 @@ namespace BMapSharp {
} }
public void CleanUpNativeData(IntPtr pNativeData) { public void CleanUpNativeData(IntPtr pNativeData) {
// Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return;
// Check nullptr // Check nullptr
if (pNativeData == IntPtr.Zero) return; if (pNativeData == IntPtr.Zero) return;
// Get real array pointer // Get the length of array
IntPtr pFakeArray = pNativeData; int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData);
IntPtr pArray = pFakeArray - szLengthHeaderSize; int szArrayItemSize = Marshal.SizeOf<IntPtr>();
// Prepare array cache and read it.
IntPtr[] apString = new IntPtr[szArrayItemCount];
Marshal.Copy(pNativeData, apString, 0, szArrayItemCount);
// Free array self
Marshal.FreeHGlobal(pNativeData);
// Get the count of array and read string pointers // Iterate the string pointer array and free them one by one.
int szArrayItemCount = Marshal.ReadInt32(pArray, 0); foreach (IntPtr pString in apString) {
IntPtr[] apStrings = new IntPtr[szArrayItemCount];
Marshal.Copy(pFakeArray, apStrings, 0, szArrayItemCount);
// Iterate the array and free them one by one.
for (int i = 0; i < szArrayItemCount; ++i) {
// Get string pointer
IntPtr pFakeString = apStrings[i];
if (pFakeString == IntPtr.Zero) continue;
IntPtr pString = pFakeString - szLengthHeaderSize;
// Free string pointer // Free string pointer
if (pString == IntPtr.Zero) continue;
Marshal.FreeHGlobal(pString); Marshal.FreeHGlobal(pString);
} }
// Free array self
Marshal.FreeHGlobal(pArray);
} }
public void CleanUpManagedData(object ManagedObj) { public void CleanUpManagedData(object ManagedObj) {
@ -164,8 +152,132 @@ namespace BMapSharp {
return -1; return -1;
} }
/// <summary>
/// Return the length of array created by this marshaler.
/// </summary>
/// <param name="ptr">The pointer to array for checking.</param>
/// <returns>The length of array (NULL terminal exclusive).</returns>
internal static int GetArrayLength(IntPtr ptr) {
int count = 0, unit = Marshal.SizeOf<IntPtr>();
while (Marshal.ReadIntPtr(ptr) != IntPtr.Zero) {
ptr += unit;
++count;
}
return count;
}
} }
public class BMStringMarshaler : ICustomMarshaler {
private static readonly BMStringMarshaler g_InInstance = new BMStringMarshaler(MarshalerType.In);
private static readonly BMStringMarshaler g_OutInstance = new BMStringMarshaler(MarshalerType.Out);
public static ICustomMarshaler GetInstance(string pstrCookie) {
if (pstrCookie == "In") return g_InInstance;
else if (pstrCookie == "Out") return g_OutInstance;
else throw new MarshalDirectiveException("Not supported cookie string for BMStringMarshaler.");
}
private readonly MarshalerType m_MarshalerType;
private BMStringMarshaler(MarshalerType marshaler_type) {
m_MarshalerType = marshaler_type;
}
public IntPtr MarshalManagedToNative(object ManagedObj) {
// Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return IntPtr.Zero;
// Check requirements.
if (ManagedObj is null) return IntPtr.Zero;
string castManagedObj = ManagedObj as string;
if (castManagedObj is null)
throw new MarshalDirectiveException("BMStringMarshaler must be used on a string.");
// Call self
return BMStringMarshaler.ToNative(castManagedObj);
}
public object MarshalNativeToManaged(IntPtr pNativeData) {
// Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.Out)) return null;
// Check nullptr
if (pNativeData == IntPtr.Zero) return null;
// Call self
return BMStringMarshaler.ToManaged(pNativeData);
}
public void CleanUpNativeData(IntPtr pNativeData) {
// Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return;
// Check nullptr
if (pNativeData == IntPtr.Zero) return;
// Free native pointer
Marshal.FreeHGlobal(pNativeData);
}
public void CleanUpManagedData(object ManagedObj) {
// Do nothing, because managed data do not need any clean up.
}
public int GetNativeDataSize() {
// Return -1 to indicate the managed type this marshaler handles is not a value type.
return -1;
}
/// <summary>
/// Return the length in byte of given pointer represented C style string.
/// </summary>
/// <param name="ptr">The pointer for checking.</param>
/// <returns>The length of C style string (NUL exclusive).</returns>
internal static int GetCStringLength(IntPtr ptr) {
int count = 0, unit = Marshal.SizeOf<byte>();
while (Marshal.ReadByte(ptr) != (byte)0) {
ptr += unit;
++count;
}
return count;
}
/// <summary>
/// Convert given string object to native data.
/// This function is shared by 2 marshalers.
/// </summary>
/// <param name="obj">String object. Caller must make sure this object is not null.</param>
/// <returns>The created native data pointer.</returns>
internal static IntPtr ToNative(string obj) {
// Encode string first
byte[] encString = Encoding.UTF8.GetBytes(obj);
// Allocate string memory with extra NUL.
int szStringItemCount = encString.Length;
int szStringItemSize = Marshal.SizeOf<byte>();
IntPtr pString = Marshal.AllocHGlobal(szStringItemSize * (szStringItemCount + 1));
// Copy encoded string data
Marshal.Copy(encString, 0, pString, szStringItemCount);
// Setup NUL
Marshal.WriteByte(pString + (szStringItemSize * szStringItemCount), (byte)0);
// Return value
return pString;
}
/// <summary>
/// Extract managed string from given native pointer holding C style string data.
/// This function is shared by 2 marshalers.
/// </summary>
/// <param name="ptr">Native pointer holding string data. Caller must make sure this pointer is not nullptr.</param>
/// <returns>The extracted managed string data.</returns>
internal static string ToManaged(IntPtr ptr) {
// Get the length of given string.
int szStringItemCount = BMStringMarshaler.GetCStringLength(ptr);
int szStringItemSize = Marshal.SizeOf<byte>();
// Prepare cache and copy string data
byte[] encString = new byte[szStringItemCount];
Marshal.Copy(ptr, encString, 0, szStringItemCount);
// Decode string and return
return Encoding.UTF8.GetString(encString);
}
}
#endregion
/// <summary>The callback function of BMap.</summary>
/// <param name="msg">The message content need to be printed.</param>
internal delegate void OutputCallback([In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler))] string msg);
// Decide the file name of loaded DLL. // Decide the file name of loaded DLL.
#if BMAP_OS_WINDOWS #if BMAP_OS_WINDOWS
@ -181,7 +293,7 @@ namespace BMapSharp {
#region Function Defines #region Function Defines
// ##### GENERATED FUNCTIONS BEGIN ##### // ##### GENERATED FUNCTIONS BEGIN #####
/// <summary>BMInit</summary> /// <summary>BMInit</summary>
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMInit", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMInit", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
@ -203,7 +315,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMFile_Load", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMFile_Load", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMFile_Load([In, MarshalAs(UnmanagedType.LPUTF8Str)] string file_name, [In, MarshalAs(UnmanagedType.LPUTF8Str)] string temp_folder, [In, MarshalAs(UnmanagedType.LPUTF8Str)] string texture_folder, [In, MarshalAs(UnmanagedType.FunctionPtr)] OutputCallback raw_callback, [In, MarshalAs(UnmanagedType.U4)] uint encoding_count, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringArrayMarshaler))] string[] encodings, [Out, MarshalAs(UnmanagedType.SysInt)] out IntPtr out_file); internal static extern bool BMFile_Load([In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "In")] string file_name, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "In")] string temp_folder, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "In")] string texture_folder, [In, MarshalAs(UnmanagedType.FunctionPtr)] OutputCallback raw_callback, [In, MarshalAs(UnmanagedType.U4)] uint encoding_count, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringArrayMarshaler), MarshalCookie = "In")] string[] encodings, [Out, MarshalAs(UnmanagedType.SysInt)] out IntPtr out_file);
/// <summary>BMFile_Create</summary> /// <summary>BMFile_Create</summary>
/// <param name="temp_folder">Type: LibCmo::CKSTRING. </param> /// <param name="temp_folder">Type: LibCmo::CKSTRING. </param>
/// <param name="texture_folder">Type: LibCmo::CKSTRING. </param> /// <param name="texture_folder">Type: LibCmo::CKSTRING. </param>
@ -214,7 +326,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMFile_Create", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMFile_Create", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMFile_Create([In, MarshalAs(UnmanagedType.LPUTF8Str)] string temp_folder, [In, MarshalAs(UnmanagedType.LPUTF8Str)] string texture_folder, [In, MarshalAs(UnmanagedType.FunctionPtr)] OutputCallback raw_callback, [In, MarshalAs(UnmanagedType.U4)] uint encoding_count, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringArrayMarshaler))] string[] encodings, [Out, MarshalAs(UnmanagedType.SysInt)] out IntPtr out_file); internal static extern bool BMFile_Create([In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "In")] string temp_folder, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "In")] string texture_folder, [In, MarshalAs(UnmanagedType.FunctionPtr)] OutputCallback raw_callback, [In, MarshalAs(UnmanagedType.U4)] uint encoding_count, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringArrayMarshaler), MarshalCookie = "In")] string[] encodings, [Out, MarshalAs(UnmanagedType.SysInt)] out IntPtr out_file);
/// <summary>BMFile_Save</summary> /// <summary>BMFile_Save</summary>
/// <param name="map_file">Type: BMap::BMFile*. </param> /// <param name="map_file">Type: BMap::BMFile*. </param>
/// <param name="file_name">Type: LibCmo::CKSTRING. </param> /// <param name="file_name">Type: LibCmo::CKSTRING. </param>
@ -224,7 +336,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMFile_Save", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMFile_Save", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMFile_Save([In, MarshalAs(UnmanagedType.SysInt)] IntPtr map_file, [In, MarshalAs(UnmanagedType.LPUTF8Str)] string file_name, [In, MarshalAs(UnmanagedType.U4)] uint texture_save_opt, [In, MarshalAs(UnmanagedType.U1)] bool use_compress, [In, MarshalAs(UnmanagedType.I4)] int compreess_level); internal static extern bool BMFile_Save([In, MarshalAs(UnmanagedType.SysInt)] IntPtr map_file, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "In")] string file_name, [In, MarshalAs(UnmanagedType.U4)] CK_TEXTURE_SAVEOPTIONS texture_save_opt, [In, MarshalAs(UnmanagedType.U1)] bool use_compress, [In, MarshalAs(UnmanagedType.I4)] int compreess_level);
/// <summary>BMFile_Free</summary> /// <summary>BMFile_Free</summary>
/// <param name="map_file">Type: BMap::BMFile*. </param> /// <param name="map_file">Type: BMap::BMFile*. </param>
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
@ -341,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>
@ -459,7 +593,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMObject_GetName", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMObject_GetName", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMObject_GetName([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.LPUTF8Str)] out string out_name); internal static extern bool BMObject_GetName([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "Out")] out string out_name);
/// <summary>BMObject_SetName</summary> /// <summary>BMObject_SetName</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>
@ -467,7 +601,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMObject_SetName", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMObject_SetName", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMObject_SetName([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.LPUTF8Str)] string name); internal static extern bool BMObject_SetName([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "In")] string name);
/// <summary>BMGroup_AddObject</summary> /// <summary>BMGroup_AddObject</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>
@ -500,7 +634,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_GetFileName", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMTexture_GetFileName", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMTexture_GetFileName([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.LPUTF8Str)] out string out_filename); internal static extern bool BMTexture_GetFileName([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "Out")] out string out_filename);
/// <summary>BMTexture_LoadImage</summary> /// <summary>BMTexture_LoadImage</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>
@ -508,7 +642,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_LoadImage", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMTexture_LoadImage", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMTexture_LoadImage([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.LPUTF8Str)] string filename); internal static extern bool BMTexture_LoadImage([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "In")] string filename);
/// <summary>BMTexture_SaveImage</summary> /// <summary>BMTexture_SaveImage</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>
@ -516,7 +650,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_SaveImage", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMTexture_SaveImage", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMTexture_SaveImage([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.LPUTF8Str)] string filename); internal static extern bool BMTexture_SaveImage([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "In")] string filename);
/// <summary>BMTexture_GetSaveOptions</summary> /// <summary>BMTexture_GetSaveOptions</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>
@ -524,7 +658,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_GetSaveOptions", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMTexture_GetSaveOptions", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMTexture_GetSaveOptions([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_saveopt); internal static extern bool BMTexture_GetSaveOptions([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out CK_TEXTURE_SAVEOPTIONS out_saveopt);
/// <summary>BMTexture_SetSaveOptions</summary> /// <summary>BMTexture_SetSaveOptions</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>
@ -532,7 +666,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_SetSaveOptions", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMTexture_SetSaveOptions", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMTexture_SetSaveOptions([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint saveopt); internal static extern bool BMTexture_SetSaveOptions([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] CK_TEXTURE_SAVEOPTIONS saveopt);
/// <summary>BMTexture_GetVideoFormat</summary> /// <summary>BMTexture_GetVideoFormat</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>
@ -540,7 +674,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_GetVideoFormat", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMTexture_GetVideoFormat", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMTexture_GetVideoFormat([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_vfmt); internal static extern bool BMTexture_GetVideoFormat([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VX_PIXELFORMAT out_vfmt);
/// <summary>BMTexture_SetVideoFormat</summary> /// <summary>BMTexture_SetVideoFormat</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>
@ -548,7 +682,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_SetVideoFormat", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMTexture_SetVideoFormat", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMTexture_SetVideoFormat([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint vfmt); internal static extern bool BMTexture_SetVideoFormat([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VX_PIXELFORMAT vfmt);
/// <summary>BMMaterial_GetDiffuse</summary> /// <summary>BMMaterial_GetDiffuse</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>
@ -668,7 +802,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureBlendMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureBlendMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetTextureBlendMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetTextureBlendMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXTEXTURE_BLENDMODE out_val);
/// <summary>BMMaterial_SetTextureBlendMode</summary> /// <summary>BMMaterial_SetTextureBlendMode</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>
@ -676,7 +810,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureBlendMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureBlendMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetTextureBlendMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetTextureBlendMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXTEXTURE_BLENDMODE val);
/// <summary>BMMaterial_GetTextureMinMode</summary> /// <summary>BMMaterial_GetTextureMinMode</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>
@ -684,7 +818,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureMinMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureMinMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetTextureMinMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetTextureMinMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXTEXTURE_FILTERMODE out_val);
/// <summary>BMMaterial_SetTextureMinMode</summary> /// <summary>BMMaterial_SetTextureMinMode</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>
@ -692,7 +826,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureMinMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureMinMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetTextureMinMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetTextureMinMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXTEXTURE_FILTERMODE val);
/// <summary>BMMaterial_GetTextureMagMode</summary> /// <summary>BMMaterial_GetTextureMagMode</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>
@ -700,7 +834,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureMagMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureMagMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetTextureMagMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetTextureMagMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXTEXTURE_FILTERMODE out_val);
/// <summary>BMMaterial_SetTextureMagMode</summary> /// <summary>BMMaterial_SetTextureMagMode</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>
@ -708,7 +842,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureMagMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureMagMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetTextureMagMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetTextureMagMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXTEXTURE_FILTERMODE val);
/// <summary>BMMaterial_GetTextureAddressMode</summary> /// <summary>BMMaterial_GetTextureAddressMode</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>
@ -716,7 +850,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureAddressMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureAddressMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetTextureAddressMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetTextureAddressMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXTEXTURE_ADDRESSMODE out_val);
/// <summary>BMMaterial_SetTextureAddressMode</summary> /// <summary>BMMaterial_SetTextureAddressMode</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>
@ -724,7 +858,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureAddressMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureAddressMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetTextureAddressMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetTextureAddressMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXTEXTURE_ADDRESSMODE val);
/// <summary>BMMaterial_GetSourceBlend</summary> /// <summary>BMMaterial_GetSourceBlend</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>
@ -732,7 +866,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetSourceBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetSourceBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetSourceBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetSourceBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXBLEND_MODE out_val);
/// <summary>BMMaterial_SetSourceBlend</summary> /// <summary>BMMaterial_SetSourceBlend</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>
@ -740,7 +874,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetSourceBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetSourceBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetSourceBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetSourceBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXBLEND_MODE val);
/// <summary>BMMaterial_GetDestBlend</summary> /// <summary>BMMaterial_GetDestBlend</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>
@ -748,7 +882,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetDestBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetDestBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetDestBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetDestBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXBLEND_MODE out_val);
/// <summary>BMMaterial_SetDestBlend</summary> /// <summary>BMMaterial_SetDestBlend</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>
@ -756,7 +890,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetDestBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetDestBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetDestBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetDestBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXBLEND_MODE val);
/// <summary>BMMaterial_GetFillMode</summary> /// <summary>BMMaterial_GetFillMode</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>
@ -764,7 +898,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetFillMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetFillMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetFillMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetFillMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXFILL_MODE out_val);
/// <summary>BMMaterial_SetFillMode</summary> /// <summary>BMMaterial_SetFillMode</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>
@ -772,7 +906,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetFillMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetFillMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetFillMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetFillMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXFILL_MODE val);
/// <summary>BMMaterial_GetShadeMode</summary> /// <summary>BMMaterial_GetShadeMode</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>
@ -780,7 +914,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetShadeMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetShadeMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetShadeMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetShadeMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXSHADE_MODE out_val);
/// <summary>BMMaterial_SetShadeMode</summary> /// <summary>BMMaterial_SetShadeMode</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>
@ -788,7 +922,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetShadeMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetShadeMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetShadeMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetShadeMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXSHADE_MODE val);
/// <summary>BMMaterial_GetAlphaTestEnabled</summary> /// <summary>BMMaterial_GetAlphaTestEnabled</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>
@ -876,7 +1010,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetAlphaRef", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetAlphaRef", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetAlphaRef([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetAlphaRef([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U1)] out byte out_val);
/// <summary>BMMaterial_SetAlphaRef</summary> /// <summary>BMMaterial_SetAlphaRef</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>
@ -884,7 +1018,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetAlphaRef", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetAlphaRef", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetAlphaRef([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetAlphaRef([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U1)] byte val);
/// <summary>BMMaterial_GetAlphaFunc</summary> /// <summary>BMMaterial_GetAlphaFunc</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>
@ -892,7 +1026,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetAlphaFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetAlphaFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetAlphaFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetAlphaFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXCMPFUNC out_val);
/// <summary>BMMaterial_SetAlphaFunc</summary> /// <summary>BMMaterial_SetAlphaFunc</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>
@ -900,7 +1034,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetAlphaFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetAlphaFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetAlphaFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetAlphaFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXCMPFUNC val);
/// <summary>BMMaterial_GetZFunc</summary> /// <summary>BMMaterial_GetZFunc</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>
@ -908,7 +1042,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetZFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetZFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetZFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetZFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXCMPFUNC out_val);
/// <summary>BMMaterial_SetZFunc</summary> /// <summary>BMMaterial_SetZFunc</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>
@ -916,7 +1050,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetZFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetZFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetZFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetZFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXCMPFUNC val);
/// <summary>BMMesh_GetLitMode</summary> /// <summary>BMMesh_GetLitMode</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>
@ -924,7 +1058,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMesh_GetLitMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMesh_GetLitMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMesh_GetLitMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_mode); internal static extern bool BMMesh_GetLitMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXMESH_LITMODE out_mode);
/// <summary>BMMesh_SetLitMode</summary> /// <summary>BMMesh_SetLitMode</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>
@ -932,7 +1066,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMesh_SetLitMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMesh_SetLitMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMesh_SetLitMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint mode); internal static extern bool BMMesh_SetLitMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXMESH_LITMODE mode);
/// <summary>BMMesh_GetVertexCount</summary> /// <summary>BMMesh_GetVertexCount</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>
@ -1039,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

@ -1,5 +1,5 @@
using System; using System;
using System.Reflection.Metadata.Ecma335; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using BMapSharp.VirtoolsTypes; using BMapSharp.VirtoolsTypes;
@ -23,6 +23,9 @@ namespace BMapSharp.BMapWrapper {
} }
public static class Utils { public static class Utils {
#region Constant Values
/// <summary>The representation of invalid raw pointer.</summary> /// <summary>The representation of invalid raw pointer.</summary>
internal static readonly IntPtr INVALID_PTR = IntPtr.Zero; internal static readonly IntPtr INVALID_PTR = IntPtr.Zero;
/// <summary>The representation of invalid CK_ID.</summary> /// <summary>The representation of invalid CK_ID.</summary>
@ -32,16 +35,75 @@ namespace BMapSharp.BMapWrapper {
/// It just writes the data in console. /// It just writes the data in console.
/// </summary> /// </summary>
internal static void BMapSharpCallback(string msg) { internal static void BMapSharpCallback(string msg) {
Console.WriteLine(msg); Console.WriteLine($"[BMapSharp] {msg}");
} }
#endregion
#region Help Functions
private static void StructAssigner<T>(IntPtr pstruct, uint count, IEnumerable<T> iem) {
var stride = Marshal.SizeOf<T>();
var itor = iem.GetEnumerator();
for (uint i = 0; i < count; ++i) {
if (!itor.MoveNext()) throw new BMapException("The length of given data is too short when assigning struct array.");
Marshal.StructureToPtr<T>(itor.Current, pstruct, false);
pstruct += stride;
}
}
internal static void VxVector3Assigner(IntPtr pstruct, uint count, IEnumerable<VxVector3> iem)
=> StructAssigner<VxVector3>(pstruct, count, iem);
internal static void VxVector2Assigner(IntPtr pstruct, uint count, IEnumerable<VxVector2> iem)
=> StructAssigner<VxVector2>(pstruct, count, iem);
internal static void CKFaceIndicesAssigner(IntPtr pstruct, uint count, IEnumerable<CKFaceIndices> iem)
=> StructAssigner<CKFaceIndices>(pstruct, count, iem);
internal static void CKShortFaceIndicesAssigner(IntPtr pstruct, uint count, IEnumerable<CKShortFaceIndices> iem)
=> StructAssigner<CKShortFaceIndices>(pstruct, count, iem);
internal static void ShortAssigner(IntPtr pstruct, uint count, IEnumerable<short> iem)
=> StructAssigner<short>(pstruct, count, iem);
internal static void CKIDAssigner(IntPtr pstruct, uint count, IEnumerable<uint> iem)
=> StructAssigner<uint>(pstruct, count, iem);
internal static void CKDWORDAssigner(IntPtr pstruct, uint count, IEnumerable<uint> iem)
=> StructAssigner<uint>(pstruct, count, iem);
private static IEnumerable<T> StructIterator<T>(IntPtr pstruct, uint count) {
var stride = Marshal.SizeOf<T>();
for (uint i = 0; i < count; ++i) {
yield return Marshal.PtrToStructure<T>(pstruct);
pstruct += stride;
}
}
internal static IEnumerable<VxVector3> VxVector3Iterator(IntPtr pstruct, uint count)
=> StructIterator<VxVector3>(pstruct, count);
internal static IEnumerable<VxVector2> VxVector2Iterator(IntPtr pstruct, uint count)
=> StructIterator<VxVector2>(pstruct, count);
internal static IEnumerable<CKFaceIndices> CKFaceIndicesIterator(IntPtr pstruct, uint count)
=> StructIterator<CKFaceIndices>(pstruct, count);
internal static IEnumerable<CKShortFaceIndices> CKShortFaceIndicesIterator(IntPtr pstruct, uint count)
=> StructIterator<CKShortFaceIndices>(pstruct, count);
internal static IEnumerable<short> ShortIterator(IntPtr pstruct, uint count)
=> StructIterator<short>(pstruct, count);
internal static IEnumerable<uint> CKIDIterator(IntPtr pstruct, uint count)
=> StructIterator<uint>(pstruct, count);
internal static IEnumerable<uint> CKDWORDIterator(IntPtr pstruct, uint count)
=> StructIterator<uint>(pstruct, count);
#endregion
#region End User Exposed
private static readonly BMapGuard Singleton = new BMapGuard(); private static readonly BMapGuard Singleton = new BMapGuard();
public static bool IsBMapAvailable() { public static bool IsBMapAvailable() {
return !Singleton.IsInvalid; return !Singleton.IsInvalid;
} }
#endregion
} }
public abstract class AbstractPointer : SafeHandle { // TODO: Maybe I need to implement IEquatable, IComparable<T>, and IComparable for AbstractPointer and AbstractCKObject.
// But I give it up. I am lazy. What I have written barely works for me now.
public abstract class AbstractPointer : SafeHandle, IEquatable<AbstractPointer> {
internal AbstractPointer(IntPtr raw_pointer) : base(Utils.INVALID_PTR, true) { internal AbstractPointer(IntPtr raw_pointer) : base(Utils.INVALID_PTR, true) {
this.handle = raw_pointer; this.handle = raw_pointer;
} }
@ -49,216 +111,505 @@ namespace BMapSharp.BMapWrapper {
public override bool IsInvalid => this.handle == Utils.INVALID_PTR; public override bool IsInvalid => this.handle == Utils.INVALID_PTR;
protected override bool ReleaseHandle() => throw new NotImplementedException(); protected override bool ReleaseHandle() => throw new NotImplementedException();
protected bool isValid() => this.handle != Utils.INVALID_PTR; internal bool isValid() => this.handle != Utils.INVALID_PTR;
protected IntPtr getPointer() => this.handle; internal IntPtr getPointer() => this.handle;
// protected AbstractPointer(IntPtr raw_pointer) : base(raw_pointer, true) {} #region IEquatable
// protected IntPtr GetPointer() => this.handle; public override bool Equals(object obj) => this.Equals(obj as AbstractPointer);
// public override bool IsInvalid { get { return this.handle == Utils.INVALID_PTR; } } public bool Equals(AbstractPointer obj) {
if (obj is null) return false;
// Optimization for a common success case
if (Object.ReferenceEquals(this, obj)) return true;
// If run-time types are not exactly the same, return false.
if (this.GetType() != obj.GetType()) return false;
// Return true if the fields match.
return this.handle == obj.handle;
}
// #region IComparable public override int GetHashCode() => this.handle.GetHashCode();
// public int CompareTo(AbstractPointer other) { public static bool operator ==(AbstractPointer lhs, AbstractPointer rhs) {
// return m_RawPointer.CompareTo(other.m_RawPointer); if (lhs is null) {
// } if (rhs is null) return true;
// Only left side is null.
return false;
}
// Equals handles case of null on right side
return lhs.Equals(rhs);
}
public static bool operator !=(AbstractPointer lhs, AbstractPointer rhs) => !(lhs == rhs);
// #endregion #endregion
// #region IEquatable
// public override bool Equals(object obj) => this.Equals(obj as AbstractPointer);
// public bool Equals(AbstractPointer other) {
// if (other is null) return false;
// if (Object.ReferenceEquals(this, other)) return true;
// // if (this.GetType() != other.GetType()) return false;
// return this.m_RawPointer == other.m_RawPointer;
// }
// public static bool operator ==(AbstractPointer lhs, AbstractPointer rhs) {
// if (lhs is null) {
// if (rhs is null) return true;
// return false;
// }
// return lhs.Equals(rhs);
// }
// public static bool operator !=(AbstractPointer lhs, AbstractPointer rhs) => !(lhs == rhs);
// #endregion
#region Misc #region Misc
public override int GetHashCode() => this.handle.GetHashCode();
public override string ToString() => this.handle.ToString(); public override string ToString() => this.handle.ToString();
#endregion #endregion
} }
public abstract class AbstractCKObject { public abstract class AbstractCKObject : SafeHandle, IEquatable<AbstractCKObject> {
internal AbstractCKObject(IntPtr raw_pointer, uint ckid) { // Same as AbstractPointer, but not own this handle.
m_RawPointer = raw_pointer; internal AbstractCKObject(IntPtr raw_pointer, uint ckid) : base(Utils.INVALID_PTR, false) {
this.handle = raw_pointer;
m_CKID = ckid; m_CKID = ckid;
} }
private readonly IntPtr m_RawPointer; public override bool IsInvalid => this.handle == Utils.INVALID_PTR;
protected override bool ReleaseHandle() => throw new NotImplementedException();
private readonly uint m_CKID; private readonly uint m_CKID;
protected bool isValid() => m_RawPointer != Utils.INVALID_PTR && m_RawPointer != Utils.INVALID_CKID; internal bool isValid() => this.handle != Utils.INVALID_PTR && m_CKID != Utils.INVALID_CKID;
protected IntPtr getPointer() => m_RawPointer; internal IntPtr getPointer() => this.handle;
protected uint getCKID() => m_CKID; internal uint getCKID() => m_CKID;
// private uint m_CKID; #region IEquatable
// protected AbstractCKObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer) { public override bool Equals(object obj) => this.Equals(obj as AbstractCKObject);
// m_CKID = ckid; public bool Equals(AbstractCKObject obj) {
// } if (obj is null) return false;
// Optimization for a common success case
if (Object.ReferenceEquals(this, obj)) return true;
// If run-time types are not exactly the same, return false.
if (this.GetType() != obj.GetType()) return false;
// Return true if the fields match.
return (this.m_CKID == obj.m_CKID) && (this.handle == obj.handle);
}
// protected override bool IsValid() => base.IsValid() && m_CKID != Utils.INVALID_CKID; public override int GetHashCode() => HashCode.Combine(this.handle, m_CKID);
// protected uint GetCKID() => m_CKID;
// #region IComparable public static bool operator ==(AbstractCKObject lhs, AbstractCKObject rhs) {
if (lhs is null) {
if (rhs is null) return true;
// Only left side is null.
return false;
}
// Equals handles case of null on right side
return lhs.Equals(rhs);
}
public static bool operator !=(AbstractCKObject lhs, AbstractCKObject rhs) => !(lhs == rhs);
// public int CompareTo(AbstractCKObject other) { #endregion
// var ret = base.CompareTo((AbstractPointer)other);
// if (ret != 0) return ret;
// return m_CKID.CompareTo(other.m_CKID);
// }
// #endregion
// #region IEquatable
// public override bool Equals(object obj) => this.Equals(obj as AbstractCKObject);
// public bool Equals(AbstractCKObject other) {
// if (other is null) return false;
// if (Object.ReferenceEquals(this, other)) return true;
// }
// public static bool operator ==(AbstractCKObject left, AbstractCKObject right) =>
// ((AbstractPointer)left == (AbstractPointer)right) && left.m_CKID == right.m_CKID;
// public static bool operator !=(AbstractCKObject left, AbstractCKObject right) =>
// ((AbstractPointer)left != (AbstractPointer)right) || left.m_CKID != right.m_CKID;
// #endregion
#region Misc #region Misc
public override int GetHashCode() => HashCode.Combine(m_RawPointer, m_CKID); public override string ToString() => $"{this.handle}, {m_CKID}";
public override string ToString() => $"{m_RawPointer}, {m_CKID}";
#endregion
#region Subclass Utilities
protected delegate bool FctGenericValueGetter<T>(IntPtr bmf, uint id, out T val);
protected delegate bool FctGenericValueSetter<T>(IntPtr bmf, uint id, T val);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected T getGenericValue<T>(FctGenericValueGetter<T> fct) {
BMapException.ThrowIfFailed(fct(getPointer(), getCKID(), out T out_val));
return out_val;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void setGenericValue<T>(FctGenericValueSetter<T> fct, T val) {
BMapException.ThrowIfFailed(fct(getPointer(), getCKID(), val));
}
#endregion #endregion
} }
public class BMObject : AbstractCKObject { public class BMObject : AbstractCKObject {
internal BMObject(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {} internal BMObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public string GetName() { public string GetName() => getGenericValue<string>(BMap.BMObject_GetName);
BMapException.ThrowIfFailed(BMap.BMObject_GetName( public void SetName(string name) => setGenericValue<string>(BMap.BMObject_SetName, name);
this.getPointer(), this.getCKID(), out string out_name
));
return out_name;
}
public void SetName(string name) {
BMapException.ThrowIfFailed(BMap.BMObject_SetName(
this.getPointer(), this.getCKID(), name
));
}
} }
public class BMTexture : BMObject { public class BMTexture : BMObject {
internal BMTexture(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {} internal BMTexture(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public string GetFileName() => getGenericValue<string>(BMap.BMTexture_GetFileName);
public void LoadImage(string filepath) {
BMapException.ThrowIfFailed(BMap.BMTexture_LoadImage(getPointer(), getCKID(), filepath));
}
public void SaveImage(string filepath) {
BMapException.ThrowIfFailed(BMap.BMTexture_SaveImage(getPointer(), getCKID(), filepath));
}
public CK_TEXTURE_SAVEOPTIONS GetSaveOptions() => getGenericValue<CK_TEXTURE_SAVEOPTIONS>(BMap.BMTexture_GetSaveOptions);
public void SetSaveOptions(CK_TEXTURE_SAVEOPTIONS opt) => setGenericValue<CK_TEXTURE_SAVEOPTIONS>(BMap.BMTexture_SetSaveOptions, opt);
public VX_PIXELFORMAT GetVideoFormat() => getGenericValue<VX_PIXELFORMAT>(BMap.BMTexture_GetVideoFormat);
public void SetVideoFormat(VX_PIXELFORMAT vfmt) => setGenericValue<VX_PIXELFORMAT>(BMap.BMTexture_SetVideoFormat, vfmt);
} }
public class BMMaterial : BMObject { public class BMMaterial : BMObject {
internal BMMaterial(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {} internal BMMaterial(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public VxColor GetDiffuse() => getGenericValue<VxColor>(BMap.BMMaterial_GetDiffuse);
public void SetDiffuse(VxColor col) => setGenericValue<VxColor>(BMap.BMMaterial_SetDiffuse, col);
public VxColor GetAmbient() => getGenericValue<VxColor>(BMap.BMMaterial_GetAmbient);
public void SetAmbient(VxColor col) => setGenericValue<VxColor>(BMap.BMMaterial_SetAmbient, col);
public VxColor GetSpecular() => getGenericValue<VxColor>(BMap.BMMaterial_GetSpecular);
public void SetSpecular(VxColor col) => setGenericValue<VxColor>(BMap.BMMaterial_SetSpecular, col);
public VxColor GetEmissive() => getGenericValue<VxColor>(BMap.BMMaterial_GetEmissive);
public void SetEmissive(VxColor col) => setGenericValue<VxColor>(BMap.BMMaterial_SetEmissive, col);
public float GetSpecularPower() => getGenericValue<float>(BMap.BMMaterial_GetSpecularPower);
public void SetSpecularPower(float val) => setGenericValue<float>(BMap.BMMaterial_SetSpecularPower, val);
public VxColor GetTextureBorderColor() {
BMapException.ThrowIfFailed(BMap.BMMaterial_GetTextureBorderColor(getPointer(), getCKID(), out uint out_val));
return new VxColor(out_val);
}
public void SetTextureBorderColor(VxColor col) {
BMapException.ThrowIfFailed(BMap.BMMaterial_SetTextureBorderColor(getPointer(), getCKID(), col.ToDword()));
}
public VXTEXTURE_BLENDMODE GetTextureBlendMode() => getGenericValue<VXTEXTURE_BLENDMODE>(BMap.BMMaterial_GetTextureBlendMode);
public void SetTextureBlendMode(VXTEXTURE_BLENDMODE val) => setGenericValue<VXTEXTURE_BLENDMODE>(BMap.BMMaterial_SetTextureBlendMode, val);
public VXTEXTURE_FILTERMODE GetTextureMinMode() => getGenericValue<VXTEXTURE_FILTERMODE>(BMap.BMMaterial_GetTextureMinMode);
public void SetTextureMinMode(VXTEXTURE_FILTERMODE val) => setGenericValue<VXTEXTURE_FILTERMODE>(BMap.BMMaterial_SetTextureMinMode, val);
public VXTEXTURE_FILTERMODE GetTextureMagMode() => getGenericValue<VXTEXTURE_FILTERMODE>(BMap.BMMaterial_GetTextureMagMode);
public void SetTextureMagMode(VXTEXTURE_FILTERMODE val) => setGenericValue<VXTEXTURE_FILTERMODE>(BMap.BMMaterial_SetTextureMagMode, val);
public VXTEXTURE_ADDRESSMODE GetTextureAddressMode() => getGenericValue<VXTEXTURE_ADDRESSMODE>(BMap.BMMaterial_GetTextureAddressMode);
public void SetTextureAddressMode(VXTEXTURE_ADDRESSMODE val) => setGenericValue<VXTEXTURE_ADDRESSMODE>(BMap.BMMaterial_SetTextureAddressMode, val);
public VXBLEND_MODE GetSourceBlend() => getGenericValue<VXBLEND_MODE>(BMap.BMMaterial_GetSourceBlend);
public void SetSourceBlend(VXBLEND_MODE val) => setGenericValue<VXBLEND_MODE>(BMap.BMMaterial_SetSourceBlend, val);
public VXBLEND_MODE GetDestBlend() => getGenericValue<VXBLEND_MODE>(BMap.BMMaterial_GetDestBlend);
public void SetDestBlend(VXBLEND_MODE val) => setGenericValue<VXBLEND_MODE>(BMap.BMMaterial_SetDestBlend, val);
public VXFILL_MODE GetFillMode() => getGenericValue<VXFILL_MODE>(BMap.BMMaterial_GetFillMode);
public void SetFillMode(VXFILL_MODE val) => setGenericValue<VXFILL_MODE>(BMap.BMMaterial_SetFillMode, val);
public VXSHADE_MODE GetShadeMode() => getGenericValue<VXSHADE_MODE>(BMap.BMMaterial_GetShadeMode);
public void SetShadeMode(VXSHADE_MODE val) => setGenericValue<VXSHADE_MODE>(BMap.BMMaterial_SetShadeMode, val);
public bool GetAlphaTestEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetAlphaTestEnabled);
public void SetAlphaTestEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetAlphaTestEnabled, val);
public bool GetAlphaBlendEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetAlphaBlendEnabled);
public void SetAlphaBlendEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetAlphaBlendEnabled, val);
public bool GetPerspectiveCorrectionEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetPerspectiveCorrectionEnabled);
public void SetPerspectiveCorrectionEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetPerspectiveCorrectionEnabled, val);
public bool GetZWriteEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetZWriteEnabled);
public void SetZWriteEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetZWriteEnabled, val);
public bool GetTwoSidedEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetTwoSidedEnabled);
public void SetTwoSidedEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetTwoSidedEnabled, val);
public byte GetAlphaRef() => getGenericValue<byte>(BMap.BMMaterial_GetAlphaRef);
public void SetAlphaRef(byte val) => setGenericValue<byte>(BMap.BMMaterial_SetAlphaRef, val);
public VXCMPFUNC GetAlphaFunc() => getGenericValue<VXCMPFUNC>(BMap.BMMaterial_GetAlphaFunc);
public void SetAlphaFunc(VXCMPFUNC val) => setGenericValue<VXCMPFUNC>(BMap.BMMaterial_SetAlphaFunc, val);
public VXCMPFUNC GetZFunc() => getGenericValue<VXCMPFUNC>(BMap.BMMaterial_GetZFunc);
public void SetZFunc(VXCMPFUNC val) => setGenericValue<VXCMPFUNC>(BMap.BMMaterial_SetZFunc, val);
} }
public class BMMesh : BMObject { public class BMMesh : BMObject {
internal BMMesh(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {} internal BMMesh(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public VXMESH_LITMODE GetLitMode() => getGenericValue<VXMESH_LITMODE>(BMap.BMMesh_GetLitMode);
public void SetLitMode(VXMESH_LITMODE mode) => setGenericValue<VXMESH_LITMODE>(BMap.BMMesh_SetLitMode, mode);
public uint GetVertexCount() => getGenericValue<uint>(BMap.BMMesh_GetVertexCount);
public void SetVertexCount(uint count) => setGenericValue<uint>(BMap.BMMesh_SetVertexCount, count);
public IEnumerable<VxVector3> GetVertexPositions() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexPositions(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.VxVector3Iterator(out_mem, GetVertexCount());
}
public void SetVertexPositions(IEnumerable<VxVector3> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexPositions(getPointer(), getCKID(), out IntPtr out_mem));
Utils.VxVector3Assigner(out_mem, GetVertexCount(), iem);
}
public IEnumerable<VxVector3> GetVertexNormals() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexNormals(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.VxVector3Iterator(out_mem, GetVertexCount());
}
public void SetVertexNormals(IEnumerable<VxVector3> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexNormals(getPointer(), getCKID(), out IntPtr out_mem));
Utils.VxVector3Assigner(out_mem, GetVertexCount(), iem);
}
public IEnumerable<VxVector2> GetVertexUVs() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexUVs(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.VxVector2Iterator(out_mem, GetVertexCount());
}
public void SetVertexUVs(IEnumerable<VxVector2> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexUVs(getPointer(), getCKID(), out IntPtr out_mem));
Utils.VxVector2Assigner(out_mem, GetVertexCount(), iem);
}
public uint GetFaceCount() => getGenericValue<uint>(BMap.BMMesh_GetFaceCount);
public void SetFaceCount(uint count) => setGenericValue<uint>(BMap.BMMesh_SetFaceCount, count);
public IEnumerable<CKShortFaceIndices> GetFaceIndices() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceIndices(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.CKShortFaceIndicesIterator(out_mem, GetFaceCount());
}
public void SetFaceIndices(IEnumerable<CKShortFaceIndices> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceIndices(getPointer(), getCKID(), out IntPtr out_mem));
Utils.CKShortFaceIndicesAssigner(out_mem, GetFaceCount(), iem);
}
public IEnumerable<short> GetFaceMaterialSlotIndexs() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceMaterialSlotIndexs(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.ShortIterator(out_mem, GetFaceCount());
}
public void SetFaceMaterialSlotIndexs(IEnumerable<short> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceMaterialSlotIndexs(getPointer(), getCKID(), out IntPtr out_mem));
Utils.ShortAssigner(out_mem, GetFaceCount(), iem);
}
public uint GetMaterialSlotCount() => getGenericValue<uint>(BMap.BMMesh_GetMaterialSlotCount);
public void SetMaterialSlotCount(uint count) => setGenericValue<uint>(BMap.BMMesh_SetMaterialSlotCount, count);
public IEnumerable<BMMaterial> GetMaterialSlots() {
uint count = GetMaterialSlotCount();
for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetMaterialSlot(getPointer(), getCKID(), i, out uint out_mtlid));
if (out_mtlid == Utils.INVALID_CKID) yield return null;
else yield return new BMMaterial(getPointer(), out_mtlid);
}
}
public void SetMaterialSlots(IEnumerable<BMMaterial> iem) {
uint count = GetMaterialSlotCount();
var itor = iem.GetEnumerator();
for (uint i = 0; i < count; ++i) {
if (!itor.MoveNext()) throw new BMapException("The length of given material array is too short when assigning material slots.");
uint mtlid = itor.Current is null ? Utils.INVALID_CKID : itor.Current.getCKID();
BMapException.ThrowIfFailed(BMap.BMMesh_SetMaterialSlot(getPointer(), getCKID(), i, mtlid));
}
}
} }
public class BM3dObject : BMObject { public class BM3dEntity : BMObject {
internal BM3dObject(nint 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.BM3dEntity_GetWorldMatrix);
public void SetWorldMatrix(VxMatrix mat) => setGenericValue<VxMatrix>(BMap.BM3dEntity_SetWorldMatrix, mat);
public BMMesh GetCurrentMesh() {
BMapException.ThrowIfFailed(BMap.BM3dEntity_GetCurrentMesh(getPointer(), getCKID(), out uint out_meshid));
if (out_meshid == Utils.INVALID_CKID) return null;
else return new BMMesh(getPointer(), out_meshid);
}
public void SetCurrentMesh(BMMesh mesh) {
uint meshid = (mesh is null) ? Utils.INVALID_CKID : mesh.getCKID();
BMapException.ThrowIfFailed(BMap.BM3dEntity_SetCurrentMesh(getPointer(), getCKID(), meshid));
}
public bool GetVisibility() => getGenericValue<bool>(BMap.BM3dEntity_GetVisibility);
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 {
internal BMGroup(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {} internal BMGroup(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public void AddObject(BM3dObject member) {
BMapException.ThrowIfFailed(BMap.BMGroup_AddObject(getPointer(), getCKID(), member.getCKID()));
}
public uint GetObjectCount() => getGenericValue<uint>(BMap.BMGroup_GetObjectCount);
public IEnumerable<BM3dObject> GetObjects() {
var size = GetObjectCount();
for (uint i = 0; i < size; ++i) {
BMapException.ThrowIfFailed(BMap.BMGroup_GetObject(getPointer(), getCKID(), i, out uint out_objid));
yield return new BM3dObject(getPointer(), out_objid);
}
}
} }
public sealed class BMFileReader : AbstractPointer { public sealed class BMFileReader : AbstractPointer {
private static IntPtr AllocateHandle(string file_name, string temp_folder, string texture_folder, string[] encodings) { private static IntPtr allocateHandle(string file_name, string temp_folder, string texture_folder, string[] encodings) {
BMapException.ThrowIfFailed(BMap.BMFile_Load( BMapException.ThrowIfFailed(BMap.BMFile_Load(
file_name, temp_folder, texture_folder, file_name, temp_folder, texture_folder,
Utils.BMapSharpCallback, Utils.BMapSharpCallback,
(uint)encodings.Length, encodings, (uint)encodings.Length, encodings,
out IntPtr out_file out IntPtr out_file
)); ));
return out_file; return out_file;
} }
protected override bool ReleaseHandle() { protected override bool ReleaseHandle() {
return BMap.BMFile_Free(this.handle); return BMap.BMFile_Free(this.getPointer());
} }
public BMFileReader(string file_name, string temp_folder, string texture_folder, string[] encodings) public BMFileReader(string file_name, string temp_folder, string texture_folder, string[] encodings)
: base(AllocateHandle(file_name, temp_folder, texture_folder, encodings)) {} : base(allocateHandle(file_name, temp_folder, texture_folder, encodings)) { }
public uint GetTextureCount() { private delegate bool FctProtoGetCount(IntPtr bmf, out uint cnt);
BMapException.ThrowIfFailed(BMap.BMFile_GetTextureCount(this.getPointer(), out uint out_count)); private delegate bool FctProtoGetObject(IntPtr bmf, uint idx, out uint id);
private delegate T FctProtoCreateInstance<T>(IntPtr bmf, uint id);
private uint getCKObjectCount(FctProtoGetCount fct_cnt) {
BMapException.ThrowIfFailed(fct_cnt(this.getPointer(), out uint out_count));
return out_count; return out_count;
} }
public IEnumerable<BMTexture> GetTextures() { private IEnumerable<T> getCKObjects<T>(FctProtoGetCount fct_cnt, FctProtoGetObject fct_obj, FctProtoCreateInstance<T> fct_crt) {
uint count = GetTextureCount(); uint count = getCKObjectCount(fct_cnt);
for (uint i = 0; i < count; ++i) { for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMFile_GetTexture(this.getPointer(), i, out uint out_id)); BMapException.ThrowIfFailed(fct_obj(this.getPointer(), i, out uint out_id));
yield return new BMTexture(this.getPointer(), out_id); yield return fct_crt(this.getPointer(), out_id);
} }
} }
public uint GetMaterialCount() { public uint GetTextureCount() =>
BMapException.ThrowIfFailed(BMap.BMFile_GetMaterialCount(this.getPointer(), out uint out_count)); getCKObjectCount(BMap.BMFile_GetTextureCount);
return out_count; public IEnumerable<BMTexture> GetTextures() =>
getCKObjects<BMTexture>(BMap.BMFile_GetTextureCount, BMap.BMFile_GetTexture, (bmf, id) => new BMTexture(bmf, id));
public uint GetMaterialCount() =>
getCKObjectCount(BMap.BMFile_GetMaterialCount);
public IEnumerable<BMMaterial> GetMaterials() =>
getCKObjects<BMMaterial>(BMap.BMFile_GetMaterialCount, BMap.BMFile_GetMaterial, (bmf, id) => new BMMaterial(bmf, id));
public uint GetMeshCount() =>
getCKObjectCount(BMap.BMFile_GetMeshCount);
public IEnumerable<BMMesh> GetMeshes() =>
getCKObjects<BMMesh>(BMap.BMFile_GetMeshCount, BMap.BMFile_GetMesh, (bmf, id) => new BMMesh(bmf, id));
public uint Get3dObjectCount() =>
getCKObjectCount(BMap.BMFile_Get3dObjectCount);
public IEnumerable<BM3dObject> Get3dObjects() =>
getCKObjects<BM3dObject>(BMap.BMFile_Get3dObjectCount, BMap.BMFile_Get3dObject, (bmf, id) => new BM3dObject(bmf, id));
public uint GetGroupCount() =>
getCKObjectCount(BMap.BMFile_GetGroupCount);
public IEnumerable<BMGroup> GetGroups() =>
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));
}
public sealed class BMFileWriter : AbstractPointer {
private static IntPtr allocateHandle(string temp_folder, string texture_folder, string[] encodings) {
BMapException.ThrowIfFailed(BMap.BMFile_Create(
temp_folder, texture_folder,
Utils.BMapSharpCallback,
(uint)encodings.Length, encodings,
out IntPtr out_file
));
return out_file;
} }
public IEnumerable<BMMaterial> GetMaterials() { protected override bool ReleaseHandle() {
uint count = GetMaterialCount(); return BMap.BMFile_Free(this.getPointer());
for (uint i = 0; i < count; ++i) { }
BMapException.ThrowIfFailed(BMap.BMFile_GetMaterial(this.getPointer(), i, out uint out_id)); public BMFileWriter(string temp_folder, string texture_folder, string[] encodings)
yield return new BMMaterial(this.getPointer(), out_id); : base(allocateHandle(temp_folder, texture_folder, encodings)) { }
}
public void Save(string filename, CK_TEXTURE_SAVEOPTIONS texture_save_opt, bool use_compress, int compress_level) {
BMapException.ThrowIfFailed(BMap.BMFile_Save(
getPointer(),
filename,
texture_save_opt,
use_compress,
compress_level
));
} }
public uint GetMeshCount() { private delegate bool FctProtoCreateObject(IntPtr bmf, out uint id);
BMapException.ThrowIfFailed(BMap.BMFile_GetMeshCount(this.getPointer(), out uint out_count)); private delegate T FctProtoCreateInstance<T>(IntPtr bmf, uint id);
return out_count; private T createCKObject<T>(FctProtoCreateObject fct_crt, FctProtoCreateInstance<T> fct_inst) {
} BMapException.ThrowIfFailed(fct_crt(this.getPointer(), out uint out_id));
public IEnumerable<BMMesh> GetMeshs() { return fct_inst(this.getPointer(), out_id);
uint count = GetMeshCount();
for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMFile_GetMesh(this.getPointer(), i, out uint out_id));
yield return new BMMesh(this.getPointer(), out_id);
}
} }
public uint Get3dObjectCount() { public BMTexture CreateTexture() => createCKObject<BMTexture>(BMap.BMFile_CreateTexture, (bmf, id) => new BMTexture(bmf, id));
BMapException.ThrowIfFailed(BMap.BMFile_Get3dObjectCount(this.getPointer(), out uint out_count)); public BMMaterial CreateMaterial() => createCKObject<BMMaterial>(BMap.BMFile_CreateMaterial, (bmf, id) => new BMMaterial(bmf, id));
return out_count; 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 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 {
private static IntPtr allocateHandle() {
BMapException.ThrowIfFailed(BMap.BMMeshTrans_New(out IntPtr out_trans));
return out_trans;
} }
public IEnumerable<BM3dObject> Get3dObjects() { protected override bool ReleaseHandle() {
uint count = Get3dObjectCount(); return BMap.BMMeshTrans_Delete(this.getPointer());
for (uint i = 0; i < count; ++i) { }
BMapException.ThrowIfFailed(BMap.BMFile_Get3dObject(this.getPointer(), i, out uint out_id)); public BMMeshTrans() : base(allocateHandle()) { }
yield return new BM3dObject(this.getPointer(), out_id);
} public void Parse(BMMesh objmesh) {
BMapException.ThrowIfFailed(BMap.BMMeshTrans_Parse(
getPointer(),
objmesh.getPointer(),
objmesh.getCKID()
));
} }
public uint GetGroupCount() { public void PrepareVertex(uint count, IEnumerable<VxVector3> iem) {
BMapException.ThrowIfFailed(BMap.BMFile_GetGroupCount(this.getPointer(), out uint out_count)); // Prepare count first
return out_count; BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareVertexCount(getPointer(), count));
// Then put data
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareVertex(getPointer(), out IntPtr out_mem));
Utils.VxVector3Assigner(out_mem, count, iem);
} }
public IEnumerable<BMGroup> GetGroups() { public void PrepareNormal(uint count, IEnumerable<VxVector3> iem) {
uint count = GetGroupCount(); // Prepare count first
for (uint i = 0; i < count; ++i) { BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareNormalCount(getPointer(), count));
BMapException.ThrowIfFailed(BMap.BMFile_GetGroup(this.getPointer(), i, out uint out_id)); // Then put data
yield return new BMGroup(this.getPointer(), out_id); BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareNormal(getPointer(), out IntPtr out_mem));
} Utils.VxVector3Assigner(out_mem, count, iem);
}
public void PrepareUV(uint count, IEnumerable<VxVector2> iem) {
// Prepare count first
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareUVCount(getPointer(), count));
// Then put data
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareUV(getPointer(), out IntPtr out_mem));
Utils.VxVector2Assigner(out_mem, count, iem);
}
public void PrepareMtlSlot(uint count, IEnumerable<BMMaterial> iem) {
// Prepare count first
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareMtlSlotCount(getPointer(), count));
// Then put data
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareMtlSlot(getPointer(), out IntPtr out_mem));
var cast_iem = iem.Select((mtl) => mtl is null ? Utils.INVALID_CKID : mtl.getCKID());
Utils.CKIDAssigner(out_mem, count, cast_iem);
}
public void PrepareFace(uint count, IEnumerable<CKFaceIndices> vec_idx, IEnumerable<CKFaceIndices> nml_idx, IEnumerable<CKFaceIndices> uv_idx, IEnumerable<uint> mtl_idx) {
// Prepare count first
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareFaceCount(getPointer(), count));
// Get data address
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareFaceVertexIndices(getPointer(), out IntPtr raw_vec_idx));
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareFaceNormalIndices(getPointer(), out IntPtr raw_nml_idx));
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareFaceUVIndices(getPointer(), out IntPtr raw_uv_idx));
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareFaceMtlSlot(getPointer(), out IntPtr raw_mtl_idx));
// Assign data
Utils.CKFaceIndicesAssigner(raw_vec_idx, count, vec_idx);
Utils.CKFaceIndicesAssigner(raw_nml_idx, count, nml_idx);
Utils.CKFaceIndicesAssigner(raw_uv_idx, count, uv_idx);
Utils.CKDWORDAssigner(raw_mtl_idx, count, mtl_idx);
} }
} }

View File

@ -15,12 +15,14 @@ namespace BMapSharp.VirtoolsTypes {
public float X, Y; public float X, Y;
public VxVector2(float _x = 0.0f, float _y = 0.0f) { public VxVector2(float _x = 0.0f, float _y = 0.0f) {
X = _x; X = _x; Y = _y;
Y = _y;
} }
public VxVector2(Vector2 vec) {
FromManaged(vec);
}
public void FromManaged(Vector2 vec) { public void FromManaged(Vector2 vec) {
X = vec.X; X = vec.X; Y = vec.Y;
Y = vec.Y;
} }
public Vector2 ToManaged() { public Vector2 ToManaged() {
return new Vector2(X, Y); return new Vector2(X, Y);
@ -33,14 +35,14 @@ namespace BMapSharp.VirtoolsTypes {
public float X, Y, Z; public float X, Y, Z;
public VxVector3(float _x = 0.0f, float _y = 0.0f, float _z = 0.0f) { public VxVector3(float _x = 0.0f, float _y = 0.0f, float _z = 0.0f) {
X = _x; X = _x; Y = _y; Z = _z;
Y = _y;
Z = _z;
} }
public VxVector3(Vector3 vec) {
FromManaged(vec);
}
public void FromManaged(Vector3 vec) { public void FromManaged(Vector3 vec) {
X = vec.X; X = vec.X; Y = vec.Y; Z = vec.Z;
Y = vec.Y;
Z = vec.Z;
} }
public Vector3 ToManaged() { public Vector3 ToManaged() {
return new Vector3(X, Y, Z); return new Vector3(X, Y, Z);
@ -50,29 +52,31 @@ namespace BMapSharp.VirtoolsTypes {
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)] [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct VxColor { public struct VxColor {
[MarshalAs(UnmanagedType.R4)] [MarshalAs(UnmanagedType.R4)]
public float A, R, G, B; public float R, G, B, A;
public VxColor(float _r, float _g, float _b, float _a) { public VxColor(float _r, float _g, float _b, float _a) {
A = _a; A = _a; R = _r; G = _g; B = _b;
R = _r;
G = _g;
B = _b;
Regulate(); Regulate();
} }
public VxColor(Vector4 col) {
FromManagedRGBA(col);
}
public VxColor(Vector3 col) {
FromManagedRGB(col);
}
public VxColor(uint val) {
FromDword(val);
}
public void FromManagedRGBA(Vector4 col) { public void FromManagedRGBA(Vector4 col) {
R = col.X; R = col.X; G = col.Y; B = col.Z; A = col.W;
G = col.Y;
B = col.Z;
A = col.W;
Regulate(); Regulate();
} }
public Vector4 ToManagedRGBA() { public Vector4 ToManagedRGBA() {
return new Vector4(R, G, B, A); return new Vector4(R, G, B, A);
} }
public void FromManagedRGB(Vector3 col) { public void FromManagedRGB(Vector3 col) {
R = col.X; R = col.X; G = col.Y; B = col.Z; A = 1.0f;
G = col.Y;
B = col.Z;
Regulate(); Regulate();
} }
public Vector3 ToManagedRGB() { public Vector3 ToManagedRGB() {
@ -101,6 +105,7 @@ namespace BMapSharp.VirtoolsTypes {
val |= (uint)(B * 255.0f); val |= (uint)(B * 255.0f);
return val; return val;
} }
public static float ClampFactor(float factor) { public static float ClampFactor(float factor) {
return System.Math.Clamp(factor, 0.0f, 1.0f); return System.Math.Clamp(factor, 0.0f, 1.0f);
} }
@ -166,6 +171,18 @@ namespace BMapSharp.VirtoolsTypes {
} }
} }
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct CKShortFaceIndices {
[MarshalAs(UnmanagedType.U2)]
public ushort I1, I2, I3;
public CKShortFaceIndices(ushort i1 = 0, ushort i2 = 0, ushort i3 = 0) {
I1 = i1;
I2 = i2;
I3 = i3;
}
}
public enum CK_TEXTURE_SAVEOPTIONS : uint { public enum CK_TEXTURE_SAVEOPTIONS : uint {
CKTEXTURE_RAWDATA = 0, /**< Save raw data inside file. The bitmap is saved in a raw 32 bit per pixel format. */ CKTEXTURE_RAWDATA = 0, /**< Save raw data inside file. The bitmap is saved in a raw 32 bit per pixel format. */
CKTEXTURE_EXTERNAL = 1, /**< Store only the file name for the texture. The bitmap file must be present in the bitmap paths when loading the composition. */ CKTEXTURE_EXTERNAL = 1, /**< Store only the file name for the texture. The bitmap file must be present in the bitmap paths when loading the composition. */
@ -209,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

@ -1,10 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\BMapSharp\BMapSharp.csproj" />
</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>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -1,12 +1,219 @@
using BMapSharp.BMapWrapper;
using System; using System;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.CommandLine;
namespace BMapSharpTestbench {
internal class Program {
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
Console.OutputEncoding = Encoding.UTF8;
if (!BMapSharp.BMapWrapper.Utils.IsBMapAvailable()) {
Console.WriteLine("Fail to initialize native BMap.");
Environment.Exit(0);
}
// Waiting debugger
int pid = System.Diagnostics.Process.GetCurrentProcess().Id;
Console.WriteLine($"C# PID is {pid}. Waiting debugger, press any key to continue...");
Console.ReadKey(true);
// Start testbench
string file_name = resolved_args.mFileName; // "LightCameraTest.nmo";
string temp_folder = resolved_args.mTempFolder; // "Temp";
string texture_folder = resolved_args.mTextureFolder; // "F:\\Ballance\\Ballance\\Textures";
string[] encodings = resolved_args.mEncodings; // ["cp1252", "gb2312"];
using (var reader = new BMapSharp.BMapWrapper.BMFileReader(file_name, temp_folder, texture_folder, encodings)) {
TestCommon(reader);
TestIEquatable(reader);
}
Console.WriteLine("Press any key to quit...");
Console.ReadKey(true);
namespace BMapSharpTestbench // Note: actual namespace depends on the project name.
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
} }
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) {
// Console.WriteLine("===== Groups =====");
// foreach (var gp in reader.GetGroups()) {
// Console.WriteLine(gp.GetName());
// foreach (var gp_item in gp.GetObjects()) {
// Console.WriteLine($"\t{gp_item.GetName()}");
// }
// }
// Console.WriteLine("===== 3dObjects =====");
// foreach (var obj in reader.Get3dObjects()) {
// Console.WriteLine(obj.GetName());
// var current_mesh = obj.GetCurrentMesh();
// var mesh_name = current_mesh is null ? "<null>" : current_mesh.GetName();
// Console.WriteLine($"\tMesh: {mesh_name}");
// Console.WriteLine($"\tVisibility: {obj.GetVisibility()}");
// Console.WriteLine($"\tMatrix: {obj.GetWorldMatrix().ToManaged()}");
// }
// Console.WriteLine("===== Meshes =====");
// foreach (var mesh in reader.GetMeshes()) {
// Console.WriteLine(mesh.GetName());
// Console.WriteLine($"\tLit Mode: {mesh.GetLitMode()}");
// Console.WriteLine($"\tVertex Count: {mesh.GetVertexCount()}");
// Console.WriteLine($"\tFace Count: {mesh.GetFaceCount()}");
// Console.WriteLine($"\tMaterial Slot Count: {mesh.GetMaterialSlotCount()}");
// }
// Console.WriteLine("===== Materials =====");
// foreach (var mtl in reader.GetMaterials()) {
// Console.WriteLine(mtl.GetName());
// Console.WriteLine($"\tDiffuse: {mtl.GetDiffuse().ToManagedRGBA()}");
// Console.WriteLine($"\tAmbient: {mtl.GetAmbient().ToManagedRGBA()}");
// Console.WriteLine($"\tSpecular: {mtl.GetSpecular().ToManagedRGBA()}");
// Console.WriteLine($"\tEmissive: {mtl.GetEmissive().ToManagedRGBA()}");
// Console.WriteLine($"\tSpecular Power: {mtl.GetSpecularPower()}");
// Console.WriteLine($"\tTexture Border Color: {mtl.GetTextureBorderColor().ToManagedRGBA()}");
// Console.WriteLine($"\tTexture Blend Mode: {mtl.GetTextureBlendMode()}");
// Console.WriteLine($"\tTexture Min Mode: {mtl.GetTextureMinMode()}");
// Console.WriteLine($"\tTexture Mag Mode: {mtl.GetTextureMagMode()}");
// Console.WriteLine($"\tSource Blend: {mtl.GetSourceBlend()}");
// Console.WriteLine($"\tDest Blend: {mtl.GetDestBlend()}");
// Console.WriteLine($"\tFill Mode: {mtl.GetFillMode()}");
// Console.WriteLine($"\tShade Mode: {mtl.GetShadeMode()}");
// Console.WriteLine($"\tAlpha Test Enabled: {mtl.GetAlphaTestEnabled()}");
// Console.WriteLine($"\tAlpha Blend Enabled: {mtl.GetAlphaBlendEnabled()}");
// Console.WriteLine($"\tPerspective Correction Enabled: {mtl.GetPerspectiveCorrectionEnabled()}");
// Console.WriteLine($"\tZ Write Enabled: {mtl.GetZWriteEnabled()}");
// Console.WriteLine($"\tTwo Sided Enabled: {mtl.GetTwoSidedEnabled()}");
// Console.WriteLine($"\tAlpha Ref: {mtl.GetAlphaRef()}");
// Console.WriteLine($"\tAlpha Func: {mtl.GetAlphaFunc()}");
// Console.WriteLine($"\tZ Func: {mtl.GetZFunc()}");
// }
// Console.WriteLine("===== Textures =====");
// foreach (var tex in reader.GetTextures()) {
// Console.WriteLine(tex.GetName());
// Console.WriteLine($"\tFile Name: {tex.GetFileName()}");
// Console.WriteLine($"\tSave Options: {tex.GetSaveOptions()}");
// 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 =====");
}
static void TestIEquatable(BMapSharp.BMapWrapper.BMFileReader reader) {
if (reader.Get3dObjectCount() < 2u) {
Debug.Fail(
"Invalid file for test IEquatable.",
"We can not perform IEquatable test because the length of 3dObject is too short (must greater than 2). Please choose another file to perform."
);
return;
}
// Prepare test variables
var all_3dobjects = new List<BM3dObject>(reader.Get3dObjects());
var first_3dobj = all_3dobjects[0];
var second_3dobj = all_3dobjects[1];
all_3dobjects = new List<BM3dObject>(reader.Get3dObjects());
var first_3dobj_again = all_3dobjects[0];
Debug.Assert(!Object.ReferenceEquals(first_3dobj, first_3dobj_again));
// Hashtable test
var test_hashset = new HashSet<BM3dObject>();
Debug.Assert(test_hashset.Add(first_3dobj));
Debug.Assert(!test_hashset.Add(first_3dobj_again));
Debug.Assert(test_hashset.Add(second_3dobj));
// Dictionary test
var test_dictionary = new Dictionary<BM3dObject, string>();
Debug.Assert(test_dictionary.TryAdd(first_3dobj, first_3dobj.GetName()));
Debug.Assert(!test_dictionary.TryAdd(first_3dobj_again, first_3dobj_again.GetName()));
Debug.Assert(test_dictionary.TryAdd(second_3dobj, second_3dobj.GetName()));
}
} }
} }

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 #####

File diff suppressed because it is too large Load Diff

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,35 +1,178 @@
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:
print('===== Groups =====') test_common(reader)
for gp in reader.get_groups(): test_equatable(reader)
print(gp.get_name())
print('===== Objects =====') def test_common(reader: bmap.BMFileReader):
for obj in reader.get_3dobjects(): # print('===== Groups =====')
print(obj.get_name()) # for gp in reader.get_groups():
# print(gp.get_name())
# for gp_item in gp.get_objects():
# print(f'\t{gp_item.get_name()}')
# print('===== 3dObjects =====')
# for obj in reader.get_3dobjects():
# print(obj.get_name())
# current_mesh = obj.get_current_mesh()
# mesh_name = '<null>' if current_mesh is None else current_mesh.get_name()
# print(f'\tMesh: {mesh_name}')
# print(f'\tVisibility: {obj.get_visibility()}')
# print(f'\tMatrix: {obj.get_world_matrix().to_const()}')
# print('===== Meshes =====')
# for mesh in reader.get_meshs():
# print(mesh.get_name())
# print(f'\tLit Mode: {mesh.get_lit_mode()}')
# print(f'\tVertex Count: {mesh.get_vertex_count()}')
# print(f'\tFace Count: {mesh.get_face_count()}')
# print(f'\tMaterial Slot Count: {mesh.get_material_slot_count()}')
# print('===== Materials =====')
# for mtl in reader.get_materials():
# print(mtl.get_name())
print('===== Meshes =====') # print(f'\tDiffuse: {mtl.get_diffuse().to_const_rgba()}')
for mesh in reader.get_meshs(): # print(f'\tAmbient: {mtl.get_ambient().to_const_rgba()}')
print(mesh.get_name()) # print(f'\tSpecular: {mtl.get_specular().to_const_rgba()}')
# print(f'\tEmissive: {mtl.get_emissive().to_const_rgba()}')
print('===== Materials =====') # print(f'\tSpecular Power: {mtl.get_specular_power()}')
for mtl in reader.get_materials():
print(mtl.get_name())
print('===== Textures =====') # print(f'\tTexture Border Color: {mtl.get_texture_border_color().to_const_rgba()}')
for tex in reader.get_textures():
print(tex.get_name()) # print(f'\tTexture Blend Mode: {mtl.get_texture_blend_mode()}')
# print(f'\tTexture Min Mode: {mtl.get_texture_min_mode()}')
# print(f'\tTexture Mag Mode: {mtl.get_texture_mag_mode()}')
# print(f'\tSource Blend: {mtl.get_source_blend()}')
# print(f'\tDest Blend: {mtl.get_dest_blend()}')
# print(f'\tFill Mode: {mtl.get_fill_mode()}')
# print(f'\tShade Mode: {mtl.get_shade_mode()}')
# print(f'\tAlpha Test Enabled: {mtl.get_alpha_test_enabled()}')
# print(f'\tAlpha Blend Enabled: {mtl.get_alpha_blend_enabled()}')
# print(f'\tPerspective Correction Enabled: {mtl.get_perspective_correction_enabled()}')
# print(f'\tZ Write Enabled: {mtl.get_z_write_enabled()}')
# print(f'\tTwo Sided Enabled: {mtl.get_two_sided_enabled()}')
# print(f'\tAlpha Ref: {mtl.get_alpha_ref()}')
# print(f'\tAlpha Func: {mtl.get_alpha_func()}')
# print(f'\tZ Func: {mtl.get_z_func()}')
# print('===== Textures =====')
# for tex in reader.get_textures():
# print(tex.get_name())
# print(f'\tFile Name: {tex.get_file_name()}')
# print(f'\tSave Options: {tex.get_save_options()}')
# 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):
# Check requirements
assert (reader.get_3dobject_count() >= 2), '''
Invalid file for test IEquatable.
We can not perform IEquatable test because the length of 3dObject is too short (must greater than 2). Please choose another file to perform.
'''
# Prepare variables
all_3dobjects: tuple[bmap.BM3dObject, ...] = tuple(reader.get_3dobjects())
first_3dobj: bmap.BM3dObject = all_3dobjects[0]
second_3dobj: bmap.BM3dObject = all_3dobjects[1]
all_3dobjects = tuple(reader.get_3dobjects())
first_3dobj_again: bmap.BM3dObject = all_3dobjects[0]
# Test set
test_set: set[bmap.BM3dObject] = set()
test_set.add(first_3dobj)
assert len(test_set) == 1
assert first_3dobj in test_set
assert first_3dobj_again in test_set
assert second_3dobj not in test_set
test_set.add(first_3dobj_again)
assert len(test_set) == 1
test_set.add(second_3dobj)
assert len(test_set) == 2
assert second_3dobj in test_set
# Test dict
test_dict: dict[bmap.BM3dObject, str | None] = {}
test_dict[first_3dobj] = first_3dobj.get_name()
assert len(test_dict) == 1
assert first_3dobj in test_dict
assert first_3dobj_again in test_dict
assert second_3dobj not in test_dict
test_dict[first_3dobj_again] = first_3dobj_again.get_name()
assert len(test_dict) == 1
test_dict[second_3dobj] = second_3dobj.get_name()
assert len(test_dict) == 2
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))

6
CMake/VTVersion.hpp.in Normal file
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

@ -6,6 +6,10 @@ endif()
# Find YYCC library # Find YYCC library
# It will produce YYCC::YYCCommonplace target for including and linking. # It will produce YYCC::YYCCommonplace target for including and linking.
find_package(YYCCommonplace REQUIRED #
HINTS ${YYCC_PATH} NO_DEFAULT_PATH # 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,6 +1,6 @@
cmake_minimum_required(VERSION 3.23) cmake_minimum_required(VERSION 3.23)
project(NeMo project(NeMo
VERSION 0.2.0 VERSION 0.3.0
LANGUAGES CXX LANGUAGES CXX
) )
@ -53,7 +53,7 @@ endif ()
install(EXPORT LibCmoTargets install(EXPORT LibCmoTargets
FILE LibCmoTargets.cmake FILE LibCmoTargets.cmake
NAMESPACE NeMo:: NAMESPACE NeMo::
DESTINATION ${YYCC_INSTALL_LIB_PATH}/cmake/LibCmo DESTINATION ${NEMO_INSTALL_LIB_PATH}/cmake/LibCmo
) )
# Package configuration file # Package configuration file
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
@ -65,7 +65,7 @@ write_basic_package_version_file(
configure_package_config_file( configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/CMake/LibCmoConfig.cmake.in ${CMAKE_CURRENT_LIST_DIR}/CMake/LibCmoConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LibCmo INSTALL_DESTINATION ${NEMO_INSTALL_LIB_PATH}/cmake/LibCmo
) )
# Copy package files to install destination # Copy package files to install destination
install( install(
@ -73,5 +73,5 @@ FILES
"${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfigVersion.cmake" "${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfigVersion.cmake"
DESTINATION DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/LibCmo ${NEMO_INSTALL_LIB_PATH}/cmake/LibCmo
) )

83
COMPILE.md Normal file
View File

@ -0,0 +1,83 @@
# Compile Manual
## Requirements
This project require:
* CMake 3.23 at least.
* The common compiler supporting C++ 20 (GCC / Clang / MSVC).
* Littile-endian architecture system.
* zlib.
* iconv (non-Windows system required).
* [stb](https://github.com/nothings/stb): For image read and write.
* [YYCCommonplace](https://github.com/yyc12345/YYCCommonplace): My personal invented library concentrating some common functions for mine.
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
### 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:
* 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.
* 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.
After configuring, you can normally build YYCCommonplace like a common CMake project.
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
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.
### zlib
If you are in Windows, you should download zlib source code and build it with given Visual Studio solution files. The final file we needed is `zlibwapi.dll` with `ZlibDllRelease` build type.
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
### Directory Hierarchy
First, create subdirectory `Bin/build` and `Bin/install` at the root directory of libcmo21.
### Configuration
Then enter subdirectory `Bin/build` and use following command to configure CMake:
- 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> ../..`
- 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> ../..`
The arguments in command should be replaced by:
* `<path-to-stb>`: The root directory of your cloned stb repository.
* `<path-to-yycc-install>`: The directory to installed CMake package you chosen when building YYCCommonplace.
* `<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:
* `NEMO_BUILD_UNVIRT`: Build `Unvirt`, a command line application debugging Virtools files.
* `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.
* `NEMO_BUILD_DOC`: Build the document of libcmo21.
### Build
Execute following command to build libcmo21.
* Windows: `cmake --build . --config RelWithDebInfo`
* non-Windows: `cmake --build .`
### Build Type
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.
## Install
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.
## Note
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.

View File

@ -45,14 +45,22 @@ public class CSharpWriter {
// use "switch" to check variable type // use "switch" to check variable type
switch (vt_base_type) { switch (vt_base_type) {
case "CKSTRING": case "CKSTRING":
// decide direction cookies
String direction_cookie = "";
if (paramdecl.mIsInput) {
direction_cookie = "In";
} else {
direction_cookie = "Out";
}
// only allow 0 and 1 pointer level for string. // only allow 0 and 1 pointer level for string.
switch (vt_pointer_level) { switch (vt_pointer_level) {
case 0: case 0:
ret.mMarshalAs = "UnmanagedType.LPUTF8Str"; ret.mMarshalAs = "UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = \"" + direction_cookie + "\"";
// ret.mMarshalAs = "UnmanagedType.LPUTF8Str";
ret.mCsType = "string"; ret.mCsType = "string";
break; break;
case 1: case 1:
ret.mMarshalAs = "UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringArrayMarshaler)"; ret.mMarshalAs = "UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringArrayMarshaler), MarshalCookie = \"" + direction_cookie + "\"";
ret.mCsType = "string[]"; ret.mCsType = "string[]";
break; break;
} }
@ -110,6 +118,7 @@ public class CSharpWriter {
ret.mMarshalAs = "UnmanagedType.SysInt"; ret.mMarshalAs = "UnmanagedType.SysInt";
ret.mCsType = "IntPtr"; ret.mCsType = "IntPtr";
} }
break;
case "CK_ID": case "CK_ID":
if (vt_pointer_level == 0) { if (vt_pointer_level == 0) {
ret.mMarshalAs = "UnmanagedType.U4"; ret.mMarshalAs = "UnmanagedType.U4";
@ -179,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":
@ -187,11 +197,14 @@ public class CSharpWriter {
case "VXSHADE_MODE": case "VXSHADE_MODE":
case "VXCMPFUNC": case "VXCMPFUNC":
case "VXMESH_LITMODE": case "VXMESH_LITMODE":
// all enum share the same underlying type. // all enum type use the same strategy
if (vt_pointer_level == 0) { if (vt_pointer_level == 0) {
// all enum type should be marshaled as its underlying type
// but we can use its name in C# directly.
ret.mMarshalAs = "UnmanagedType.U4"; ret.mMarshalAs = "UnmanagedType.U4";
ret.mCsType = "uint"; ret.mCsType = vt_base_type;
} else { } else {
// for pointer type, use IntPtr instead.
ret.mMarshalAs = "UnmanagedType.SysInt"; ret.mMarshalAs = "UnmanagedType.SysInt";
ret.mCsType = "IntPtr"; ret.mCsType = "IntPtr";
} }

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

@ -14,5 +14,6 @@ add_custom_target (NeMoDocuments
# Install built documentation # Install built documentation
install (DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html install (DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html
CONFIGURATIONS Release RelWithDebInfo MinSizeRel
DESTINATION ${NEMO_INSTALL_DOC_PATH} DESTINATION ${NEMO_INSTALL_DOC_PATH}
) )

View File

@ -521,7 +521,7 @@ namespace LibCmo::CK2 {
m_Slots.resize(count); m_Slots.resize(count);
if (count == 0) { if (count == 0) {
EnumsHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_INVALID); YYCC::EnumHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_INVALID);
} }
} }
@ -535,8 +535,8 @@ namespace LibCmo::CK2 {
m_CurrentSlot = slot; m_CurrentSlot = slot;
// NOTE: idk what the fuck this is. just interpter the IDA decompiled code. // NOTE: idk what the fuck this is. just interpter the IDA decompiled code.
if (EnumsHelper::Has(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP)) { if (YYCC::EnumHelper::Has(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP)) {
EnumsHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_FORCERESTORE); YYCC::EnumHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_FORCERESTORE);
} }
} }
@ -660,14 +660,14 @@ namespace LibCmo::CK2 {
// but we decide split the flag settings and slot. // but we decide split the flag settings and slot.
// User should set slot count manually. // User should set slot count manually.
if (is_cube) { if (is_cube) {
EnumsHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP); YYCC::EnumHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP);
} else { } else {
EnumsHelper::Rm(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP); YYCC::EnumHelper::Remove(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP);
} }
} }
bool CKBitmapData::IsCubeMap() const { bool CKBitmapData::IsCubeMap() const {
return EnumsHelper::Has(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP); return YYCC::EnumHelper::Has(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP);
} }
const CKBitmapProperties& CKBitmapData::GetSaveFormat() const { const CKBitmapProperties& CKBitmapData::GetSaveFormat() const {
@ -688,14 +688,14 @@ namespace LibCmo::CK2 {
void CKBitmapData::SetTransparent(bool Transparency) { void CKBitmapData::SetTransparent(bool Transparency) {
if (Transparency) { if (Transparency) {
EnumsHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_TRANSPARENT); YYCC::EnumHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_TRANSPARENT);
} else { } else {
EnumsHelper::Rm(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_TRANSPARENT); YYCC::EnumHelper::Remove(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_TRANSPARENT);
} }
} }
bool CKBitmapData::IsTransparent() const { bool CKBitmapData::IsTransparent() const {
return EnumsHelper::Has(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_TRANSPARENT); return YYCC::EnumHelper::Has(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_TRANSPARENT);
} }
void CKBitmapData::SetTransparentColor(CKDWORD col) { void CKBitmapData::SetTransparentColor(CKDWORD col) {

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());
@ -205,8 +234,8 @@ namespace LibCmo::CK2 {
std::string name_conv; std::string name_conv;
// ========== compress feature process ========== // ========== compress feature process ==========
if (EnumsHelper::Has(this->m_FileInfo.FileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) || if (YYCC::EnumHelper::Has(this->m_FileInfo.FileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) ||
EnumsHelper::Has(this->m_FileInfo.FileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) { YYCC::EnumHelper::Has(this->m_FileInfo.FileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
void* decomp_buffer = CKUnPackData(this->m_FileInfo.DataUnPackSize, parser->GetPtr(), this->m_FileInfo.DataPackSize); void* decomp_buffer = CKUnPackData(this->m_FileInfo.DataUnPackSize, parser->GetPtr(), this->m_FileInfo.DataPackSize);
if (decomp_buffer != nullptr) { if (decomp_buffer != nullptr) {
@ -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

@ -216,8 +216,8 @@ namespace LibCmo::CK2 {
} }
// compress header if needed // compress header if needed
if (EnumsHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) || if (YYCC::EnumHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) ||
EnumsHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) { YYCC::EnumHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
CKDWORD comp_buf_size = 0; CKDWORD comp_buf_size = 0;
void* comp_buffer = CKPackData(hdrparser->GetBase(), hdrparser->GetSize(), comp_buf_size, m_Ctx->GetCompressionLevel()); void* comp_buffer = CKPackData(hdrparser->GetBase(), hdrparser->GetSize(), comp_buf_size, m_Ctx->GetCompressionLevel());
@ -263,8 +263,8 @@ namespace LibCmo::CK2 {
} }
// compress header if needed // compress header if needed
if (EnumsHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) || if (YYCC::EnumHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) ||
EnumsHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) { YYCC::EnumHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
CKDWORD comp_buf_size = 0; CKDWORD comp_buf_size = 0;
void* comp_buffer = CKPackData(datparser->GetBase(), datparser->GetSize(), comp_buf_size, m_Ctx->GetCompressionLevel()); void* comp_buffer = CKPackData(datparser->GetBase(), datparser->GetSize(), comp_buf_size, m_Ctx->GetCompressionLevel());

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

@ -419,23 +419,23 @@ namespace LibCmo::CK2 {
std::memcpy(this->m_pData, dwbuf + bufpos, sizeof(CKDWORD) * this->m_DataDwSize); std::memcpy(this->m_pData, dwbuf + bufpos, sizeof(CKDWORD) * this->m_DataDwSize);
bufpos += this->m_DataDwSize; bufpos += this->m_DataDwSize;
} }
if (!EnumsHelper::Has(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_FILE)) { if (!YYCC::EnumHelper::Has(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_FILE)) {
// forced no bind file // forced no bind file
this->m_BindFile = nullptr; this->m_BindFile = nullptr;
} }
if (EnumsHelper::Has(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_IDS)) { if (YYCC::EnumHelper::Has(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_IDS)) {
this->m_ObjectList.resize(dwbuf[bufpos]); this->m_ObjectList.resize(dwbuf[bufpos]);
bufpos += 1u; bufpos += 1u;
std::memcpy(this->m_ObjectList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ObjectList.size()); std::memcpy(this->m_ObjectList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ObjectList.size());
bufpos += this->m_ObjectList.size(); bufpos += this->m_ObjectList.size();
} }
if (EnumsHelper::Has(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_CHN)) { if (YYCC::EnumHelper::Has(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_CHN)) {
this->m_ChunkList.resize(dwbuf[bufpos]); this->m_ChunkList.resize(dwbuf[bufpos]);
bufpos += 1u; bufpos += 1u;
std::memcpy(this->m_ChunkList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ChunkList.size()); std::memcpy(this->m_ChunkList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ChunkList.size());
bufpos += this->m_ChunkList.size(); bufpos += this->m_ChunkList.size();
} }
if (EnumsHelper::Has(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_MAN)) { if (YYCC::EnumHelper::Has(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_MAN)) {
this->m_ManagerList.resize(dwbuf[bufpos]); this->m_ManagerList.resize(dwbuf[bufpos]);
bufpos += 1u; bufpos += 1u;
std::memcpy(this->m_ManagerList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ManagerList.size()); std::memcpy(this->m_ManagerList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ManagerList.size());
@ -459,19 +459,19 @@ namespace LibCmo::CK2 {
if (!m_ObjectList.empty()) { if (!m_ObjectList.empty()) {
size += CKSizeof(CKDWORD) * static_cast<CKDWORD>(m_ObjectList.size()) + sizeof(CKDWORD); size += CKSizeof(CKDWORD) * static_cast<CKDWORD>(m_ObjectList.size()) + sizeof(CKDWORD);
EnumsHelper::Add(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_IDS); YYCC::EnumHelper::Add(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_IDS);
} }
if (!m_ChunkList.empty()) { if (!m_ChunkList.empty()) {
size += CKSizeof(CKDWORD) * static_cast<CKDWORD>(m_ChunkList.size()) + sizeof(CKDWORD); size += CKSizeof(CKDWORD) * static_cast<CKDWORD>(m_ChunkList.size()) + sizeof(CKDWORD);
EnumsHelper::Add(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_CHN); YYCC::EnumHelper::Add(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_CHN);
} }
if (!m_ManagerList.empty()) { if (!m_ManagerList.empty()) {
size += CKSizeof(CKDWORD) * static_cast<CKDWORD>(m_ManagerList.size()) + sizeof(CKDWORD); size += CKSizeof(CKDWORD) * static_cast<CKDWORD>(m_ManagerList.size()) + sizeof(CKDWORD);
EnumsHelper::Add(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_MAN); YYCC::EnumHelper::Add(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_MAN);
} }
if (this->m_BindFile != nullptr) { if (this->m_BindFile != nullptr) {
EnumsHelper::Add(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_FILE); YYCC::EnumHelper::Add(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_FILE);
} }
// if buffer provided, write it // if buffer provided, write it

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

@ -86,7 +86,7 @@ namespace LibCmo::CK2::MgrImpls {
// set to be deleted // set to be deleted
CK_OBJECT_FLAGS objflag = obj->GetObjectFlags(); CK_OBJECT_FLAGS objflag = obj->GetObjectFlags();
EnumsHelper::Add(objflag, CK_OBJECT_FLAGS::CK_OBJECT_TOBEDELETED); YYCC::EnumHelper::Add(objflag, CK_OBJECT_FLAGS::CK_OBJECT_TOBEDELETED);
obj->SetObjectFlags(objflag); obj->SetObjectFlags(objflag);
// collect class id // collect class id

View File

@ -9,12 +9,12 @@ namespace LibCmo::CK2::ObjImpls {
CKRenderObject(ctx, ckid, name), CKRenderObject(ctx, ckid, name),
m_PotentialMeshes(), m_CurrentMesh(nullptr), m_PotentialMeshes(), m_CurrentMesh(nullptr),
m_WorldMatrix(), m_ZOrder(0), m_WorldMatrix(), m_ZOrder(0),
m_MoveableFlags(EnumsHelper::Merge({ m_MoveableFlags(YYCC::EnumHelper::Merge(
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_PICKABLE, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_PICKABLE,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_RENDERCHANNELS, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_RENDERCHANNELS,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_INVERSEWORLDMATVALID VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_INVERSEWORLDMATVALID
})), )),
m_3dEntityFlags(static_cast<CK_3DENTITY_FLAGS>(0)) {} m_3dEntityFlags(static_cast<CK_3DENTITY_FLAGS>(0)) {}
CK3dEntity::~CK3dEntity() {} CK3dEntity::~CK3dEntity() {}
@ -53,15 +53,15 @@ namespace LibCmo::CK2::ObjImpls {
// regulate self flag again // regulate self flag again
// MARK: originally we should check parent here. // MARK: originally we should check parent here.
// but we do not support parent and hierarchy feature, so we simply remove flag // but we do not support parent and hierarchy feature, so we simply remove flag
EnumsHelper::Rm(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PARENTVALID); YYCC::EnumHelper::Remove(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PARENTVALID);
// MARK: originally we should check grouped into CKPlace here. // MARK: originally we should check grouped into CKPlace here.
// but we do not support CKPlace, so we simply remove this flag // but we do not support CKPlace, so we simply remove this flag
EnumsHelper::Rm(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PLACEVALID); YYCC::EnumHelper::Remove(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PLACEVALID);
// check z-order, if not zero, save it // check z-order, if not zero, save it
if (m_ZOrder != 0) { if (m_ZOrder != 0) {
EnumsHelper::Add(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_ZORDERVALID); YYCC::EnumHelper::Add(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_ZORDERVALID);
} else { } else {
EnumsHelper::Rm(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_ZORDERVALID); YYCC::EnumHelper::Remove(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_ZORDERVALID);
} }
// write 2 flags // write 2 flags
@ -94,7 +94,7 @@ namespace LibCmo::CK2::ObjImpls {
if (!suc) return false; if (!suc) return false;
// backup moveable flags // backup moveable flags
bool hasWorldAligned = EnumsHelper::Has(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_WORLDALIGNED); bool hasWorldAligned = YYCC::EnumHelper::Has(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_WORLDALIGNED);
// MARK: object animation is skipped // MARK: object animation is skipped
@ -132,11 +132,11 @@ namespace LibCmo::CK2::ObjImpls {
chunk->ReadStruct(m_3dEntityFlags); chunk->ReadStruct(m_3dEntityFlags);
chunk->ReadStruct(m_MoveableFlags); chunk->ReadStruct(m_MoveableFlags);
// remove some properties // remove some properties
EnumsHelper::Rm(m_3dEntityFlags, EnumsHelper::Merge({ YYCC::EnumHelper::Remove(m_3dEntityFlags,
CK_3DENTITY_FLAGS::CK_3DENTITY_UPDATELASTFRAME, CK_3DENTITY_FLAGS::CK_3DENTITY_UPDATELASTFRAME,
CK_3DENTITY_FLAGS::CK_3DENTITY_RESERVED0 CK_3DENTITY_FLAGS::CK_3DENTITY_RESERVED0
})); );
EnumsHelper::Rm(m_MoveableFlags, EnumsHelper::Merge({ YYCC::EnumHelper::Remove(m_MoveableFlags,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_RESERVED2, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_RESERVED2,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_STENCILONLY, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_STENCILONLY,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_DONTUPDATEFROMPARENT, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_DONTUPDATEFROMPARENT,
@ -145,19 +145,19 @@ namespace LibCmo::CK2::ObjImpls {
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_BOXVALID, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_BOXVALID,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_USERBOX, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_USERBOX,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_UPTODATE VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_UPTODATE
})); );
if (hasWorldAligned) { if (hasWorldAligned) {
EnumsHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_WORLDALIGNED); YYCC::EnumHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_WORLDALIGNED);
} }
// if order render first // if order render first
if (EnumsHelper::Has(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_RENDERFIRST)) { if (YYCC::EnumHelper::Has(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_RENDERFIRST)) {
m_ZOrder = 10000; m_ZOrder = 10000;
} }
// 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]));
@ -171,47 +171,47 @@ namespace LibCmo::CK2::ObjImpls {
VxMath::VxVector3 crossProduct = VxMath::NSVxVector::CrossProduct(col0, col1); VxMath::VxVector3 crossProduct = VxMath::NSVxVector::CrossProduct(col0, col1);
CKFLOAT dotProduct = VxMath::NSVxVector::DotProduct(crossProduct, col2); CKFLOAT dotProduct = VxMath::NSVxVector::DotProduct(crossProduct, col2);
if (dotProduct >= 0.0f) { if (dotProduct >= 0.0f) {
EnumsHelper::Rm(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_INDIRECTMATRIX); YYCC::EnumHelper::Remove(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_INDIRECTMATRIX);
} else { } else {
EnumsHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_INDIRECTMATRIX); YYCC::EnumHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_INDIRECTMATRIX);
} }
// copy visible data // copy visible data
// process direct visible // process direct visible
if (EnumsHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE)) { if (YYCC::EnumHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE)) {
EnumsHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE); YYCC::EnumHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE);
} else { } else {
EnumsHelper::Rm(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE); YYCC::EnumHelper::Remove(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE);
} }
// process indirect visible // process indirect visible
if (EnumsHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE)) { if (YYCC::EnumHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE)) {
EnumsHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE); YYCC::EnumHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE);
} else { } else {
EnumsHelper::Rm(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE); YYCC::EnumHelper::Remove(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE);
} }
// read associated CKPlace // read associated CKPlace
if (EnumsHelper::Has(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PLACEVALID)) { if (YYCC::EnumHelper::Has(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PLACEVALID)) {
// MARK: we drop the support of CKPlace. // MARK: we drop the support of CKPlace.
// so we just read it and skip it. // so we just read it and skip it.
CK_ID placeid; CK_ID placeid;
chunk->ReadObjectID(placeid); chunk->ReadObjectID(placeid);
// and remove this flag // and remove this flag
EnumsHelper::Rm(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PLACEVALID); YYCC::EnumHelper::Remove(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PLACEVALID);
} }
// read parent // read parent
if (EnumsHelper::Has(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PARENTVALID)) { if (YYCC::EnumHelper::Has(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PARENTVALID)) {
// MAKR: we drop the support of parent and the whole 3dentity hierarchy system // MAKR: we drop the support of parent and the whole 3dentity hierarchy system
// we ignore this field. // we ignore this field.
CK_ID parentid; CK_ID parentid;
chunk->ReadObjectID(parentid); chunk->ReadObjectID(parentid);
// and remove this flag // and remove this flag
EnumsHelper::Rm(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PARENTVALID); YYCC::EnumHelper::Remove(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PARENTVALID);
} }
// read priority (non-zero zorder) // read priority (non-zero zorder)
if (EnumsHelper::Has(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_ZORDERVALID)) { if (YYCC::EnumHelper::Has(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_ZORDERVALID)) {
chunk->ReadStruct(m_ZOrder); chunk->ReadStruct(m_ZOrder);
} }
@ -227,16 +227,16 @@ namespace LibCmo::CK2::ObjImpls {
void CK3dEntity::Show(CK_OBJECT_SHOWOPTION show) { void CK3dEntity::Show(CK_OBJECT_SHOWOPTION show) {
CKObject::Show(show); CKObject::Show(show);
EnumsHelper::Rm(m_MoveableFlags, EnumsHelper::Merge({ YYCC::EnumHelper::Remove(m_MoveableFlags,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE
})); );
switch (show) { switch (show) {
case CK_OBJECT_SHOWOPTION::CKSHOW: case CK_OBJECT_SHOWOPTION::CKSHOW:
EnumsHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE); YYCC::EnumHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE);
break; break;
case CK_OBJECT_SHOWOPTION::CKHIERARCHICALHIDE: case CK_OBJECT_SHOWOPTION::CKHIERARCHICALHIDE:
EnumsHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE); YYCC::EnumHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE);
break; break;
case CK_OBJECT_SHOWOPTION::CKHIDE: case CK_OBJECT_SHOWOPTION::CKHIDE:
break; break;

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

@ -21,12 +21,12 @@ namespace LibCmo::CK2::ObjImpls {
m_LineCount(0), m_LineCount(0),
m_LineIndices(), m_LineIndices(),
// init flags // init flags
m_Flags(EnumsHelper::Merge({ m_Flags(YYCC::EnumHelper::Merge(
VxMath::VXMESH_FLAGS::VXMESH_VISIBLE, VxMath::VXMESH_FLAGS::VXMESH_VISIBLE,
VxMath::VXMESH_FLAGS::VXMESH_RENDERCHANNELS VxMath::VXMESH_FLAGS::VXMESH_RENDERCHANNELS
})) { )) {
// set visible in default // set visible in default
EnumsHelper::Add(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE); YYCC::EnumHelper::Add(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
} }
CKMesh::~CKMesh() {} CKMesh::~CKMesh() {}
@ -145,7 +145,7 @@ namespace LibCmo::CK2::ObjImpls {
rawbuf += CKSizeof(CKDWORD); rawbuf += CKSizeof(CKDWORD);
// write vertex position // write vertex position
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::NoPos)) { if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::NoPos)) {
CKDWORD consumed = CKSizeof(VxMath::VxVector3) * vtxCount; CKDWORD consumed = CKSizeof(VxMath::VxVector3) * vtxCount;
std::memcpy(rawbuf, m_VertexPosition.data(), consumed); std::memcpy(rawbuf, m_VertexPosition.data(), consumed);
rawbuf += consumed; rawbuf += consumed;
@ -154,7 +154,7 @@ namespace LibCmo::CK2::ObjImpls {
// write color and specular color // write color and specular color
{ {
CKDWORD consumed = 0; CKDWORD consumed = 0;
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::SingleColor)) { if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::SingleColor)) {
consumed = CKSizeof(CKDWORD) * vtxCount; consumed = CKSizeof(CKDWORD) * vtxCount;
} else { } else {
consumed = CKSizeof(CKDWORD); consumed = CKSizeof(CKDWORD);
@ -165,7 +165,7 @@ namespace LibCmo::CK2::ObjImpls {
} }
{ {
CKDWORD consumed = 0; CKDWORD consumed = 0;
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::SingleSpecularColor)) { if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::SingleSpecularColor)) {
consumed = CKSizeof(CKDWORD) * vtxCount; consumed = CKSizeof(CKDWORD) * vtxCount;
} else { } else {
consumed = CKSizeof(CKDWORD); consumed = CKSizeof(CKDWORD);
@ -176,7 +176,7 @@ namespace LibCmo::CK2::ObjImpls {
} }
// write normal // write normal
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::NoNormal)) { if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::NoNormal)) {
CKDWORD consumed = CKSizeof(VxMath::VxVector3) * vtxCount; CKDWORD consumed = CKSizeof(VxMath::VxVector3) * vtxCount;
std::memcpy(rawbuf, m_VertexNormal.data(), consumed); std::memcpy(rawbuf, m_VertexNormal.data(), consumed);
rawbuf += consumed; rawbuf += consumed;
@ -185,7 +185,7 @@ namespace LibCmo::CK2::ObjImpls {
// write uv // write uv
{ {
CKDWORD consumed = 0; CKDWORD consumed = 0;
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::SingleUV)) { if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::SingleUV)) {
consumed = CKSizeof(VxMath::VxVector2) * vtxCount; consumed = CKSizeof(VxMath::VxVector2) * vtxCount;
} else { } else {
consumed = CKSizeof(VxMath::VxVector2); consumed = CKSizeof(VxMath::VxVector2);
@ -229,13 +229,13 @@ namespace LibCmo::CK2::ObjImpls {
// read flag // read flag
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_MESH::CK_STATESAVE_MESHFLAGS)) { if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_MESH::CK_STATESAVE_MESHFLAGS)) {
chunk->ReadStruct(m_Flags); chunk->ReadStruct(m_Flags);
EnumsHelper::Mask(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_ALLFLAGS); YYCC::EnumHelper::Mask(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_ALLFLAGS);
// I don't know why, just interpter the IDA code. // I don't know why, just interpter the IDA code.
EnumsHelper::Rm(m_Flags, EnumsHelper::Merge({ YYCC::EnumHelper::Remove(m_Flags,
VxMath::VXMESH_FLAGS::VXMESH_BOUNDINGUPTODATE, VxMath::VXMESH_FLAGS::VXMESH_BOUNDINGUPTODATE,
VxMath::VXMESH_FLAGS::VXMESH_OPTIMIZED VxMath::VXMESH_FLAGS::VXMESH_OPTIMIZED
})); );
} }
// read material slots // read material slots
@ -285,14 +285,14 @@ namespace LibCmo::CK2::ObjImpls {
const CKBYTE* rawbuf = static_cast<const CKBYTE*>(buf.get()); const CKBYTE* rawbuf = static_cast<const CKBYTE*>(buf.get());
// copy position if it have // copy position if it have
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::NoPos)) { if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::NoPos)) {
CKDWORD consumed = CKSizeof(VxMath::VxVector3) * vertexCount; CKDWORD consumed = CKSizeof(VxMath::VxVector3) * vertexCount;
std::memcpy(m_VertexPosition.data(), rawbuf, consumed); std::memcpy(m_VertexPosition.data(), rawbuf, consumed);
rawbuf += consumed; rawbuf += consumed;
} }
// copy color or apply single color // copy color or apply single color
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::SingleColor)) { if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::SingleColor)) {
CKDWORD consumed = CKSizeof(CKDWORD) * vertexCount; CKDWORD consumed = CKSizeof(CKDWORD) * vertexCount;
std::memcpy(m_VertexColor.data(), rawbuf, consumed); std::memcpy(m_VertexColor.data(), rawbuf, consumed);
rawbuf += consumed; rawbuf += consumed;
@ -309,7 +309,7 @@ namespace LibCmo::CK2::ObjImpls {
} }
// copy specular color or apply a single color // copy specular color or apply a single color
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::SingleSpecularColor)) { if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::SingleSpecularColor)) {
CKDWORD consumed = CKSizeof(CKDWORD) * vertexCount; CKDWORD consumed = CKSizeof(CKDWORD) * vertexCount;
std::memcpy(m_VertexSpecularColor.data(), rawbuf, consumed); std::memcpy(m_VertexSpecularColor.data(), rawbuf, consumed);
rawbuf += consumed; rawbuf += consumed;
@ -326,14 +326,14 @@ namespace LibCmo::CK2::ObjImpls {
} }
// copy normals if it has // copy normals if it has
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::NoNormal)) { if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::NoNormal)) {
CKDWORD consumed = CKSizeof(VxMath::VxVector3) * vertexCount; CKDWORD consumed = CKSizeof(VxMath::VxVector3) * vertexCount;
std::memcpy(m_VertexNormal.data(), rawbuf, consumed); std::memcpy(m_VertexNormal.data(), rawbuf, consumed);
rawbuf += consumed; rawbuf += consumed;
} }
// copy uv or apply single uv // copy uv or apply single uv
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::SingleUV)) { if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::SingleUV)) {
CKDWORD consumed = CKSizeof(VxMath::VxVector2) * vertexCount; CKDWORD consumed = CKSizeof(VxMath::VxVector2) * vertexCount;
std::memcpy(m_VertexUV.data(), rawbuf, consumed); std::memcpy(m_VertexUV.data(), rawbuf, consumed);
rawbuf += consumed; rawbuf += consumed;
@ -407,7 +407,7 @@ namespace LibCmo::CK2::ObjImpls {
} }
// build normals // build normals
if (EnumsHelper::Has(saveflags, VertexSaveFlags::NoNormal)) { if (YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::NoNormal)) {
BuildNormals(); BuildNormals();
} else { } else {
BuildFaceNormals(); BuildFaceNormals();
@ -425,9 +425,9 @@ namespace LibCmo::CK2::ObjImpls {
CKObject::Show(show); CKObject::Show(show);
if (show == CK_OBJECT_SHOWOPTION::CKSHOW) { if (show == CK_OBJECT_SHOWOPTION::CKSHOW) {
EnumsHelper::Add(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_VISIBLE); YYCC::EnumHelper::Add(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_VISIBLE);
} else { } else {
EnumsHelper::Rm(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_VISIBLE); YYCC::EnumHelper::Remove(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_VISIBLE);
} }
} }
@ -449,15 +449,15 @@ namespace LibCmo::CK2::ObjImpls {
m_Flags = flags; m_Flags = flags;
// sync visibility to CKObject layer. // sync visibility to CKObject layer.
if (EnumsHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_VISIBLE)) { if (YYCC::EnumHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_VISIBLE)) {
EnumsHelper::Add(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE); YYCC::EnumHelper::Add(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
} else { } else {
EnumsHelper::Rm(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE); YYCC::EnumHelper::Remove(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
} }
} }
VxMath::VXMESH_LITMODE CKMesh::GetLitMode() const { VxMath::VXMESH_LITMODE CKMesh::GetLitMode() const {
if (EnumsHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_PRELITMODE)) { if (YYCC::EnumHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_PRELITMODE)) {
return VxMath::VXMESH_LITMODE::VX_PRELITMESH; return VxMath::VXMESH_LITMODE::VX_PRELITMESH;
} else { } else {
return VxMath::VXMESH_LITMODE::VX_LITMESH; return VxMath::VXMESH_LITMODE::VX_LITMESH;
@ -467,10 +467,10 @@ namespace LibCmo::CK2::ObjImpls {
void CKMesh::SetLitMode(VxMath::VXMESH_LITMODE mode) { void CKMesh::SetLitMode(VxMath::VXMESH_LITMODE mode) {
switch (mode) { switch (mode) {
case VxMath::VXMESH_LITMODE::VX_PRELITMESH: case VxMath::VXMESH_LITMODE::VX_PRELITMESH:
EnumsHelper::Add(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_PRELITMODE); YYCC::EnumHelper::Add(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_PRELITMODE);
break; break;
case VxMath::VXMESH_LITMODE::VX_LITMESH: case VxMath::VXMESH_LITMODE::VX_LITMESH:
EnumsHelper::Rm(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_PRELITMODE); YYCC::EnumHelper::Remove(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_PRELITMODE);
break; break;
} }
} }
@ -478,51 +478,51 @@ namespace LibCmo::CK2::ObjImpls {
VxMath::VXTEXTURE_WRAPMODE CKMesh::GetWrapMode() const { VxMath::VXTEXTURE_WRAPMODE CKMesh::GetWrapMode() const {
VxMath::VXTEXTURE_WRAPMODE ret = VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_NONE; VxMath::VXTEXTURE_WRAPMODE ret = VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_NONE;
if (EnumsHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPU)) { if (YYCC::EnumHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPU)) {
EnumsHelper::Add(ret, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_U); YYCC::EnumHelper::Add(ret, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_U);
} }
if (EnumsHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPV)) { if (YYCC::EnumHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPV)) {
EnumsHelper::Add(ret, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_V); YYCC::EnumHelper::Add(ret, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_V);
} }
return ret; return ret;
} }
void CKMesh::SetWrapMode(VxMath::VXTEXTURE_WRAPMODE mode) { void CKMesh::SetWrapMode(VxMath::VXTEXTURE_WRAPMODE mode) {
if (EnumsHelper::Has(mode, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_U)) { if (YYCC::EnumHelper::Has(mode, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_U)) {
EnumsHelper::Add(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPU); YYCC::EnumHelper::Add(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPU);
} else { } else {
EnumsHelper::Rm(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPU); YYCC::EnumHelper::Remove(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPU);
} }
if (EnumsHelper::Has(mode, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_V)) { if (YYCC::EnumHelper::Has(mode, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_V)) {
EnumsHelper::Add(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPV); YYCC::EnumHelper::Add(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPV);
} else { } else {
EnumsHelper::Rm(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPV); YYCC::EnumHelper::Remove(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPV);
} }
} }
CKMesh::VertexSaveFlags CKMesh::GenerateSaveFlags() { CKMesh::VertexSaveFlags CKMesh::GenerateSaveFlags() {
// set to initial status // set to initial status
VertexSaveFlags saveflags = EnumsHelper::Merge({ VertexSaveFlags saveflags = YYCC::EnumHelper::Merge(
VertexSaveFlags::SingleColor, VertexSaveFlags::SingleColor,
VertexSaveFlags::SingleSpecularColor, VertexSaveFlags::SingleSpecularColor,
VertexSaveFlags::NoNormal, VertexSaveFlags::NoNormal,
VertexSaveFlags::SingleUV VertexSaveFlags::SingleUV
}); );
// check no pos // check no pos
// if position is generated, skip saving position // if position is generated, skip saving position
if (EnumsHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_PROCEDURALPOS)) { if (YYCC::EnumHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_PROCEDURALPOS)) {
EnumsHelper::Add(saveflags, VertexSaveFlags::NoPos); YYCC::EnumHelper::Add(saveflags, VertexSaveFlags::NoPos);
} }
// check uv // check uv
// if uv is not generated and all uv are not the same value, remove single uv // if uv is not generated and all uv are not the same value, remove single uv
if (!EnumsHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_PROCEDURALUV)) { if (!YYCC::EnumHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_PROCEDURALUV)) {
for (const auto& uv : m_VertexUV) { for (const auto& uv : m_VertexUV) {
if (uv != m_VertexUV.front()) { if (uv != m_VertexUV.front()) {
EnumsHelper::Rm(saveflags, VertexSaveFlags::SingleUV); YYCC::EnumHelper::Remove(saveflags, VertexSaveFlags::SingleUV);
break; break;
} }
} }
@ -532,19 +532,19 @@ namespace LibCmo::CK2::ObjImpls {
// if all color are not the same value, remove single color // if all color are not the same value, remove single color
for (const auto& col : m_VertexColor) { for (const auto& col : m_VertexColor) {
if (col != m_VertexColor.front()) { if (col != m_VertexColor.front()) {
EnumsHelper::Rm(saveflags, VertexSaveFlags::SingleColor); YYCC::EnumHelper::Remove(saveflags, VertexSaveFlags::SingleColor);
break; break;
} }
} }
for (const auto& col : m_VertexSpecularColor) { for (const auto& col : m_VertexSpecularColor) {
if (col != m_VertexSpecularColor.front()) { if (col != m_VertexSpecularColor.front()) {
EnumsHelper::Rm(saveflags, VertexSaveFlags::SingleSpecularColor); YYCC::EnumHelper::Remove(saveflags, VertexSaveFlags::SingleSpecularColor);
break; break;
} }
} }
// if normal not changed, and position is not generated, we should consider whether we need save normal (step into if) // if normal not changed, and position is not generated, we should consider whether we need save normal (step into if)
if (!EnumsHelper::Has(m_Flags, EnumsHelper::Merge({ VxMath::VXMESH_FLAGS::VXMESH_NORMAL_CHANGED, VxMath::VXMESH_FLAGS::VXMESH_PROCEDURALPOS }))) { if (!YYCC::EnumHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_NORMAL_CHANGED, VxMath::VXMESH_FLAGS::VXMESH_PROCEDURALPOS)) {
// MARK: we should build face normal first // MARK: we should build face normal first
// then we build vertex normal like BuildNormals. // then we build vertex normal like BuildNormals.
// then, we compare the difference between the generated normals and user specified normals, by simply using operator- (userNml - generatedNml) and abs the result. // then, we compare the difference between the generated normals and user specified normals, by simply using operator- (userNml - generatedNml) and abs the result.
@ -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;
} }
@ -581,7 +581,7 @@ namespace LibCmo::CK2::ObjImpls {
accnml /= static_cast<CKFLOAT>(m_VertexCount); accnml /= static_cast<CKFLOAT>(m_VertexCount);
if (accnml.Length() > 0.001f) { if (accnml.Length() > 0.001f) {
// too large difference, we need save normal // too large difference, we need save normal
EnumsHelper::Rm(saveflags, VertexSaveFlags::NoNormal); YYCC::EnumHelper::Remove(saveflags, VertexSaveFlags::NoNormal);
} }
} }

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,23 +16,23 @@ 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) {
m_ObjectFlags = flags; m_ObjectFlags = flags;
} }
bool CKObject::IsToBeDeleted() const { bool CKObject::IsToBeDeleted() const {
return EnumsHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_TOBEDELETED); return YYCC::EnumHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_TOBEDELETED);
} }
CKContext* CKObject::GetCKContext() const { CKContext* CKObject::GetCKContext() const {
return m_Context; return m_Context;
@ -51,10 +51,10 @@ namespace LibCmo::CK2::ObjImpls {
void CKObject::PreSave(CKFileVisitor* file, CKDWORD flags) {} void CKObject::PreSave(CKFileVisitor* file, CKDWORD flags) {}
bool CKObject::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) { bool CKObject::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) {
if (EnumsHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE)) { if (YYCC::EnumHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE)) {
// if hierarchy hidden // if hierarchy hidden
chunk->WriteIdentifier(CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIERAHIDDEN); chunk->WriteIdentifier(CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIERAHIDDEN);
} else if (!EnumsHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE)) { } else if (!YYCC::EnumHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE)) {
// if really hidden // if really hidden
chunk->WriteIdentifier(CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIDDEN); chunk->WriteIdentifier(CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIDDEN);
} }
@ -65,18 +65,20 @@ namespace LibCmo::CK2::ObjImpls {
bool CKObject::Load(CKStateChunk* chunk, CKFileVisitor* file) { bool CKObject::Load(CKStateChunk* chunk, CKFileVisitor* file) {
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIDDEN)) { if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIDDEN)) {
EnumsHelper::Rm(this->m_ObjectFlags, YYCC::EnumHelper::Remove(this->m_ObjectFlags,
EnumsHelper::Merge({ CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE })); CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE,
CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE
);
} else { } else {
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIERAHIDDEN)) { if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIERAHIDDEN)) {
// != 0 // != 0
EnumsHelper::Rm(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE); YYCC::EnumHelper::Remove(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
EnumsHelper::Add(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE); YYCC::EnumHelper::Add(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE);
} else { } else {
// == 0 // == 0
EnumsHelper::Add(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE); YYCC::EnumHelper::Add(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
EnumsHelper::Rm(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE); YYCC::EnumHelper::Remove(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE);
} }
} }
@ -89,17 +91,17 @@ namespace LibCmo::CK2::ObjImpls {
void CKObject::Show(CK_OBJECT_SHOWOPTION show) { void CKObject::Show(CK_OBJECT_SHOWOPTION show) {
// clear all visible data of object flags // clear all visible data of object flags
EnumsHelper::Rm(m_ObjectFlags, EnumsHelper::Merge({ YYCC::EnumHelper::Remove(m_ObjectFlags,
CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE,
CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE
})); );
switch (show) { switch (show) {
case CK_OBJECT_SHOWOPTION::CKSHOW: case CK_OBJECT_SHOWOPTION::CKSHOW:
EnumsHelper::Add(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE); YYCC::EnumHelper::Add(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
break; break;
case CK_OBJECT_SHOWOPTION::CKHIERARCHICALHIDE: case CK_OBJECT_SHOWOPTION::CKHIERARCHICALHIDE:
EnumsHelper::Add(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE); YYCC::EnumHelper::Add(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE);
break; break;
case CK_OBJECT_SHOWOPTION::CKHIDE: case CK_OBJECT_SHOWOPTION::CKHIDE:
return; return;
@ -107,7 +109,7 @@ namespace LibCmo::CK2::ObjImpls {
} }
bool CKObject::IsVisible() const { bool CKObject::IsVisible() const {
return EnumsHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE); return YYCC::EnumHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
} }

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

@ -1,3 +1,10 @@
# Configure version file
configure_file(
${CMAKE_CURRENT_LIST_DIR}/../CMake/VTVersion.hpp.in
${CMAKE_CURRENT_LIST_DIR}/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
@ -30,8 +37,13 @@ PRIVATE
CK2/ObjImpls/CKMesh.cpp CK2/ObjImpls/CKMesh.cpp
CK2/ObjImpls/CKObject.cpp CK2/ObjImpls/CKObject.cpp
CK2/ObjImpls/CKTexture.cpp CK2/ObjImpls/CKTexture.cpp
CK2/ObjImpls/CKLight.cpp
CK2/ObjImpls/CKTargetLight.cpp
CK2/ObjImpls/CKCamera.cpp
CK2/ObjImpls/CKTargetCamera.cpp
# VxMath # VxMath
VxMath/VxMemoryMappedFile.cpp VxMath/VxMemoryMappedFile.cpp
VxMath/VxTypes.cpp
VxMath/VxMath.cpp VxMath/VxMath.cpp
# X Container # X Container
XContainer/XTypes.cpp XContainer/XTypes.cpp
@ -42,6 +54,7 @@ PUBLIC
FILE_SET HEADERS FILE_SET HEADERS
FILES FILES
# Asststant header files # Asststant header files
VTVersion.hpp
VTInternal.hpp VTInternal.hpp
VTEncoding.hpp VTEncoding.hpp
VTUtils.hpp VTUtils.hpp
@ -73,6 +86,10 @@ FILES
CK2/ObjImpls/CK3dObject.hpp CK2/ObjImpls/CK3dObject.hpp
CK2/ObjImpls/CKRenderObject.hpp CK2/ObjImpls/CKRenderObject.hpp
CK2/ObjImpls/CKSceneObject.hpp CK2/ObjImpls/CKSceneObject.hpp
CK2/ObjImpls/CKLight.hpp
CK2/ObjImpls/CKTargetLight.hpp
CK2/ObjImpls/CKCamera.hpp
CK2/ObjImpls/CKTargetCamera.hpp
# VxMath # VxMath
VxMath/VxTypes.hpp VxMath/VxTypes.hpp
VxMath/VxMath.hpp VxMath/VxMath.hpp
@ -86,19 +103,15 @@ target_include_directories(LibCmo
PUBLIC PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE
YYCC::YYCCommonplace
ZLIB::ZLIB
stb::stb-image
) )
target_link_libraries(LibCmo target_link_libraries(LibCmo
PRIVATE PUBLIC
YYCC::YYCCommonplace YYCC::YYCCommonplace
PRIVATE
ZLIB::ZLIB ZLIB::ZLIB
stb::stb-image stb::stb-image
) )
if (NOT WIN32) if (NOT WIN32)
target_include_directories(LibCmo PRIVATE Iconv::Iconv)
target_link_libraries(LibCmo PRIVATE Iconv::Iconv) target_link_libraries(LibCmo PRIVATE Iconv::Iconv)
endif () endif ()
# Setup C++ standard # Setup C++ standard

View File

@ -34,6 +34,10 @@
#include "CK2/ObjImpls/CKTexture.hpp" #include "CK2/ObjImpls/CKTexture.hpp"
#include "CK2/ObjImpls/CKMaterial.hpp" #include "CK2/ObjImpls/CKMaterial.hpp"
#include "CK2/ObjImpls/CKMesh.hpp" #include "CK2/ObjImpls/CKMesh.hpp"
#include "CK2/ObjImpls/CKLight.hpp"
#include "CK2/ObjImpls/CKTargetLight.hpp"
#include "CK2/ObjImpls/CKCamera.hpp"
#include "CK2/ObjImpls/CKTargetCamera.hpp"
// CK2 Managers // CK2 Managers
#include "CK2/MgrImpls/CKBaseManager.hpp" #include "CK2/MgrImpls/CKBaseManager.hpp"

View File

@ -2,10 +2,10 @@
#include <map> #include <map>
#if YYCC_OS == YYCC_OS_WINDOWS #if YYCC_OS == YYCC_OS_WINDOWS
#include <WinImportPrefix.hpp> #include <YYCC/WinImportPrefix.hpp>
#include <Windows.h> #include <Windows.h>
#include <fileapi.h> #include <fileapi.h>
#include <WinImportSuffix.hpp> #include <YYCC/WinImportSuffix.hpp>
#else #else
#include <iconv.h> #include <iconv.h>
#endif #endif

View File

@ -36,7 +36,7 @@ namespace LibCmo::EncodingHelper {
* In underlying implementation, it actually is \c nullptr. * In underlying implementation, it actually is \c nullptr.
* Because EncodingToken is just a raw pointer. * Because EncodingToken is just a raw pointer.
*/ */
constexpr EncodingToken INVALID_ENCODING_TOKEN = nullptr; inline constexpr EncodingToken INVALID_ENCODING_TOKEN = nullptr;
/** /**
* @brief Create encoding token by given universal encoding name. * @brief Create encoding token by given universal encoding name.

View File

@ -10,4 +10,4 @@
#define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stb_image_write.h> #include <stb_image_write.h>
#define STB_IMAGE_RESIZE_IMPLEMENTATION #define STB_IMAGE_RESIZE_IMPLEMENTATION
#include <stb_image_resize.h> #include <deprecated/stb_image_resize.h>

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,9 +17,11 @@
* 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.

View File

@ -5,13 +5,14 @@
#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 // Include YYCC helper library and check its version
#include <YYCCommonplace.hpp> #include <YYCCommonplace.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>
#include <type_traits>
#include <initializer_list>
/** /**
* @brief The core namespace of LibCmo project. * @brief The core namespace of LibCmo project.
@ -69,91 +70,4 @@ namespace LibCmo {
#pragma endregion #pragma endregion
/**
* @brief The namespace for convenient C++ enum class logic operations.
* @details
* C++ enum class statement is a modern way to declare enum in C++.
* But it lack essential logic operations which is commonly used by programmer.
* So we create this helper to resolve this issue.
*/
namespace EnumsHelper {
/**
* @brief Merge given enum flags like performing <TT>e1 | e2 | ... | en</TT>
* @tparam TEnum Enum type for processing.
* @param[in] il The list of enum flags to be merged.
* @return The merged enum flag.
*/
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
constexpr TEnum Merge(std::initializer_list<TEnum> il) {
using ut = std::underlying_type_t<TEnum>;
ut result = 0;
for (auto it = il.begin(); it != il.end(); ++it) {
result |= static_cast<ut>(*it);
}
return static_cast<TEnum>(result);
}
/**
* @brief Reverse given enum flags like performing <TT>~(e)</TT>
* @tparam TEnum Enum type for processing.
* @param[in] e The list of enum flags to be inversed.
* @return The inversed enum flag.
*/
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
constexpr TEnum Inv(TEnum e) {
using ut = std::underlying_type_t<TEnum>;
return static_cast<TEnum>(~(static_cast<ut>(e)));
}
/**
* @brief Remove specified enum flags from given enum flags like performing <TT>e1 &= (~e2)</TT>
* @tparam TEnum Enum type for processing.
* @param[in,out] e1 The enum flags to be processed.
* @param[in] e2 The enum flag to be removed.
*/
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
constexpr void Rm(TEnum& e1, TEnum e2) {
using ut = std::underlying_type_t<TEnum>;
e1 = static_cast<TEnum>(static_cast<ut>(e1) & static_cast<ut>(Inv(e2)));
}
/**
* @brief Use specified enum flags to mask given enum flags like performing <TT>e1 &= e2</TT>
* @tparam TEnum Enum type for processing.
* @param[in,out] e1 The enum flags to be masked.
* @param[in] e2 The mask enum flag.
*/
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
constexpr void Mask(TEnum& e1, TEnum e2) {
using ut = std::underlying_type_t<TEnum>;
e1 = static_cast<TEnum>(static_cast<ut>(e1) & static_cast<ut>(e2));
}
/**
* @brief Add specified enum flags to given enum flags like performing <TT>e1 |= e2</TT>
* @tparam TEnum Enum type for processing.
* @param[in,out] e1 The enum flags to be processed.
* @param[in] e2 The enum flag to be added.
*/
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
constexpr void Add(TEnum& e1, TEnum e2) {
using ut = std::underlying_type_t<TEnum>;
e1 = static_cast<TEnum>(static_cast<ut>(e1) | static_cast<ut>(e2));
}
/**
* @brief Check whether given enum flags has specified enum flag like performing <TT>bool(e & probe)</TT>
* @tparam TEnum Enum type for processing.
* @param[in] e1 The enum flags to be checked.
* @param[in] e2 The enum flag for checking.
* @return True if it has, otherwise false.
*/
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
constexpr bool Has(TEnum e1, TEnum e2) {
using ut = std::underlying_type_t<TEnum>;
return static_cast<bool>(static_cast<ut>(e1) & static_cast<ut>(e2));
}
}
} }

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

@ -1,6 +1,6 @@
#include "VxMath.hpp" #include "VxMath.hpp"
#include <cmath> #include <cmath>
#include <stb_image_resize.h> #include <deprecated/stb_image_resize.h>
namespace LibCmo::VxMath { namespace LibCmo::VxMath {
@ -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;

View File

@ -2,9 +2,9 @@
#include "../VTInternal.hpp" #include "../VTInternal.hpp"
#if YYCC_OS == YYCC_OS_WINDOWS #if YYCC_OS == YYCC_OS_WINDOWS
#include <WinImportPrefix.hpp> #include <YYCC/WinImportPrefix.hpp>
#include <Windows.h> #include <Windows.h>
#include <WinImportSuffix.hpp> #include <YYCC/WinImportSuffix.hpp>
#else #else
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>

529
LibCmo/VxMath/VxTypes.cpp Normal file
View File

@ -0,0 +1,529 @@
#include "VxTypes.hpp"
#include <cmath>
namespace LibCmo::VxMath {
#pragma region VxVector2
VxVector2::VxVector2() :x(0.0f), y(0.0f) {}
VxVector2::VxVector2(CKFLOAT _x, CKFLOAT _y) : x(_x), y(_y) {}
CKFLOAT& VxVector2::operator[](size_t i) {
switch (i) {
case 0: return x;
case 1: return y;
default: throw LogicException("Invalid index for VxVector2::operator[].");
}
}
const CKFLOAT& VxVector2::operator[](size_t i) const {
switch (i) {
case 0: return x;
case 1: return y;
default: throw LogicException("Invalid index for VxVector2::operator[].");
}
}
bool VxVector2::operator==(const VxVector2& rhs) const {
return (x == rhs.x && y == rhs.y);
}
auto VxVector2::operator<=>(const VxVector2& rhs) const {
if (auto cmp = x <=> rhs.x; cmp != 0) return cmp;
return y <=> rhs.y;
}
VxVector2 VxVector2::operator+() const {
return *this;
}
VxVector2 VxVector2::operator-() const {
return VxVector2(-x, -y);
}
VxVector2& VxVector2::operator+=(const VxVector2& rhs) {
x += rhs.x;
y += rhs.y;
return *this;
}
VxVector2 operator+(const VxVector2& lhs, const VxVector2& rhs) {
return VxVector2(lhs.x + rhs.x, lhs.y + rhs.y);
}
VxVector2& VxVector2::operator-=(const VxVector2& rhs) {
x -= rhs.x;
y -= rhs.y;
return *this;
}
VxVector2 operator-(const VxVector2& lhs, const VxVector2& rhs) {
return VxVector2(lhs.x - rhs.x, lhs.y - rhs.y);
}
VxVector2& VxVector2::operator*=(CKFLOAT rhs) {
x *= rhs;
y *= rhs;
return *this;
}
VxVector2 operator*(const VxVector2& lhs, CKFLOAT rhs) {
return VxVector2(lhs.x * rhs, lhs.y * rhs);
}
VxVector2 operator*(CKFLOAT lhs, const VxVector2& rhs) {
return VxVector2(lhs * rhs.x, lhs * rhs.y);
}
CKFLOAT operator*(const VxVector2& lhs, const VxVector2& rhs) {
return (lhs.x * rhs.x + lhs.y * rhs.y);
}
VxVector2& VxVector2::operator/=(CKFLOAT rhs) {
if (rhs == 0.0f) return *this;
x /= rhs;
y /= rhs;
return *this;
}
VxVector2 operator/(const VxVector2& lhs, CKFLOAT rhs) {
if (rhs == 0.0f) return VxVector2();
else return VxVector2(lhs.x / rhs, lhs.y / rhs);
}
CKFLOAT VxVector2::SquaredLength() const {
return (x * x + y * y);
}
CKFLOAT VxVector2::Length() const {
return std::sqrt(SquaredLength());
}
void VxVector2::Normalized() {
CKFLOAT len = Length();
if (len == 0.0f) return;
x /= len;
y /= len;
}
VxVector2 VxVector2::Normalize() const {
CKFLOAT len = Length();
if (len == 0.0f) return VxVector2();
else return VxVector2(x / len, y / len);
}
/* ===== BEGIN USER CUSTOM ===== */
/* ===== END USER CUSTOM ===== */
#pragma endregion
#pragma region VxVector3
VxVector3::VxVector3() :x(0.0f), y(0.0f), z(0.0f) {}
VxVector3::VxVector3(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z) : x(_x), y(_y), z(_z) {}
CKFLOAT& VxVector3::operator[](size_t i) {
switch (i) {
case 0: return x;
case 1: return y;
case 2: return z;
default: throw LogicException("Invalid index for VxVector3::operator[].");
}
}
const CKFLOAT& VxVector3::operator[](size_t i) const {
switch (i) {
case 0: return x;
case 1: return y;
case 2: return z;
default: throw LogicException("Invalid index for VxVector3::operator[].");
}
}
bool VxVector3::operator==(const VxVector3& rhs) const {
return (x == rhs.x && y == rhs.y && z == rhs.z);
}
auto VxVector3::operator<=>(const VxVector3& rhs) const {
if (auto cmp = x <=> rhs.x; cmp != 0) return cmp;
if (auto cmp = y <=> rhs.y; cmp != 0) return cmp;
return z <=> rhs.z;
}
VxVector3 VxVector3::operator+() const {
return *this;
}
VxVector3 VxVector3::operator-() const {
return VxVector3(-x, -y, -z);
}
VxVector3& VxVector3::operator+=(const VxVector3& rhs) {
x += rhs.x;
y += rhs.y;
z += rhs.z;
return *this;
}
VxVector3 operator+(const VxVector3& lhs, const VxVector3& rhs) {
return VxVector3(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
}
VxVector3& VxVector3::operator-=(const VxVector3& rhs) {
x -= rhs.x;
y -= rhs.y;
z -= rhs.z;
return *this;
}
VxVector3 operator-(const VxVector3& lhs, const VxVector3& rhs) {
return VxVector3(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
}
VxVector3& VxVector3::operator*=(CKFLOAT rhs) {
x *= rhs;
y *= rhs;
z *= rhs;
return *this;
}
VxVector3 operator*(const VxVector3& lhs, CKFLOAT rhs) {
return VxVector3(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs);
}
VxVector3 operator*(CKFLOAT lhs, const VxVector3& rhs) {
return VxVector3(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);
}
CKFLOAT operator*(const VxVector3& lhs, const VxVector3& rhs) {
return (lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z);
}
VxVector3& VxVector3::operator/=(CKFLOAT rhs) {
if (rhs == 0.0f) return *this;
x /= rhs;
y /= rhs;
z /= rhs;
return *this;
}
VxVector3 operator/(const VxVector3& lhs, CKFLOAT rhs) {
if (rhs == 0.0f) return VxVector3();
else return VxVector3(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs);
}
CKFLOAT VxVector3::SquaredLength() const {
return (x * x + y * y + z * z);
}
CKFLOAT VxVector3::Length() const {
return std::sqrt(SquaredLength());
}
void VxVector3::Normalized() {
CKFLOAT len = Length();
if (len == 0.0f) return;
x /= len;
y /= len;
z /= len;
}
VxVector3 VxVector3::Normalize() const {
CKFLOAT len = Length();
if (len == 0.0f) return VxVector3();
else return VxVector3(x / len, y / len, z / len);
}
/* ===== BEGIN USER CUSTOM ===== */
/* ===== END USER CUSTOM ===== */
#pragma endregion
#pragma region VxVector4
VxVector4::VxVector4() :x(0.0f), y(0.0f), z(0.0f), w(0.0f) {}
VxVector4::VxVector4(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w) : x(_x), y(_y), z(_z), w(_w) {}
CKFLOAT& VxVector4::operator[](size_t i) {
switch (i) {
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: throw LogicException("Invalid index for VxVector4::operator[].");
}
}
const CKFLOAT& VxVector4::operator[](size_t i) const {
switch (i) {
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: throw LogicException("Invalid index for VxVector4::operator[].");
}
}
bool VxVector4::operator==(const VxVector4& rhs) const {
return (x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w);
}
auto VxVector4::operator<=>(const VxVector4& rhs) const {
if (auto cmp = x <=> rhs.x; cmp != 0) return cmp;
if (auto cmp = y <=> rhs.y; cmp != 0) return cmp;
if (auto cmp = z <=> rhs.z; cmp != 0) return cmp;
return w <=> rhs.w;
}
VxVector4 VxVector4::operator+() const {
return *this;
}
VxVector4 VxVector4::operator-() const {
return VxVector4(-x, -y, -z, -w);
}
VxVector4& VxVector4::operator+=(const VxVector4& rhs) {
x += rhs.x;
y += rhs.y;
z += rhs.z;
w += rhs.w;
return *this;
}
VxVector4 operator+(const VxVector4& lhs, const VxVector4& rhs) {
return VxVector4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w);
}
VxVector4& VxVector4::operator-=(const VxVector4& rhs) {
x -= rhs.x;
y -= rhs.y;
z -= rhs.z;
w -= rhs.w;
return *this;
}
VxVector4 operator-(const VxVector4& lhs, const VxVector4& rhs) {
return VxVector4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w);
}
VxVector4& VxVector4::operator*=(CKFLOAT rhs) {
x *= rhs;
y *= rhs;
z *= rhs;
w *= rhs;
return *this;
}
VxVector4 operator*(const VxVector4& lhs, CKFLOAT rhs) {
return VxVector4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs);
}
VxVector4 operator*(CKFLOAT lhs, const VxVector4& rhs) {
return VxVector4(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w);
}
CKFLOAT operator*(const VxVector4& lhs, const VxVector4& rhs) {
return (lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z + lhs.w * rhs.w);
}
VxVector4& VxVector4::operator/=(CKFLOAT rhs) {
if (rhs == 0.0f) return *this;
x /= rhs;
y /= rhs;
z /= rhs;
w /= rhs;
return *this;
}
VxVector4 operator/(const VxVector4& lhs, CKFLOAT rhs) {
if (rhs == 0.0f) return VxVector4();
else return VxVector4(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs);
}
CKFLOAT VxVector4::SquaredLength() const {
return (x * x + y * y + z * z + w * w);
}
CKFLOAT VxVector4::Length() const {
return std::sqrt(SquaredLength());
}
void VxVector4::Normalized() {
CKFLOAT len = Length();
if (len == 0.0f) return;
x /= len;
y /= len;
z /= len;
w /= len;
}
VxVector4 VxVector4::Normalize() const {
CKFLOAT len = Length();
if (len == 0.0f) return VxVector4();
else return VxVector4(x / len, y / len, z / len, w / len);
}
/* ===== BEGIN USER CUSTOM ===== */
/* ===== END USER CUSTOM ===== */
#pragma endregion
#pragma region VxQuaternion
VxQuaternion::VxQuaternion() :x(0.0f), y(0.0f), z(0.0f), w(1.0f) {} // SET YOUR CUSTOM INIT
VxQuaternion::VxQuaternion(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w) : x(_x), y(_y), z(_z), w(_w) {}
CKFLOAT& VxQuaternion::operator[](size_t i) {
switch (i) {
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: throw LogicException("Invalid index for VxQuaternion::operator[].");
}
}
const CKFLOAT& VxQuaternion::operator[](size_t i) const {
switch (i) {
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: throw LogicException("Invalid index for VxQuaternion::operator[].");
}
}
bool VxQuaternion::operator==(const VxQuaternion& rhs) const {
return (x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w);
}
auto VxQuaternion::operator<=>(const VxQuaternion& rhs) const {
if (auto cmp = x <=> rhs.x; cmp != 0) return cmp;
if (auto cmp = y <=> rhs.y; cmp != 0) return cmp;
if (auto cmp = z <=> rhs.z; cmp != 0) return cmp;
return w <=> rhs.w;
}
/* ===== BEGIN USER CUSTOM ===== */
/* ===== END USER CUSTOM ===== */
#pragma endregion
#pragma region VxColor
VxColor::VxColor() :r(0.0f), g(0.0f), b(0.0f), a(1.0f) {} // SET YOUR CUSTOM INIT
VxColor::VxColor(CKFLOAT _r, CKFLOAT _g, CKFLOAT _b, CKFLOAT _a) : r(_r), g(_g), b(_b), a(_a) {}
CKFLOAT& VxColor::operator[](size_t i) {
switch (i) {
case 0: return r;
case 1: return g;
case 2: return b;
case 3: return a;
default: throw LogicException("Invalid index for VxColor::operator[].");
}
}
const CKFLOAT& VxColor::operator[](size_t i) const {
switch (i) {
case 0: return r;
case 1: return g;
case 2: return b;
case 3: return a;
default: throw LogicException("Invalid index for VxColor::operator[].");
}
}
bool VxColor::operator==(const VxColor& rhs) const {
return (r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a);
}
auto VxColor::operator<=>(const VxColor& rhs) const {
if (auto cmp = r <=> rhs.r; cmp != 0) return cmp;
if (auto cmp = g <=> rhs.g; cmp != 0) return cmp;
if (auto cmp = b <=> rhs.b; cmp != 0) return cmp;
return a <=> rhs.a;
}
/* ===== BEGIN USER CUSTOM ===== */
VxColor::VxColor(CKDWORD argb) { FromARGB(argb); }
VxColor::VxColor(CKFLOAT _r, CKFLOAT _g, CKFLOAT _b) : r(_r), g(_g), b(_b), a(1.0f) {}
void VxColor::FromARGB(CKDWORD argb) {
a = ((argb & 0xFF000000) >> 24) / 255.0f;
r = ((argb & 0x00FF0000) >> 16) / 255.0f;
g = ((argb & 0x0000FF00) >> 8) / 255.0f;
b = ((argb & 0x000000FF) >> 0) / 255.0f;
}
CKDWORD VxColor::ToARGB() const {
CKDWORD argb = 0;
argb |= static_cast<CKDWORD>(a * 255.0f);
argb <<= 8;
argb |= static_cast<CKDWORD>(r * 255.0f);
argb <<= 8;
argb |= static_cast<CKDWORD>(g * 255.0f);
argb <<= 8;
argb |= static_cast<CKDWORD>(b * 255.0f);
return argb;
}
void VxColor::Regulate() {
if (r > 1.0f) r = 1.0f;
else if (r < 0.0f) r = 0.0f;
if (g > 1.0f) g = 1.0f;
else if (g < 0.0f) g = 0.0f;
if (b > 1.0f) b = 1.0f;
else if (b < 0.0f) b = 0.0f;
if (a > 1.0f) a = 1.0f;
else if (a < 0.0f) a = 0.0f;
}
/* ===== END USER CUSTOM ===== */
#pragma endregion
#pragma region VxMatrix
VxMatrix::VxMatrix() : m_Data() { SetIdentity(); }
VxMatrix::VxMatrix(CKFLOAT m[4][4]) : m_Data() { std::memcpy(m_Data, m, sizeof(m_Data)); }
VxVector4& VxMatrix::operator[](size_t i) {
if (i >= 4) throw LogicException("Invalid index for VxMatrix::operator[].");
return *(reinterpret_cast<VxVector4*>(m_Data) + i);
}
const VxVector4& VxMatrix::operator[](size_t i) const {
if (i >= 4) throw LogicException("Invalid index for VxMatrix::operator[].");
return *(reinterpret_cast<const VxVector4*>(m_Data) + i);
}
bool VxMatrix::operator==(const VxMatrix& rhs) const {
return ((*this)[0] == rhs[0] && (*this)[1] == rhs[1] && (*this)[2] == rhs[2] && (*this)[3] == rhs[3]);
}
auto VxMatrix::operator<=>(const VxMatrix& rhs) const {
if (auto cmp = (*this)[0] <=> rhs[0]; cmp != 0) return cmp;
if (auto cmp = (*this)[1] <=> rhs[1]; cmp != 0) return cmp;
if (auto cmp = (*this)[2] <=> rhs[2]; cmp != 0) return cmp;
return (*this)[3] <=> rhs[3];
}
/* ===== BEGIN USER CUSTOM ===== */
void VxMatrix::Clear() {
std::memset(m_Data, 0, sizeof(m_Data));
}
void VxMatrix::SetIdentity() {
Clear();
m_Data[0][0] = m_Data[1][1] = m_Data[2][2] = m_Data[3][3] = 1.0f;
}
void VxMatrix::Perspective(CKFLOAT Fov, CKFLOAT Aspect, CKFLOAT Near_plane, CKFLOAT Far_plane) {
Clear();
m_Data[0][0] = std::cos(Fov * 0.5f) / std::sin(Fov * 0.5f);
m_Data[1][1] = m_Data[0][0] * Aspect;
m_Data[2][2] = Far_plane / (Far_plane - Near_plane);
m_Data[3][2] = -m_Data[2][2] * Near_plane;
m_Data[2][3] = 1;
}
void VxMatrix::PerspectiveRect(CKFLOAT Left, CKFLOAT Right, CKFLOAT Top, CKFLOAT Bottom, CKFLOAT Near_plane, CKFLOAT Far_plane) {
Clear();
CKFLOAT RL = 1.0f / (Right - Left);
CKFLOAT TB = 1.0f / (Top - Bottom);
m_Data[0][0] = 2.0f * Near_plane * RL;
m_Data[1][1] = 2.0f * Near_plane * TB;
m_Data[2][0] = -(Right + Left) * RL;
m_Data[2][1] = -(Top + Bottom) * TB;
m_Data[2][2] = Far_plane / (Far_plane - Near_plane);
m_Data[3][2] = -m_Data[2][2] * Near_plane;
m_Data[2][3] = 1;
}
void VxMatrix::Orthographic(CKFLOAT Zoom, CKFLOAT Aspect, CKFLOAT Near_plane, CKFLOAT Far_plane) {
Clear();
CKFLOAT iz = 1.0f / (Far_plane - Near_plane);
m_Data[0][0] = Zoom;
m_Data[1][1] = Zoom * Aspect;
m_Data[2][2] = iz;
m_Data[3][2] = -Near_plane * iz;
m_Data[3][3] = 1.0f;
}
void VxMatrix::OrthographicRect(CKFLOAT Left, CKFLOAT Right, CKFLOAT Top, CKFLOAT Bottom, CKFLOAT Near_plane, CKFLOAT Far_plane) {
Clear();
CKFLOAT ix = 1.0f / (Right - Left);
CKFLOAT iy = 1.0f / (Top - Bottom);
CKFLOAT iz = 1.0f / (Far_plane - Near_plane);
m_Data[0][0] = 2.0f * ix;
m_Data[1][1] = -2.0f * iy;
m_Data[2][2] = iz;
m_Data[3][0] = -(Left + Right) * ix;
m_Data[3][1] = (Top + Bottom) * iy;
m_Data[3][2] = -Near_plane * iz;
m_Data[3][3] = 1.0f;
}
/* ===== END USER CUSTOM ===== */
#pragma endregion
#pragma region Patched
namespace NSVxVector {
CKFLOAT DotProduct(const VxVector2& lhs, const VxVector2& rhs) {
return lhs * rhs;
}
CKFLOAT DotProduct(const VxVector3& lhs, const VxVector3& rhs) {
return lhs * rhs;
}
CKFLOAT 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 Absolute(VxVector3& lhs) {
lhs.x = std::fabs(lhs.x);
lhs.y = std::fabs(lhs.y);
lhs.z = std::fabs(lhs.z);
}
}
namespace NSVxMatrix {
}
#pragma endregion
}

View File

@ -7,7 +7,6 @@
#include <vector> #include <vector>
#include <cstring> #include <cstring>
#include <cinttypes> #include <cinttypes>
#include <cmath>
/** /**
* @brief The VxMath part of LibCmo. * @brief The VxMath part of LibCmo.
@ -23,191 +22,75 @@ namespace LibCmo::VxMath {
class VxMemoryMappedFile; class VxMemoryMappedFile;
// Misc // ========== Vector-like Definition ==========
/** /**
* @brief The representation of a Vector in 2 dimensions. * @brief The representation of a Vector in 2 dimensions.
* @remarks In original Virtools SDK, it was named Vx2DVector.
* @see VxVector3 * @see VxVector3
*/ */
struct VxVector2 { struct VxVector2 {
CKFLOAT x, y; CKFLOAT x, y;
VxVector2() : x(0.0f), y(0.0f) {} VxVector2();
VxVector2(CKFLOAT _x, CKFLOAT _y) : x(_x), y(_y) {} VxVector2(CKFLOAT _x, CKFLOAT _y);
YYCC_DEF_CLS_COPY_MOVE(VxVector2); YYCC_DEF_CLS_COPY_MOVE(VxVector2);
CKFLOAT& operator[](size_t i) { CKFLOAT& operator[](size_t i);
switch (i) { const CKFLOAT& operator[](size_t i) const;
case 0: return x; bool operator==(const VxVector2& rhs) const;
case 1: return y; auto operator<=>(const VxVector2& rhs) const;
default: throw LogicException("Invalid index for VxVector2::operator[]."); VxVector2 operator+() const;
} VxVector2 operator-() const;
} VxVector2& operator+=(const VxVector2& rhs);
const CKFLOAT& operator[](size_t i) const { friend VxVector2 operator+(const VxVector2& lhs, const VxVector2& rhs);
switch (i) { VxVector2& operator-=(const VxVector2& rhs);
case 0: return x; friend VxVector2 operator-(const VxVector2& lhs, const VxVector2& rhs);
case 1: return y; VxVector2& operator*=(CKFLOAT rhs);
default: throw LogicException("Invalid index for VxVector2::operator[]."); friend VxVector2 operator*(const VxVector2& lhs, CKFLOAT rhs);
} friend VxVector2 operator*(CKFLOAT lhs, const VxVector2& rhs);
} friend CKFLOAT operator*(const VxVector2& lhs, const VxVector2& rhs);
VxVector2& operator+=(const VxVector2& rhs) { VxVector2& operator/=(CKFLOAT rhs);
x += rhs.x; friend VxVector2 operator/(const VxVector2& lhs, CKFLOAT rhs);
y += rhs.y; CKFLOAT SquaredLength() const;
return *this; CKFLOAT Length() const;
} void Normalized();
friend VxVector2 operator+(const VxVector2& lhs, const VxVector2& rhs) { VxVector2 Normalize() const;
return VxVector2(lhs.x + rhs.x, lhs.y + rhs.y);
} /* ===== BEGIN USER CUSTOM ===== */
VxVector2& operator-=(const VxVector2& rhs) { /* ===== END USER CUSTOM ===== */
x -= rhs.x;
y -= rhs.y;
return *this;
}
friend VxVector2 operator-(const VxVector2& lhs, const VxVector2& rhs) {
return VxVector2(lhs.x - rhs.x, lhs.y - rhs.y);
}
VxVector2& operator*=(CKFLOAT rhs) {
x *= rhs;
y *= rhs;
return *this;
}
friend VxVector2 operator*(const VxVector2& lhs, CKFLOAT rhs) {
return VxVector2(lhs.x * rhs, lhs.y * rhs);
}
friend VxVector2 operator*(CKFLOAT lhs, const VxVector2& rhs) {
return VxVector2(lhs * rhs.x, lhs * rhs.y);
}
friend CKFLOAT operator*(const VxVector2& lhs, const VxVector2& rhs) {
return (lhs.x * rhs.x + lhs.y * rhs.y);
}
VxVector2& operator/=(CKFLOAT rhs) {
if (rhs == 0.0f) return *this;
x /= rhs;
y /= rhs;
return *this;
}
friend VxVector2 operator/(const VxVector2& lhs, CKFLOAT rhs) {
if (rhs == 0.0f) return VxVector2(0.0f, 0.0f);
return VxVector2(lhs.x / rhs, lhs.y / rhs);
}
bool operator==(const VxVector2& rhs) const {
return (x == rhs.x && y == rhs.y);
}
auto operator<=>(const VxVector2& rhs) const {
if (auto cmp = x <=> rhs.x; cmp != 0) return cmp;
return y <=> rhs.y;
}
CKFLOAT SquaredLength() const {
return (x * x + y * y);
}
CKFLOAT Length() const {
return std::sqrt(SquaredLength());
}
void Normalized() {
CKFLOAT len = Length();
if (len == 0.0f) return;
x /= len;
y /= len;
}
VxVector2 Normalize() const {
CKFLOAT len = Length();
if (len == 0.0f) return VxVector2();
return VxVector2(x / len, y / len);
}
}; };
/** /**
* @brief The representation of a Vector in 3 dimensions * @brief The representation of a Vector in 3 dimensions
* @remarks In original Virtools SDK, it was named VxVector.
*/ */
struct VxVector3 { struct VxVector3 {
CKFLOAT x, y, z; CKFLOAT x, y, z;
VxVector3() : x(0.0f), y(0.0f), z(0.0f) {} VxVector3();
VxVector3(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z) : x(_x), y(_y), z(_z) {} VxVector3(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z);
YYCC_DEF_CLS_COPY_MOVE(VxVector3); YYCC_DEF_CLS_COPY_MOVE(VxVector3);
CKFLOAT& operator[](size_t i) { CKFLOAT& operator[](size_t i);
switch (i) { const CKFLOAT& operator[](size_t i) const;
case 0: return x; bool operator==(const VxVector3& rhs) const;
case 1: return y; auto operator<=>(const VxVector3& rhs) const;
case 2: return z; VxVector3 operator+() const;
default: throw LogicException("Invalid index for VxVector3::operator[]."); VxVector3 operator-() const;
} VxVector3& operator+=(const VxVector3& rhs);
} friend VxVector3 operator+(const VxVector3& lhs, const VxVector3& rhs);
const CKFLOAT& operator[](size_t i) const { VxVector3& operator-=(const VxVector3& rhs);
switch (i) { friend VxVector3 operator-(const VxVector3& lhs, const VxVector3& rhs);
case 0: return x; VxVector3& operator*=(CKFLOAT rhs);
case 1: return y; friend VxVector3 operator*(const VxVector3& lhs, CKFLOAT rhs);
case 2: return z; friend VxVector3 operator*(CKFLOAT lhs, const VxVector3& rhs);
default: throw LogicException("Invalid index for VxVector3::operator[]."); friend CKFLOAT operator*(const VxVector3& lhs, const VxVector3& rhs);
} VxVector3& operator/=(CKFLOAT rhs);
} friend VxVector3 operator/(const VxVector3& lhs, CKFLOAT rhs);
VxVector3& operator+=(const VxVector3& rhs) { CKFLOAT SquaredLength() const;
x += rhs.x; CKFLOAT Length() const;
y += rhs.y; void Normalized();
z += rhs.z; VxVector3 Normalize() const;
return *this;
} /* ===== BEGIN USER CUSTOM ===== */
friend VxVector3 operator+(const VxVector3& lhs, const VxVector3& rhs) { /* ===== END USER CUSTOM ===== */
return VxVector3(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
}
VxVector3& operator-=(const VxVector3& rhs) {
x -= rhs.x;
y -= rhs.y;
z -= rhs.z;
return *this;
}
friend VxVector3 operator-(const VxVector3& lhs, const VxVector3& rhs) {
return VxVector3(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
}
VxVector3& operator*=(CKFLOAT rhs) {
x *= rhs;
y *= rhs;
z *= rhs;
return *this;
}
friend VxVector3 operator*(const VxVector3& lhs, CKFLOAT rhs) {
return VxVector3(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs);
}
friend VxVector3 operator*(CKFLOAT lhs, const VxVector3& rhs) {
return VxVector3(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);
}
friend CKFLOAT operator*(const VxVector3& lhs, const VxVector3& rhs) {
return (lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z);
}
VxVector3& operator/=(CKFLOAT rhs) {
if (rhs == 0.0f) return *this;
x /= rhs;
y /= rhs;
z /= rhs;
return *this;
}
friend VxVector3 operator/(const VxVector3& lhs, CKFLOAT rhs) {
if (rhs == 0.0f) return VxVector3(0.0f, 0.0f, 0.0f);
return VxVector3(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs);
}
bool operator==(const VxVector3& rhs) const {
return (x == rhs.x && y == rhs.y && z == rhs.z);
}
auto operator<=>(const VxVector3& rhs) const {
if (auto cmp = x <=> rhs.x; cmp != 0) return cmp;
if (auto cmp = y <=> rhs.y; cmp != 0) return cmp;
return z <=> rhs.z;
}
CKFLOAT SquaredLength() const {
return (x * x + y * y + z * z);
}
CKFLOAT Length() const {
return std::sqrt(SquaredLength());
}
void Normalized() {
CKFLOAT len = Length();
if (len == 0.0f) return;
x /= len;
y /= len;
z /= len;
}
VxVector3 Normalize() const {
CKFLOAT len = Length();
if (len == 0.0f) return VxVector3();
return VxVector3(x / len, y / len, z / len);
}
}; };
/** /**
@ -215,107 +98,37 @@ namespace LibCmo::VxMath {
* @details * @details
* VxVector4 is used for 3D transformation when the w component is used for perspective information. * VxVector4 is used for 3D transformation when the w component is used for perspective information.
* Most of the methods available for a VxVector3 are also implemented for the VxVector4. * Most of the methods available for a VxVector3 are also implemented for the VxVector4.
* @remarks In original Virtools SDK, it was named VxVector4. Not changed.
* @see VxVector3 * @see VxVector3
*/ */
struct VxVector4 { struct VxVector4 {
CKFLOAT x, y, z, w; CKFLOAT x, y, z, w;
VxVector4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {} VxVector4();
VxVector4(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w) : x(_x), y(_y), z(_z), w(_w) {} VxVector4(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w);
YYCC_DEF_CLS_COPY_MOVE(VxVector4); YYCC_DEF_CLS_COPY_MOVE(VxVector4);
CKFLOAT& operator[](size_t i) { CKFLOAT& operator[](size_t i);
switch (i) { const CKFLOAT& operator[](size_t i) const;
case 0: return x; bool operator==(const VxVector4& rhs) const;
case 1: return y; auto operator<=>(const VxVector4& rhs) const;
case 2: return z; VxVector4 operator+() const;
case 3: return w; VxVector4 operator-() const;
default: throw LogicException("Invalid index for VxVector4::operator[]."); VxVector4& operator+=(const VxVector4& rhs);
} friend VxVector4 operator+(const VxVector4& lhs, const VxVector4& rhs);
} VxVector4& operator-=(const VxVector4& rhs);
const CKFLOAT& operator[](size_t i) const { friend VxVector4 operator-(const VxVector4& lhs, const VxVector4& rhs);
switch (i) { VxVector4& operator*=(CKFLOAT rhs);
case 0: return x; friend VxVector4 operator*(const VxVector4& lhs, CKFLOAT rhs);
case 1: return y; friend VxVector4 operator*(CKFLOAT lhs, const VxVector4& rhs);
case 2: return z; friend CKFLOAT operator*(const VxVector4& lhs, const VxVector4& rhs);
case 3: return w; VxVector4& operator/=(CKFLOAT rhs);
default: throw LogicException("Invalid index for VxVector4::operator[]."); friend VxVector4 operator/(const VxVector4& lhs, CKFLOAT rhs);
} CKFLOAT SquaredLength() const;
} CKFLOAT Length() const;
VxVector4& operator+=(const VxVector4& rhs) { void Normalized();
x += rhs.x; VxVector4 Normalize() const;
y += rhs.y;
z += rhs.z; /* ===== BEGIN USER CUSTOM ===== */
w += rhs.w; /* ===== END USER CUSTOM ===== */
return *this;
}
friend VxVector4 operator+(const VxVector4& lhs, const VxVector4& rhs) {
return VxVector4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w);
}
VxVector4& operator-=(const VxVector4& rhs) {
x -= rhs.x;
y -= rhs.y;
z -= rhs.z;
w -= rhs.w;
return *this;
}
friend VxVector4 operator-(const VxVector4& lhs, const VxVector4& rhs) {
return VxVector4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w);
}
VxVector4& operator*=(CKFLOAT rhs) {
x *= rhs;
y *= rhs;
z *= rhs;
w *= rhs;
return *this;
}
friend VxVector4 operator*(const VxVector4& lhs, CKFLOAT rhs) {
return VxVector4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs);
}
friend VxVector4 operator*(CKFLOAT lhs, const VxVector4& rhs) {
return VxVector4(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w);
}
friend CKFLOAT operator*(const VxVector4& lhs, const VxVector4& rhs) {
return (lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z + lhs.w * rhs.w);
}
VxVector4& operator/=(CKFLOAT rhs) {
if (rhs == 0.0f) return *this;
x /= rhs;
y /= rhs;
z /= rhs;
w /= rhs;
return *this;
}
friend VxVector4 operator/(const VxVector4& lhs, CKFLOAT rhs) {
if (rhs == 0.0f) return VxVector4(0.0f, 0.0f, 0.0f, 0.0f);
return VxVector4(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs);
}
bool operator==(const VxVector4& rhs) const {
return (x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w);
}
auto operator<=>(const VxVector4& rhs) const {
if (auto cmp = x <=> rhs.x; cmp != 0) return cmp;
if (auto cmp = y <=> rhs.y; cmp != 0) return cmp;
if (auto cmp = z <=> rhs.z; cmp != 0) return cmp;
return w <=> rhs.w;
}
CKFLOAT SquaredLength() const {
return (x * x + y * y + z * z + w * w);
}
CKFLOAT Length() const {
return std::sqrt(SquaredLength());
}
void Normalized() {
CKFLOAT len = Length();
if (len == 0.0f) return;
x /= len;
y /= len;
z /= len;
w /= len;
}
VxVector4 Normalize() const {
CKFLOAT len = Length();
if (len == 0.0f) return VxVector4();
return VxVector4(x / len, y / len, z / len, w / len);
}
}; };
/** /**
@ -323,42 +136,22 @@ namespace LibCmo::VxMath {
* @details * @details
* A Quaternion is defined by 4 floats and is used to represents an orientation in space. * A Quaternion is defined by 4 floats and is used to represents an orientation in space.
* Its common usage is for interpolation between two orientations through the Slerp() method. * Its common usage is for interpolation between two orientations through the Slerp() method.
* *
* Quaternions can be converted to VxMatrix or Euler Angles. * Quaternions can be converted to VxMatrix or Euler Angles.
* @see VxMatrix, VxVector3 * @see VxMatrix, VxVector3
*/ */
struct VxQuaternion { struct VxQuaternion {
CKFLOAT x, y, z, w; CKFLOAT x, y, z, w;
VxQuaternion() : x(0.0f), y(0.0f), z(0.0f), w(1.0f) {} // set your custom init. VxQuaternion();
VxQuaternion(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w) : x(_x), y(_y), z(_z), w(_w) {} VxQuaternion(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w);
YYCC_DEF_CLS_COPY_MOVE(VxQuaternion); YYCC_DEF_CLS_COPY_MOVE(VxQuaternion);
CKFLOAT& operator[](size_t i) { CKFLOAT& operator[](size_t i);
switch (i) { const CKFLOAT& operator[](size_t i) const;
case 0: return x; bool operator==(const VxQuaternion& rhs) const;
case 1: return y; auto operator<=>(const VxQuaternion& rhs) const;
case 2: return z;
case 3: return w; /* ===== BEGIN USER CUSTOM ===== */
default: throw LogicException("Invalid index for VxQuaternion::operator[]."); /* ===== END USER CUSTOM ===== */
}
}
const CKFLOAT& operator[](size_t i) const {
switch (i) {
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: throw LogicException("Invalid index for VxQuaternion::operator[].");
}
}
bool operator==(const VxQuaternion& rhs) const {
return (x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w);
}
auto operator<=>(const VxQuaternion& rhs) const {
if (auto cmp = x <=> rhs.x; cmp != 0) return cmp;
if (auto cmp = y <=> rhs.y; cmp != 0) return cmp;
if (auto cmp = z <=> rhs.z; cmp != 0) return cmp;
return w <=> rhs.w;
}
}; };
/** /**
@ -366,69 +159,26 @@ namespace LibCmo::VxMath {
* @details * @details
* Structure describing a color through 4 floats for each component Red, Green, Blue and Alpha. * Structure describing a color through 4 floats for each component Red, Green, Blue and Alpha.
* And each factor should be clamped between \c 0.0f and \c 1.0f. * And each factor should be clamped between \c 0.0f and \c 1.0f.
* *
* Most methods are used to construct a VxColor or to convert it to a 32 bit ARGB format. * Most methods are used to construct a VxColor or to convert it to a 32 bit ARGB format.
*/ */
struct VxColor { struct VxColor {
CKFLOAT r, g, b, a; CKFLOAT r, g, b, a;
VxColor() : r(0.0f), g(0.0f), b(0.0f), a(1.0f) {} // set your custom init. VxColor();
VxColor(CKFLOAT _r, CKFLOAT _g, CKFLOAT _b, CKFLOAT _a) : r(_r), g(_g), b(_b), a(_a) {} VxColor(CKFLOAT _r, CKFLOAT _g, CKFLOAT _b, CKFLOAT _a);
VxColor(CKDWORD argb) { FromARGB(argb); }
YYCC_DEF_CLS_COPY_MOVE(VxColor); YYCC_DEF_CLS_COPY_MOVE(VxColor);
void FromARGB(CKDWORD argb) { CKFLOAT& operator[](size_t i);
a = ((argb & 0xFF000000) >> 24) / 255.0f; const CKFLOAT& operator[](size_t i) const;
r = ((argb & 0x00FF0000) >> 16) / 255.0f; bool operator==(const VxColor& rhs) const;
g = ((argb & 0x0000FF00) >> 8) / 255.0f; auto operator<=>(const VxColor& rhs) const;
b = ((argb & 0x000000FF) >> 0) / 255.0f;
} /* ===== BEGIN USER CUSTOM ===== */
CKDWORD ToARGB() const { VxColor(CKDWORD argb);
CKDWORD argb = 0; VxColor(CKFLOAT _r, CKFLOAT _g, CKFLOAT _b);
argb |= static_cast<CKDWORD>(a * 255.0f); void FromARGB(CKDWORD argb);
argb <<= 8; CKDWORD ToARGB() const;
argb |= static_cast<CKDWORD>(r * 255.0f); void Regulate();
argb <<= 8; /* ===== END USER CUSTOM ===== */
argb |= static_cast<CKDWORD>(g * 255.0f);
argb <<= 8;
argb |= static_cast<CKDWORD>(b * 255.0f);
return argb;
}
void Regulate() {
if (r > 1.0f) r = 1.0f;
else if (r < 0.0f) r = 0.0f;
if (g > 1.0f) g = 1.0f;
else if (g < 0.0f) g = 0.0f;
if (b > 1.0f) b = 1.0f;
else if (b < 0.0f) b = 0.0f;
if (a > 1.0f) a = 1.0f;
else if (a < 0.0f) a = 0.0f;
}
CKFLOAT& operator[](size_t i) {
switch (i) {
case 0: return r;
case 1: return g;
case 2: return b;
case 3: return a;
default: throw LogicException("Invalid index for VxColor::operator[].");
}
}
const CKFLOAT& operator[](size_t i) const {
switch (i) {
case 0: return r;
case 1: return g;
case 2: return b;
case 3: return a;
default: throw LogicException("Invalid index for VxColor::operator[].");
}
}
bool operator==(const VxColor& rhs) const {
return (r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a);
}
auto operator<=>(const VxColor& rhs) const {
if (auto cmp = r <=> rhs.r; cmp != 0) return cmp;
if (auto cmp = g <=> rhs.g; cmp != 0) return cmp;
if (auto cmp = b <=> rhs.b; cmp != 0) return cmp;
return a <=> rhs.a;
}
}; };
/** /**
@ -441,26 +191,111 @@ namespace LibCmo::VxMath {
private: private:
CKFLOAT m_Data[4][4]; CKFLOAT m_Data[4][4];
public: public:
VxMatrix() : m_Data() { ResetToIdentity(); } VxMatrix();
VxMatrix(CKFLOAT m[4][4]) : m_Data() { std::memcpy(m_Data, m, sizeof(m_Data)); } VxMatrix(CKFLOAT m[4][4]);
YYCC_DEF_CLS_COPY_MOVE(VxMatrix); YYCC_DEF_CLS_COPY_MOVE(VxMatrix);
void ResetToIdentity() { VxVector4& operator[](size_t i);
std::memset(m_Data, 0, sizeof(m_Data)); const VxVector4& operator[](size_t i) const;
m_Data[0][0] = m_Data[1][1] = m_Data[2][2] = m_Data[3][3] = 1.0f; bool operator==(const VxMatrix& rhs) const;
} auto operator<=>(const VxMatrix& rhs) const;
VxVector4& operator[](size_t i) {
if (i >= 4) throw LogicException("Invalid index for VxMatrix::operator[]."); /* ===== BEGIN USER CUSTOM ===== */
return *(reinterpret_cast<VxVector4*>(m_Data) + i); void Clear();
} void SetIdentity();
const VxVector4& operator[](size_t i) const { /**
if (i >= 4) throw LogicException("Invalid index for VxMatrix::operator[]."); * @brief Constructs a perspective projection matrix.
return *(reinterpret_cast<const VxVector4*>(m_Data) + i); * @param[in] Fov Field of View.
} * @param[in] Aspect Aspect ratio (Width/height)
bool operator==(const VxMatrix& rhs) const { * @param[in] Near_plane Distance of the near clipping plane.
return std::memcmp(m_Data, rhs.m_Data, sizeof(m_Data)) == 0; * @param[in] Far_plane Distance of the far clipping plane.
} * @remarks Sets Mat to
*
* A = Cos(Fov/2)/Sin(Fov/2)
* F = Far_plane
* N = Near_plane
*
* [ A 0 0 0]
* [ 0 A*Aspect 0 0]
* MAT= [ 0 0 F/F-N 1]
* [ 0 0 -F.N/F-N 0]
*
* @see PerspectiveRect, Orthographic, OrthographicRect
*/
void Perspective(CKFLOAT Fov, CKFLOAT Aspect, CKFLOAT Near_plane, CKFLOAT Far_plane);
/**
* @brief Constructs a perspective projection matrix given a view rectangle.
* @param[in] Left Left clipping plane value.
* @param[in] Right Right clipping plane value.
* @param[in] Top top clipping plane value.
* @param[in] Bottom bottom clipping plane value.
* @param[in] Near_plane Distance of the near clipping plane.
* @param[in] Far_plane Distance of the far clipping plane.
* @remarks Sets Mat to
*
* F = Far_plane
* N = Near_plane
* R = Right
* L = Left
* T = Top
* B = Bottom
*
* [ 2/(R-L) 0 0 0]
* [ 0 -2/(T-B) 0 0]
* MAT = [ 0 0 1/F-N 0]
* [ -(L+R)/(R-L) (T+B)/(T-B) -N/F-N 1]
*
* @see Perspective, Orthographic, OrthographicRect
*/
void PerspectiveRect(CKFLOAT Left, CKFLOAT Right, CKFLOAT Top, CKFLOAT Bottom, CKFLOAT Near_plane, CKFLOAT Far_plane);
/**
* @brief Constructs a orthographic projection matrix.
* @param[in] Zoom Zoom factor.
* @param[in] Aspect Aspect ratio (Width/height)
* @param[in] Near_plane Distance of the near clipping plane.
* @param[in] Far_plane Distance of the far clipping plane.
* @remarks Sets Mat to
*
* F = Far_plane
* N = Near_plane
*
* [ Zoom 0 0 0]
* [ 0 Zoom*Aspect 0 0]
* MAT = [ 0 0 1/F-N 0]
* [ 0 0 -N/F-N 1]
*
* @see Perspective, OrthographicRect
*/
void Orthographic(CKFLOAT Zoom, CKFLOAT Aspect, CKFLOAT Near_plane, CKFLOAT Far_plane);
/**
* @brief Constructs a orthographic projection matrix.
* @param[in] Left Left clipping plane value.
* @param[in] Right Right clipping plane value.
* @param[in] Top top clipping plane value.
* @param[in] Bottom bottom clipping plane value.
* @param[in] Near_plane Distance of the near clipping plane.
* @param[in] Far_plane Distance of the far clipping plane.
* @remarks Sets Mat to
*
* F = Far_plane
* N = Near_plane
* R = Right
* L = Left
* T = Top
* B = Bottom
*
* [ 2/(R-L) 0 0 0]
* [ 0 -2/(T-B) 0 0]
* MAT = [ 0 0 1/F-N 0]
* [ -(L+R)/(R-L) (T+B)/(T-B) -N/F-N 1]
*
* @see Perspective, Orthographic
*/
void OrthographicRect(CKFLOAT Left, CKFLOAT Right, CKFLOAT Top, CKFLOAT Bottom, CKFLOAT Near_plane, CKFLOAT Far_plane);
/* ===== END USER CUSTOM ===== */
}; };
// ========== Misc ==========
/** /**
* @brief Structure for storage of strided data. * @brief Structure for storage of strided data.
* @tparam _Ty The data pointer type this class stored. * @tparam _Ty The data pointer type this class stored.
@ -696,4 +531,96 @@ namespace LibCmo::VxMath {
CKBYTE* m_Image; /**< A pointer points to current image in memory */ CKBYTE* m_Image; /**< A pointer points to current image in memory */
}; };
// ========== 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 Absolute(VxVector3& lhs);
}
/**
* @brief The patch namespace for VxMatrix classes
* @details Like NXVxVector, these functions located in this namespace
* are exposed in public namespace in original Virtools SDK.
* And I re-organise them in there.
*/
namespace NSVxMatrix {
//void Vx3DMatrixIdentity(VxMatrix& Mat);
//void Vx3DMultiplyMatrixVector(VxVector *ResultVector,const VxMatrix& Mat,const VxVector *Vector);
//void Vx3DMultiplyMatrixVectorMany(VxVector *ResultVectors,const VxMatrix& Mat,const VxVector *Vectors,int count,int stride);
//void Vx3DMultiplyMatrixVector4(VxVector4 *ResultVector,const VxMatrix& Mat,const VxVector4 *Vector);
//void Vx3DMultiplyMatrixVector4(VxVector4 *ResultVector,const VxMatrix& Mat,const VxVector *Vector); // w=1
//void Vx3DRotateVector(VxVector *ResultVector,const VxMatrix& Mat,const VxVector *Vector);
//void Vx3DRotateVectorMany(VxVector *ResultVector,const VxMatrix& Mat,const VxVector *Vector,int count,int stride);
//void Vx3DMultiplyMatrix(VxMatrix& ResultMat,const VxMatrix& MatA,const VxMatrix& MatB);
//void Vx3DMultiplyMatrix4(VxMatrix& ResultMat,const VxMatrix& MatA,const VxMatrix& MatB);
//void Vx3DInverseMatrix(VxMatrix& InverseMat,const VxMatrix& Mat);
//float Vx3DMatrixDeterminant(const VxMatrix& Mat);
//void Vx3DMatrixFromRotation(VxMatrix& ResultMat,const VxVector& Vector, float Angle);
//void Vx3DMatrixFromRotationAndOrigin(VxMatrix& ResultMat,const VxVector& Vector,const VxVector& Origin, float Angle);
//void Vx3DMatrixFromEulerAngles(VxMatrix& Mat,float eax,float eay,float eaz);
//void Vx3DMatrixToEulerAngles(const VxMatrix& Mat,float *eax,float* eay,float* eaz);
//void Vx3DInterpolateMatrix(float step,VxMatrix& Res,const VxMatrix& A, const VxMatrix& B);
//void Vx3DInterpolateMatrixNoScale(float step,VxMatrix& Res,const VxMatrix& A, const VxMatrix& B);
//void Vx3DMultiplyMatrixVectorStrided(VxStridedData* Dest,VxStridedData* Src,const VxMatrix& Mat,int count);
//void Vx3DMultiplyMatrixVector4Strided(VxStridedData* Dest,VxStridedData* Src,const VxMatrix& Mat,int count);
//void Vx3DRotateVectorStrided(VxStridedData* Dest,VxStridedData* Src,const VxMatrix& Mat,int count);
//void Vx3DTransposeMatrix(VxMatrix& Result,const VxMatrix& A);
//void Vx3DDecomposeMatrix(const VxMatrix& A, VxQuaternion &Quat,VxVector &Pos,VxVector &Scale);
//float Vx3DDecomposeMatrixTotal(const VxMatrix& A, VxQuaternion &Quat,VxVector &Pos,VxVector &Scale,VxQuaternion &URot);
//float Vx3DDecomposeMatrixTotalPtr(const VxMatrix& A, VxQuaternion* Quat,VxVector* Pos,VxVector* Scale,VxQuaternion* URot);
//void VxInverseProject(const VxMatrix& iProjection, const Vx2DVector& i2D, const float iZ, VxVector* o3D);
}
} }

View File

@ -1,7 +1,7 @@
# libcmo21 # libcmo21
The Library for CMO (also accept NMO, VMO and NMS) File Read/Write. Also the Minimalist Virtools Environment. The Library for CMO (also accept NMO, VMO and NMS) File RW (Read and Write). Also the Minimalist Virtools Environment.
Write with one Library and Load Virtools File Everywhere. Write with one Library and Load/Save Virtools File Everywhere.
## Status ## Status
@ -10,12 +10,15 @@ This project welcome everyone's contribution, except the employee of Dassault, w
## Introduction ## Introduction
The aim of this project is creating a universal library which can read / write CMO files or any other Virtools files without any Virtools dependencies. The aim of this project is creating a universal library which can RW CMO files or any other Virtools files without any Virtools dependencies.
This project will not link any original Virtools dynamic library. So this project can be ported to any platform if the compiler supports.
This project only involving specific Virtools version, 2.1. Other Virtools versions are not considered by this project.
This project is based on reverse work of `CK2.dll`, `VxMath.dll` and `CK2_3D.dll`. The program [unvirt](https://aluigi.altervista.org/papers.htm#unvirt) created by Luigi Auriemma, which is licensed by GPL-v2, also help my work.
**The difference between this project and other Virtools libraries (e.g. [doyaGu/CK2](https://github.com/doyaGu/CK2)), is that we are not focusing on re-creating the whole Virtools engine. We only focus on the Virtools files RW, and we only just implement a minimalist Virtools environment for achieving this.** This project will not link any original Virtools dynamic library. So this project can be ported to any platform if the compiler and runtime libraries support.
This project only involving specific Virtools version, 2.1. Other too higher Virtools versions are not considered by this project.
This project is barely based on the reverse work of doyaGu who decompile `CK2.dll`, `VxMath.dll` and `CK2_3D.dll`. The program [unvirt](https://aluigi.altervista.org/papers.htm#unvirt) created by Luigi Auriemma, which is licensed by GPL-v2, also help my work.
**The difference between this project and other Virtools libraries (e.g. [doyaGu/CK2](https://github.com/doyaGu/CK2)), is that this project is not focusing on re-creating the whole Virtools engine. This project only focus on the Virtools files RW, and it only just implement a minimalist Virtools environment for achieving this.**
## Goals ## Goals
@ -23,22 +26,20 @@ The ultimate goals of this project are:
* Create a library which can read Virtools file and do not limited on x86 platform by original Virtools implement. * Create a library which can read Virtools file and do not limited on x86 platform by original Virtools implement.
* Create a universal dynamic library for Ballance Map file loading. * Create a universal dynamic library for Ballance Map file loading.
* Create a Python binding for the loader. And allow user can export Ballance Map from Blender on Linux platform natively. - Create a Python binding for the loader. And allow user can export Ballance Map from Blender on Linux platform natively.
* Create a C# binding for the loader to enable that I can load Ballance Map in Godot on Linux / Android platform natively. - Create a C# binding for the loader to enable that I can load Ballance Map in Godot on Linux / Android platform natively.
There is still a long way to go. But I will try my best. There is still a long way to go. But I will try my best.
## Project Layout ## Project Layout
* LibCmo: Core library. It is a static library. Link to your program freely because I don't want to process export table things. * LibCmo: Core library. It is a static library. Link to your program freely because I don't want to process export table things.
* IronPad: A tiny Crashpad like static library. Used by Unvirt and BMap. Report crash log and coredump only on Windows (Because I assume all Linux users have capacity to enable coredump and deliver it to developer.).
* Unvirt: Interactive Virtools file viewer. Can provide more detail than Luigi Auriemma's unvirt but only can accept version limited Virtools file (< 4.0 I guess). * Unvirt: Interactive Virtools file viewer. Can provide more detail than Luigi Auriemma's unvirt but only can accept version limited Virtools file (< 4.0 I guess).
* BMap: A dynamic library which is specific for Ballance Map loading by using LibCmo. * BMap: A dynamic library which is specific for Ballance Map loading by using LibCmo.
## Contributions ## Contributions
However, not all contribution will be accepted. Just like I said, we create **Minimalist** Virtools Environment. The basic RW functions is enough. We do not accept complex function implementations. However, not all contribution will be accepted. Just like I said, we create **Minimalist** Virtools Environment. The basic RW functions is enough. We do not accept complex function implementations. There are 3 lists which indicate our accept guideline.
There are 3 lists which indicate our accept guideline.
### Wanted Features ### Wanted Features
@ -64,14 +65,4 @@ These features explicitly will not be merged.
## Compile ## Compile
This project require: See [Compile Manual](./COMPILE.md)
* The compiler supporting C++ 20
* Littile-endian architecture system.
* zlib
* [stb](https://github.com/nothings/stb) (For image read / write)
* iconv (non-Windows system required)
It can be compiled on Windows via sln file. You should set up `LibRef.props` when using sln file to build this project on Windows.
You also can use CMake file to compile this project on Linux or anything else platform. However CMake may not be updated in time because I develop this project on Windows frequently.
You may need use this command to configure CMake: `cmake .. -DSTB_IMAGE_PATH="/path/to/stb-image" -DCMAKE_BUILD_TYPE=Release`

3
Scripts/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Disable output
win_build.bat
linux_build.sh

View File

@ -0,0 +1,67 @@
import os
import argparse
import jinja2
def get_root_directory() -> str:
return os.path.dirname(os.path.dirname(__file__))
class ScriptSettings:
m_BuildDoc: bool
def __init__(self, build_doc: bool):
self.m_BuildDoc = build_doc
class TemplateRender:
m_Loader: jinja2.BaseLoader
m_Environment: jinja2.Environment
m_WinTemplate: jinja2.Template
m_LinuxTemplate: jinja2.Template
m_Settings: ScriptSettings
def __init__(self, settings: ScriptSettings) -> None:
self.m_Loader = jinja2.FileSystemLoader(self.__get_dir())
self.m_Environment = jinja2.Environment(loader=self.m_Loader)
self.m_WinTemplate = self.m_Environment.get_template('win_build.template.bat')
self.m_LinuxTemplate = self.m_Environment.get_template('linux_build.template.sh')
self.m_Settings = settings
def __get_dir(self) -> str:
return os.path.dirname(__file__)
def __render(self, template: jinja2.Template, dest_file: str, is_win: bool) -> None:
with open(os.path.join(self.__get_dir(), dest_file), 'w', encoding='utf-8') as f:
f.write(template.render(
repo_root_dir = os.path.dirname(self.__get_dir()),
build_doc = self.m_Settings.m_BuildDoc
))
def render_win_script(self) -> None:
self.__render(self.m_WinTemplate, 'win_build.bat', True)
def render_linux_script(self) -> None:
self.__render(self.m_LinuxTemplate, 'linux_build.sh', False)
if __name__ == '__main__':
# parse argument
parser = argparse.ArgumentParser(
prog='LibCmo Windows Build Script',
description='LibCmo Windows Build Script'
)
parser.add_argument(
'-d', '--build-doc',
action='store_true', dest='build_doc',
help='Build LibCmo without documentation.'
)
args = parser.parse_args()
# build settings
settings = ScriptSettings(args.build_doc)
# build template render and render result
render = TemplateRender(settings)
render.render_win_script()
render.render_linux_script()

View File

View File

@ -1,38 +0,0 @@
@ECHO OFF
:: Check environment
SET README_PATH=%CD%\README.md
IF EXIST %README_PATH% (
REM DO NOTHING
) ELSE (
ECHO Error: You must run this script at the root folder of this project!
EXIT /b
)
:: Create main binary directory
MKDIR bin
CD bin
:: Create build and install folder
MKDIR build
MKDIR install
:: Check build doc switch
IF NOT "%1"=="NODOC" (
SET BUILD_DOC_SWITCH=ON
) ELSE (
SET BUILD_DOC_SWITCH=OFF
)
:: Build project
CD build
cmake -G "Visual Studio 16 2019" -A x64 -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_DOC=%BUILD_DOC_SWITCH% -DSTB_IMAGE_PATH="D:\CppLib\stb" -DYYCC_PATH="J:\YYCCommonplace\bin\cpp20\install\x64_Debug" -DZLIB_HEADER_PATH="D:\zlib" -DZLIB_BINARY_PATH="D:\zlib\contrib\vstudio\vc14\x64\ZlibDllRelease" ../..
pause
cmake --build . --config Release
IF NOT "%1"=="NODOC" (
cmake --build . --target NeMoDocuments
)
cmake --install . --prefix=../install --config Release
CD ..
:: Exit to original path
CD ..
ECHO Windows CMake Build Done

View File

@ -1,48 +0,0 @@
import subprocess
import os
import shutil
import argparse
def get_root_directory() -> str:
return os.path.dirname(os.path.dirname(__file__))
def execute_cmd(prog: str, args: tuple[str, ...], cwd: str) -> None:
# find program first
found_prog = shutil.which(prog)
if found_prog is None:
raise RuntimeError(f'Fail to find program {prog}')
# run command
subprocess.run(
list((found_prog, ) + args), # program + arguments
stdin=subprocess.PIPE, # redirect
stdout=subprocess.PIPE, # redirect
stderr=subprocess.STDOUT, # stderr use the same output with stdout
cwd=cwd, # work directory
shell=True, # enable shell feature
check=True, # if program failed, raise exception and exit
)
def build(no_doc: bool) -> None:
# create directory
root_dir: str = get_root_directory()
os.makedirs(os.path.join(root_dir, 'Bin', 'build'))
os.makedirs(os.path.join(root_dir, 'Bin', 'install'))
# build project
args = [
''
]
if __name__ == '__main__':
# parse argument
parser = argparse.ArgumentParser(
prog='LibCmo Windows Build Script',
description='LibCmo Windows Build Script'
)
parser.add_argument(
'-d', '--no-doc',
action='store_true', dest='no_doc',
help='Build LibCmo without documentation.'
)
args = parser.parse_args()
build(args.no_doc)

View File

@ -0,0 +1,24 @@
@ECHO OFF
:: Navigate to root directory
CD /d {{ repo_root_dir }}
:: Create main binary directory
MKDIR bin
CD bin
:: Create build and install folder
MKDIR build
MKDIR install
:: Build project
CD build
cmake -A x64 -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BMAP=ON {{ '-DNEMO_BUILD_DOC=ON' if build_doc }} -DSTB_IMAGE_PATH="D:\CppLib\stb" -DYYCC_PATH="J:\YYCCommonplace\bin\cpp20\install\x64_Release" -DZLIB_HEADER_PATH="D:\zlib" -DZLIB_BINARY_PATH="D:\zlib\contrib\vstudio\vc14\x64\ZlibDllRelease" ../..
cmake --build . --config RelWithDebInfo
{% if build_doc %}
cmake --build . --target NeMoDocuments
{% endif %}
cmake --install . --prefix=../install --config RelWithDebInfo
CD ..
:: Exit to original path
CD ..
ECHO Windows CMake Build Done

View File

@ -383,6 +383,10 @@ namespace Unvirt::AccessibleValue {
{ LibCmo::CK2::CK_BITMAPDATA_FLAGS::CKBITMAPDATA_FREEVIDEOMEMORY, { u8"CKBITMAPDATA_FREEVIDEOMEMORY" } }, { LibCmo::CK2::CK_BITMAPDATA_FLAGS::CKBITMAPDATA_FREEVIDEOMEMORY, { u8"CKBITMAPDATA_FREEVIDEOMEMORY" } },
{ LibCmo::CK2::CK_BITMAPDATA_FLAGS::CKBITMAPDATA_DYNAMIC, { u8"CKBITMAPDATA_DYNAMIC" } }, { LibCmo::CK2::CK_BITMAPDATA_FLAGS::CKBITMAPDATA_DYNAMIC, { u8"CKBITMAPDATA_DYNAMIC" } },
}; };
const GeneralReflectionArray<LibCmo::CK2::CK_CAMERA_PROJECTION> CK_CAMERA_PROJECTION {
{ LibCmo::CK2::CK_CAMERA_PROJECTION::CK_PERSPECTIVEPROJECTION, { u8"CK_PERSPECTIVEPROJECTION" } },
{ LibCmo::CK2::CK_CAMERA_PROJECTION::CK_ORTHOGRAPHICPROJECTION, { u8"CK_ORTHOGRAPHICPROJECTION" } },
};
const GeneralReflectionArray<LibCmo::VxMath::VX_PIXELFORMAT> VX_PIXELFORMAT { const GeneralReflectionArray<LibCmo::VxMath::VX_PIXELFORMAT> VX_PIXELFORMAT {
{ LibCmo::VxMath::VX_PIXELFORMAT::UNKNOWN_PF, { u8"UNKNOWN_PF" } }, { LibCmo::VxMath::VX_PIXELFORMAT::UNKNOWN_PF, { u8"UNKNOWN_PF" } },
@ -418,6 +422,12 @@ namespace Unvirt::AccessibleValue {
{ LibCmo::VxMath::VX_PIXELFORMAT::_4_ABGR8888_CLUT, { u8"_4_ABGR8888_CLUT" } }, { LibCmo::VxMath::VX_PIXELFORMAT::_4_ABGR8888_CLUT, { u8"_4_ABGR8888_CLUT" } },
{ LibCmo::VxMath::VX_PIXELFORMAT::_4_ARGB8888_CLUT, { u8"_4_ARGB8888_CLUT" } }, { LibCmo::VxMath::VX_PIXELFORMAT::_4_ARGB8888_CLUT, { u8"_4_ARGB8888_CLUT" } },
}; };
const GeneralReflectionArray<LibCmo::VxMath::VXLIGHT_TYPE> VXLIGHT_TYPE {
{ LibCmo::VxMath::VXLIGHT_TYPE::VX_LIGHTPOINT, { u8"VX_LIGHTPOINT" } },
{ LibCmo::VxMath::VXLIGHT_TYPE::VX_LIGHTSPOT, { u8"VX_LIGHTSPOT" } },
{ LibCmo::VxMath::VXLIGHT_TYPE::VX_LIGHTDIREC, { u8"VX_LIGHTDIREC" } },
{ LibCmo::VxMath::VXLIGHT_TYPE::VX_LIGHTPARA, { u8"VX_LIGHTPARA" } },
};
const GeneralReflectionArray<LibCmo::VxMath::VXTEXTURE_BLENDMODE> VXTEXTURE_BLENDMODE { const GeneralReflectionArray<LibCmo::VxMath::VXTEXTURE_BLENDMODE> VXTEXTURE_BLENDMODE {
{ LibCmo::VxMath::VXTEXTURE_BLENDMODE::VXTEXTUREBLEND_DECAL, { u8"VXTEXTUREBLEND_DECAL" } }, { LibCmo::VxMath::VXTEXTURE_BLENDMODE::VXTEXTUREBLEND_DECAL, { u8"VXTEXTUREBLEND_DECAL" } },
{ LibCmo::VxMath::VXTEXTURE_BLENDMODE::VXTEXTUREBLEND_MODULATE, { u8"VXTEXTUREBLEND_MODULATE" } }, { LibCmo::VxMath::VXTEXTURE_BLENDMODE::VXTEXTUREBLEND_MODULATE, { u8"VXTEXTUREBLEND_MODULATE" } },

View File

@ -61,7 +61,7 @@ namespace Unvirt {
} }
// check flag match // check flag match
if (LibCmo::EnumsHelper::Has(val, item.first)) { if (YYCC::EnumHelper::Has(val, item.first)) {
// add splittor if it not the first entry // add splittor if it not the first entry
if (strl.size() != 0u && splitor != nullptr) { if (strl.size() != 0u && splitor != nullptr) {
strl += splitor; strl += splitor;
@ -102,8 +102,10 @@ namespace Unvirt {
extern const GeneralReflectionArray<LibCmo::CK2::CK_3DENTITY_FLAGS> CK_3DENTITY_FLAGS; extern const GeneralReflectionArray<LibCmo::CK2::CK_3DENTITY_FLAGS> CK_3DENTITY_FLAGS;
extern const GeneralReflectionArray<LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS> CK_TEXTURE_SAVEOPTIONS; extern const GeneralReflectionArray<LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS> CK_TEXTURE_SAVEOPTIONS;
extern const GeneralReflectionArray<LibCmo::CK2::CK_BITMAPDATA_FLAGS> CK_BITMAPDATA_FLAGS; extern const GeneralReflectionArray<LibCmo::CK2::CK_BITMAPDATA_FLAGS> CK_BITMAPDATA_FLAGS;
extern const GeneralReflectionArray<LibCmo::CK2::CK_CAMERA_PROJECTION> CK_CAMERA_PROJECTION;
extern const GeneralReflectionArray<LibCmo::VxMath::VX_PIXELFORMAT> VX_PIXELFORMAT; extern const GeneralReflectionArray<LibCmo::VxMath::VX_PIXELFORMAT> VX_PIXELFORMAT;
extern const GeneralReflectionArray<LibCmo::VxMath::VXLIGHT_TYPE> VXLIGHT_TYPE;
extern const GeneralReflectionArray<LibCmo::VxMath::VXTEXTURE_BLENDMODE> VXTEXTURE_BLENDMODE; extern const GeneralReflectionArray<LibCmo::VxMath::VXTEXTURE_BLENDMODE> VXTEXTURE_BLENDMODE;
extern const GeneralReflectionArray<LibCmo::VxMath::VXTEXTURE_FILTERMODE> VXTEXTURE_FILTERMODE; extern const GeneralReflectionArray<LibCmo::VxMath::VXTEXTURE_FILTERMODE> VXTEXTURE_FILTERMODE;
extern const GeneralReflectionArray<LibCmo::VxMath::VXBLEND_MODE> VXBLEND_MODE; extern const GeneralReflectionArray<LibCmo::VxMath::VXBLEND_MODE> VXBLEND_MODE;

View File

@ -23,8 +23,6 @@ FILES
target_include_directories(Unvirt target_include_directories(Unvirt
PRIVATE PRIVATE
"${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}"
YYCC::YYCCommonplace
LibCmo
) )
# Setup linked library infomation # Setup linked library infomation
target_link_libraries(Unvirt target_link_libraries(Unvirt
@ -53,6 +51,6 @@ PRIVATE
# Install Unvirt only on Release mode # Install Unvirt only on Release mode
install(TARGETS Unvirt install(TARGETS Unvirt
CONFIGURATIONS Release CONFIGURATIONS Release RelWithDebInfo MinSizeRel
RUNTIME DESTINATION ${YYCC_INSTALL_BIN_PATH} RUNTIME DESTINATION ${YYCC_INSTALL_BIN_PATH}
) )

View File

@ -362,8 +362,8 @@ namespace Unvirt::CmdHelper {
throw std::invalid_argument("root node should not be inserted as child node."); throw std::invalid_argument("root node should not be inserted as child node.");
// check conflict // check conflict
const auto& new_node_set = new_node_ptr->GetConflictSet(); const auto& new_node_set = new_node_ptr->GetConflictSet();
for (auto& node : m_Nodes) { for (auto& child_node : m_Nodes) {
const auto& node_set = node->GetConflictSet(); const auto& node_set = child_node->GetConflictSet();
if (new_node_set.IsConflictWith(node_set)) if (new_node_set.IsConflictWith(node_set))
throw std::invalid_argument("try to add a conflict node. please check your code."); throw std::invalid_argument("try to add a conflict node. please check your code.");
} }

View File

@ -165,7 +165,7 @@ namespace Unvirt::StructFormatter {
// print current mesh // print current mesh
{ {
auto curmesh = obj->GetCurrentMesh(); auto curmesh = obj->GetCurrentMesh();
Console::Format(u8"->\t%s\t%s", Console::FormatLine(u8"->\t%s\t%s",
PrintPointer(curmesh).c_str(), PrintPointer(curmesh).c_str(),
(curmesh != nullptr ? PrintCKSTRING(curmesh->GetName()).c_str() : u8"") (curmesh != nullptr ? PrintCKSTRING(curmesh->GetName()).c_str() : u8"")
); );
@ -181,6 +181,70 @@ namespace Unvirt::StructFormatter {
} }
} }
static void PrintCKLightDetail(LibCmo::CK2::ObjImpls::CKLight* obj) {
PrintCK3dEntityDetail(obj);
Console::WriteLine(YYCC_COLOR_LIGHT_YELLOW(u8"CKLight"));
Console::WriteLine(u8"== Basics ==");
Console::FormatLine(u8"Type: %s", AccessibleValue::GetEnumName(obj->GetType(), AccessibleValue::EnumDesc::VXLIGHT_TYPE).c_str());
Console::FormatLine(u8"Color: %s", PrintColor(obj->GetColor()).c_str());
Console::FormatLine(u8"Light Power: %.2" PRIfCKFLOAT, obj->GetLightPower());
Console::WriteLine(u8"== Switches ==");
Console::FormatLine(u8"Activity: %s", PrintBool(obj->GetActivity()).c_str());
Console::FormatLine(u8"Specular Flag: %s", PrintBool(obj->GetSpecularFlag()).c_str());
Console::WriteLine(u8"== Attenuation ==");
Console::FormatLine(u8"Constant Attenuation: %.2" PRIfCKFLOAT, obj->GetConstantAttenuation());
Console::FormatLine(u8"Linear Attenuation: %.2" PRIfCKFLOAT, obj->GetLinearAttenuation());
Console::FormatLine(u8"Quadratic Attenuation: %.2" PRIfCKFLOAT, obj->GetQuadraticAttenuation());
Console::WriteLine(u8"== Spot Cone ==");
Console::FormatLine(u8"Range: %.2" PRIfCKFLOAT, obj->GetRange());
Console::FormatLine(u8"Hot Spot: %.2" PRIfCKFLOAT, obj->GetHotSpot());
Console::FormatLine(u8"Falloff: %.2" PRIfCKFLOAT, obj->GetFalloff());
Console::FormatLine(u8"Falloff Shape: %.2" PRIfCKFLOAT, obj->GetFalloffShape());
Console::WriteLine(u8"== Target ==");
auto thistarget = obj->GetTarget();
Console::FormatLine(u8"Target Address: %s", PrintPointer(thistarget).c_str());
if (thistarget != nullptr)
Console::FormatLine(u8"Target Name: %s", PrintCKSTRING(thistarget->GetName()).c_str());
}
static void PrintCKTargetLightDetail(LibCmo::CK2::ObjImpls::CKTargetLight* obj) {
PrintCKLightDetail(obj);
Console::WriteLine(YYCC_COLOR_LIGHT_YELLOW(u8"CKTargetLight"));
Console::WriteLine(YYCC_COLOR_LIGHT_RED(u8"No Data"));
}
static void PrintCKCameraDetail(LibCmo::CK2::ObjImpls::CKCamera* obj) {
PrintCK3dEntityDetail(obj);
Console::WriteLine(YYCC_COLOR_LIGHT_YELLOW(u8"CKCamera"));
Console::WriteLine(u8"== Basics ==");
Console::FormatLine(u8"Projection Type: %s", AccessibleValue::GetEnumName(obj->GetProjectionType(), AccessibleValue::EnumDesc::CK_CAMERA_PROJECTION).c_str());
Console::FormatLine(u8"Orthographic Zoom: %.2" PRIfCKFLOAT, obj->GetOrthographicZoom());
Console::FormatLine(u8"Front Plane: %.2" PRIfCKFLOAT, obj->GetFrontPlane());
Console::FormatLine(u8"Back Plane: %.2" PRIfCKFLOAT, obj->GetBackPlane());
Console::FormatLine(u8"Fov: %.2" PRIfCKFLOAT, obj->GetFov());
LibCmo::CKDWORD width, height;
obj->GetAspectRatio(width, height);
Console::FormatLine(u8"Aspect Ratio: %" PRIuCKDWORD " : %" PRIuCKDWORD, width, height);
Console::WriteLine(u8"== Target ==");
auto thistarget = obj->GetTarget();
Console::FormatLine(u8"Target Address: %s", PrintPointer(thistarget).c_str());
if (thistarget != nullptr)
Console::FormatLine(u8"Target Name: %s", PrintCKSTRING(thistarget->GetName()).c_str());
}
static void PrintCKTargetCameraDetail(LibCmo::CK2::ObjImpls::CKTargetCamera* obj) {
PrintCKCameraDetail(obj);
Console::WriteLine(YYCC_COLOR_LIGHT_YELLOW(u8"CKTargetCamera"));
Console::WriteLine(YYCC_COLOR_LIGHT_RED(u8"No Data"));
}
static void PrintCK3dObjectDetail(LibCmo::CK2::ObjImpls::CK3dObject* obj) { static void PrintCK3dObjectDetail(LibCmo::CK2::ObjImpls::CK3dObject* obj) {
PrintCK3dEntityDetail(obj); PrintCK3dEntityDetail(obj);
@ -560,6 +624,18 @@ namespace Unvirt::StructFormatter {
case LibCmo::CK2::CK_CLASSID::CKCID_3DENTITY: case LibCmo::CK2::CK_CLASSID::CKCID_3DENTITY:
PrintCK3dEntityDetail(static_cast<LibCmo::CK2::ObjImpls::CK3dEntity*>(mobj)); PrintCK3dEntityDetail(static_cast<LibCmo::CK2::ObjImpls::CK3dEntity*>(mobj));
break; break;
case LibCmo::CK2::CK_CLASSID::CKCID_LIGHT:
PrintCKLightDetail(static_cast<LibCmo::CK2::ObjImpls::CKLight*>(mobj));
break;
case LibCmo::CK2::CK_CLASSID::CKCID_TARGETLIGHT:
PrintCKTargetLightDetail(static_cast<LibCmo::CK2::ObjImpls::CKTargetLight*>(mobj));
break;
case LibCmo::CK2::CK_CLASSID::CKCID_CAMERA:
PrintCKCameraDetail(static_cast<LibCmo::CK2::ObjImpls::CKCamera*>(mobj));
break;
case LibCmo::CK2::CK_CLASSID::CKCID_TARGETCAMERA:
PrintCKTargetCameraDetail(static_cast<LibCmo::CK2::ObjImpls::CKTargetCamera*>(mobj));
break;
case LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT: case LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT:
PrintCK3dObjectDetail(static_cast<LibCmo::CK2::ObjImpls::CK3dObject*>(mobj)); PrintCK3dObjectDetail(static_cast<LibCmo::CK2::ObjImpls::CK3dObject*>(mobj));
break; break;

View File

@ -281,7 +281,7 @@ namespace Unvirt::Context {
YYCC::ConsoleHelper::EnableColorfulConsole(); YYCC::ConsoleHelper::EnableColorfulConsole();
// Show banner // Show banner
YYCC::ConsoleHelper::WriteLine(YYCC_COLOR_LIGHT_YELLOW(u8"Unvirt 0.2.0") " built at " __DATE__ " " __TIME__); YYCC::ConsoleHelper::WriteLine(YYCC_COLOR_LIGHT_YELLOW(u8"Unvirt") " (based on LibCmo " LIBCMO_VER_STR ") built at " __DATE__ " " __TIME__);
YYCC::ConsoleHelper::WriteLine(u8"Type 'help' for more infomation. Type 'exit' to quit."); YYCC::ConsoleHelper::WriteLine(u8"Type 'help' for more infomation. Type 'exit' to quit.");
// start process loop // start process loop