Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
af6a50c2f9 | |||
0bf0519c4c | |||
c18ff8f2e3 | |||
fe4a58e864 | |||
eaeaf956b5 | |||
6bb2421e1f | |||
ead22d13ff | |||
aeb2e86b14 | |||
86b27557c9 | |||
eef3a352d9 | |||
b74f1b965c | |||
c235524403 | |||
4bfc4782b5 | |||
3eeb1f6cb6 | |||
ff5a590cf4 | |||
d29d40448b |
3
.gitignore
vendored
3
.gitignore
vendored
@ -5,6 +5,9 @@
|
||||
*.nms
|
||||
*.vmo
|
||||
|
||||
# Ignore CMake generated version header
|
||||
LibCmo/VTVersion.hpp
|
||||
|
||||
# Ignore temporary Visual Studio files and folders
|
||||
temp/
|
||||
out/
|
||||
|
@ -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 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 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 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
|
||||
|
||||
@ -143,7 +146,7 @@ bool BMFile_Create(
|
||||
bool BMFile_Save(
|
||||
BMPARAM_IN(BMap::BMFile*, map_file),
|
||||
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(LibCmo::CKINT, compreess_level)) {
|
||||
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());
|
||||
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
|
||||
|
||||
@ -841,34 +859,34 @@ bool BMMesh_SetMaterialSlot(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCm
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region CK3dObject
|
||||
#pragma region CK3dEntity
|
||||
|
||||
bool BM3dObject_GetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxMatrix, out_mat)) {
|
||||
auto obj = CheckCK3dObject(bmfile, objid);
|
||||
bool BM3dEntity_GetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxMatrix, out_mat)) {
|
||||
auto obj = CheckCK3dEntity(bmfile, objid);
|
||||
if (obj == nullptr) return false;
|
||||
|
||||
BMPARAM_OUT_ASSIGN(out_mat, obj->GetWorldMatrix());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BM3dObject_SetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxMatrix, mat)) {
|
||||
auto obj = CheckCK3dObject(bmfile, objid);
|
||||
bool BM3dEntity_SetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxMatrix, mat)) {
|
||||
auto obj = CheckCK3dEntity(bmfile, objid);
|
||||
if (obj == nullptr) return false;
|
||||
|
||||
obj->SetWorldMatrix(mat);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BM3dObject_GetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_meshid)) {
|
||||
auto obj = CheckCK3dObject(bmfile, objid);
|
||||
bool BM3dEntity_GetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_meshid)) {
|
||||
auto obj = CheckCK3dEntity(bmfile, objid);
|
||||
if (obj == nullptr) return false;
|
||||
|
||||
BMPARAM_OUT_ASSIGN(out_meshid, SafeGetID(obj->GetCurrentMesh()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BM3dObject_SetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, meshid)) {
|
||||
auto obj = CheckCK3dObject(bmfile, objid);
|
||||
bool BM3dEntity_SetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, meshid)) {
|
||||
auto obj = CheckCK3dEntity(bmfile, objid);
|
||||
auto meshobj = CheckCKMesh(bmfile, meshid);
|
||||
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;
|
||||
}
|
||||
|
||||
bool BM3dObject_GetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_isVisible)) {
|
||||
auto obj = CheckCK3dObject(bmfile, objid);
|
||||
bool BM3dEntity_GetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_isVisible)) {
|
||||
auto obj = CheckCK3dEntity(bmfile, objid);
|
||||
if (obj == nullptr) return false;
|
||||
|
||||
BMPARAM_OUT_ASSIGN(out_isVisible, obj->IsVisible());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BM3dObject_SetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, is_visible)) {
|
||||
auto obj = CheckCK3dObject(bmfile, objid);
|
||||
bool BM3dEntity_SetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, is_visible)) {
|
||||
auto obj = CheckCK3dEntity(bmfile, objid);
|
||||
if (obj == nullptr) return false;
|
||||
|
||||
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 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
|
||||
|
@ -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?
|
||||
#define BMAP_RAW_EXPORT
|
||||
#define BMAP_RAW_IMPORT
|
||||
#pragma error "Unknown dynamic link import/export semantics."
|
||||
#error "Unknown dynamic link import/export semantics."
|
||||
#endif
|
||||
|
||||
// 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 */
|
||||
#define BMPARAM_IN(_t, _name) _t _name
|
||||
/**
|
||||
@brief
|
||||
Declare an output parameter.
|
||||
@details
|
||||
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.
|
||||
@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.
|
||||
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
|
||||
/** 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_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_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
|
||||
|
||||
@ -285,13 +290,52 @@ BMAP_EXPORT bool BMMesh_SetMaterialSlot(BMPARAM_OBJECT_DECL(bmfile, objid), BMPA
|
||||
|
||||
#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 BM3dObject_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 BM3dObject_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 BM3dObject_SetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, is_visible));
|
||||
BMAP_EXPORT bool BM3dEntity_GetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxMatrix, out_mat));
|
||||
BMAP_EXPORT bool BM3dEntity_SetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxMatrix, mat));
|
||||
BMAP_EXPORT bool BM3dEntity_GetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_meshid));
|
||||
BMAP_EXPORT bool BM3dEntity_SetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, meshid));
|
||||
BMAP_EXPORT bool BM3dEntity_GetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_isVisible));
|
||||
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
|
||||
|
386
BMap/BMap.cpp
386
BMap/BMap.cpp
@ -2,6 +2,247 @@
|
||||
|
||||
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
|
||||
|
||||
BMMeshTransition::TransitionVertex::TransitionVertex(
|
||||
@ -229,149 +470,4 @@ namespace BMap {
|
||||
|
||||
#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
|
||||
|
||||
}
|
||||
|
134
BMap/BMap.hpp
134
BMap/BMap.hpp
@ -16,93 +16,95 @@ namespace BMap {
|
||||
~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.
|
||||
These function will block all other functions if this class init failed.
|
||||
Or, block any more operations if this class has loaded or saved once. In this time you only can free this class
|
||||
/*
|
||||
Safe Check Function will make sure this class is visited in safe mode.
|
||||
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.
|
||||
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:
|
||||
bool IsInitError() {
|
||||
return m_IsInitError;
|
||||
}
|
||||
|
||||
private:
|
||||
bool CanExecLoad() {
|
||||
// no error, is loader, no prev load
|
||||
return (!m_IsInitError && m_IsLoader && !m_HasLoaded);
|
||||
}
|
||||
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);
|
||||
}
|
||||
/**
|
||||
* @brief Check whether there is an error when initializing this class.
|
||||
* @details
|
||||
* This class is exposed for outside code to check.
|
||||
* Internal code should use one of following 4 private check functions to check environment.
|
||||
* @return True if there is an error when initializing this class.
|
||||
*/
|
||||
bool IsInitError();
|
||||
|
||||
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:
|
||||
/**
|
||||
* @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);
|
||||
/**
|
||||
* @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);
|
||||
|
||||
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:
|
||||
LibCmo::CKDWORD 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 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;
|
||||
LibCmo::CKDWORD CommonGetObjectCount(std::vector<LibCmo::CK2::CK_ID>& container);
|
||||
LibCmo::CK2::CK_ID CommonGetObject(std::vector<LibCmo::CK2::CK_ID>& container, LibCmo::CKDWORD idx);
|
||||
LibCmo::CK2::CK_ID CommonCreateObject(std::vector<LibCmo::CK2::CK_ID>& container, LibCmo::CK2::CK_CLASSID cid);
|
||||
|
||||
// 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:
|
||||
LibCmo::CKDWORD GetGroupCount();
|
||||
LibCmo::CK2::CK_ID GetGroup(LibCmo::CKDWORD idx);
|
||||
@ -119,15 +121,19 @@ namespace BMap {
|
||||
LibCmo::CKDWORD GetTextureCount();
|
||||
LibCmo::CK2::CK_ID GetTexture(LibCmo::CKDWORD idx);
|
||||
LibCmo::CK2::CK_ID CreateTexture();
|
||||
LibCmo::CKDWORD GetTargetLightCount();
|
||||
LibCmo::CK2::CK_ID GetTargetLight(LibCmo::CKDWORD idx);
|
||||
LibCmo::CK2::CK_ID CreateTargetLight();
|
||||
|
||||
private:
|
||||
LibCmo::CK2::CKContext* m_Context;
|
||||
|
||||
std::vector<LibCmo::CK2::CK_ID> m_ObjGroups;
|
||||
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_ObjTextures;
|
||||
std::vector<LibCmo::CK2::CK_ID> m_ObjTargetLights;
|
||||
|
||||
};
|
||||
|
||||
|
@ -453,6 +453,28 @@ namespace BMapSharp {
|
||||
[DllImport(g_DllName, EntryPoint = "BMFile_CreateTexture", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
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>
|
||||
/// <param name="out_trans">Type: BMap::BMMeshTransition*. This is OUT parameter. </param>
|
||||
/// <returns>True if no error, otherwise False.</returns>
|
||||
@ -1151,54 +1173,198 @@ namespace BMapSharp {
|
||||
[DllImport(g_DllName, EntryPoint = "BMMesh_SetMaterialSlot", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
|
||||
[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);
|
||||
/// <summary>BM3dObject_GetWorldMatrix</summary>
|
||||
/// <summary>BM3dEntity_GetWorldMatrix</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_mat">Type: LibCmo::VxMath::VxMatrix. This is OUT parameter. </param>
|
||||
/// <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)]
|
||||
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);
|
||||
/// <summary>BM3dObject_SetWorldMatrix</summary>
|
||||
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>BM3dEntity_SetWorldMatrix</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="mat">Type: LibCmo::VxMath::VxMatrix. </param>
|
||||
/// <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)]
|
||||
internal static extern bool BM3dObject_SetWorldMatrix([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.Struct)] VxMatrix mat);
|
||||
/// <summary>BM3dObject_GetCurrentMesh</summary>
|
||||
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>BM3dEntity_GetCurrentMesh</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_meshid">Type: LibCmo::CK2::CK_ID. This is OUT parameter. </param>
|
||||
/// <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)]
|
||||
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);
|
||||
/// <summary>BM3dObject_SetCurrentMesh</summary>
|
||||
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>BM3dEntity_SetCurrentMesh</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="meshid">Type: LibCmo::CK2::CK_ID. </param>
|
||||
/// <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)]
|
||||
internal static extern bool BM3dObject_SetCurrentMesh([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint meshid);
|
||||
/// <summary>BM3dObject_GetVisibility</summary>
|
||||
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>BM3dEntity_GetVisibility</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_isVisible">Type: bool. This is OUT parameter. </param>
|
||||
/// <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)]
|
||||
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);
|
||||
/// <summary>BM3dObject_SetVisibility</summary>
|
||||
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>BM3dEntity_SetVisibility</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="is_visible">Type: bool. </param>
|
||||
/// <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)]
|
||||
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 #####
|
||||
|
||||
|
@ -352,7 +352,7 @@ namespace BMapSharp.BMapWrapper {
|
||||
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() {
|
||||
@ -375,24 +375,61 @@ namespace BMapSharp.BMapWrapper {
|
||||
|
||||
}
|
||||
|
||||
public class BM3dObject : BMObject {
|
||||
internal BM3dObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
||||
public class BM3dEntity : BMObject {
|
||||
internal BM3dEntity(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
||||
|
||||
public VxMatrix GetWorldMatrix() => getGenericValue<VxMatrix>(BMap.BM3dObject_GetWorldMatrix);
|
||||
public void SetWorldMatrix(VxMatrix mat) => setGenericValue<VxMatrix>(BMap.BM3dObject_SetWorldMatrix, mat);
|
||||
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.BM3dObject_GetCurrentMesh(getPointer(), getCKID(), out uint out_meshid));
|
||||
BMapException.ThrowIfFailed(BMap.BM3dEntity_GetCurrentMesh(getPointer(), getCKID(), out uint out_meshid));
|
||||
if (out_meshid == Utils.INVALID_CKID) return null;
|
||||
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.BM3dObject_SetCurrentMesh(getPointer(), getCKID(), meshid));
|
||||
BMapException.ThrowIfFailed(BMap.BM3dEntity_SetCurrentMesh(getPointer(), getCKID(), meshid));
|
||||
}
|
||||
|
||||
public bool GetVisibility() => getGenericValue<bool>(BMap.BM3dObject_GetVisibility);
|
||||
public void SetVisibility(bool visb) => setGenericValue<bool>(BMap.BM3dObject_SetVisibility, visb);
|
||||
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 {
|
||||
@ -463,6 +500,10 @@ namespace BMapSharp.BMapWrapper {
|
||||
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));
|
||||
|
||||
}
|
||||
|
||||
@ -504,6 +545,7 @@ namespace BMapSharp.BMapWrapper {
|
||||
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 {
|
||||
|
@ -226,6 +226,13 @@ namespace BMapSharp.VirtoolsTypes {
|
||||
_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 {
|
||||
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. */
|
||||
|
@ -4,6 +4,10 @@
|
||||
<ProjectReference Include="..\BMapSharp\BMapSharp.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
|
@ -3,11 +3,19 @@ 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()) {
|
||||
@ -21,10 +29,10 @@ namespace BMapSharpTestbench {
|
||||
Console.ReadKey(true);
|
||||
|
||||
// Start testbench
|
||||
string file_name = "Level_02.NMO";
|
||||
string temp_folder = "Temp";
|
||||
string texture_folder = "F:\\Ballance\\Ballance\\Textures";
|
||||
string[] encodings = ["cp1252", "gb2312"];
|
||||
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);
|
||||
@ -36,6 +44,53 @@ namespace BMapSharpTestbench {
|
||||
|
||||
}
|
||||
|
||||
class BMapSharpArguments {
|
||||
public string mFileName;
|
||||
public string mTempFolder;
|
||||
public string mTextureFolder;
|
||||
public string[] mEncodings;
|
||||
}
|
||||
|
||||
static BMapSharpArguments ResolveArguments(string[] args) {
|
||||
// define arguments
|
||||
var fileNameOpt = new Option<string>
|
||||
("--file-path", "The path to input Virtools file.");
|
||||
fileNameOpt.IsRequired = true;
|
||||
var tempFolderOpt = new Option<string>
|
||||
("--temp-dir", "The temp folder used by BMap.");
|
||||
tempFolderOpt.IsRequired = true;
|
||||
var textureFolderOpt = new Option<string>
|
||||
("--texture-dir", "The texture folder containing Ballance texture resources.");
|
||||
textureFolderOpt.IsRequired = true;
|
||||
var encodingsOpt = new Option<IEnumerable<string>>
|
||||
("--encodings", "The encodings used to parse the names stroed in input Virtools file.");
|
||||
encodingsOpt.IsRequired = true;
|
||||
encodingsOpt.Arity = ArgumentArity.OneOrMore;
|
||||
encodingsOpt.AllowMultipleArgumentsPerToken = true;
|
||||
|
||||
// init root command
|
||||
var rootCommand = new RootCommand("The testbench of BMapSharp.");
|
||||
rootCommand.Add(fileNameOpt);
|
||||
rootCommand.Add(tempFolderOpt);
|
||||
rootCommand.Add(textureFolderOpt);
|
||||
rootCommand.Add(encodingsOpt);
|
||||
|
||||
// init result container
|
||||
BMapSharpArguments ret = new BMapSharpArguments();
|
||||
// set handler
|
||||
rootCommand.SetHandler((context) => {
|
||||
ret.mFileName = context.ParseResult.GetValueForOption(fileNameOpt);
|
||||
ret.mTempFolder = context.ParseResult.GetValueForOption(tempFolderOpt);
|
||||
ret.mTextureFolder = context.ParseResult.GetValueForOption(textureFolderOpt);
|
||||
ret.mEncodings = context.ParseResult.GetValueForOption(encodingsOpt).ToArray();
|
||||
context.ExitCode = 61;
|
||||
});
|
||||
|
||||
// execute root command and return value.
|
||||
if (rootCommand.Invoke(args) != 61) return null;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void TestCommon(BMapSharp.BMapWrapper.BMFileReader reader) {
|
||||
// Console.WriteLine("===== Groups =====");
|
||||
// foreach (var gp in reader.GetGroups()) {
|
||||
@ -66,38 +121,38 @@ namespace BMapSharpTestbench {
|
||||
// Console.WriteLine($"\tMaterial Slot Count: {mesh.GetMaterialSlotCount()}");
|
||||
// }
|
||||
|
||||
Console.WriteLine("===== Materials =====");
|
||||
foreach (var mtl in reader.GetMaterials()) {
|
||||
Console.WriteLine(mtl.GetName());
|
||||
// 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($"\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($"\tSpecular Power: {mtl.GetSpecularPower()}");
|
||||
|
||||
Console.WriteLine($"\tTexture Border Color: {mtl.GetTextureBorderColor().ToManagedRGBA()}");
|
||||
// Console.WriteLine($"\tTexture Border Color: {mtl.GetTextureBorderColor().ToManagedRGBA()}");
|
||||
|
||||
Console.WriteLine($"\tTexture Blend Mode: {mtl.GetTextureBlendMode()}");
|
||||
Console.WriteLine($"\tTexture 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($"\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 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 Ref: {mtl.GetAlphaRef()}");
|
||||
|
||||
Console.WriteLine($"\tAlpha Func: {mtl.GetAlphaFunc()}");
|
||||
Console.WriteLine($"\tZ Func: {mtl.GetZFunc()}");
|
||||
}
|
||||
// Console.WriteLine($"\tAlpha Func: {mtl.GetAlphaFunc()}");
|
||||
// Console.WriteLine($"\tZ Func: {mtl.GetZFunc()}");
|
||||
// }
|
||||
|
||||
// Console.WriteLine("===== Textures =====");
|
||||
// foreach (var tex in reader.GetTextures()) {
|
||||
@ -108,6 +163,24 @@ namespace BMapSharpTestbench {
|
||||
// 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 =====");
|
||||
}
|
||||
|
||||
@ -119,7 +192,7 @@ namespace BMapSharpTestbench {
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Prepare test variables
|
||||
var all_3dobjects = new List<BM3dObject>(reader.Get3dObjects());
|
||||
var first_3dobj = all_3dobjects[0];
|
||||
|
@ -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 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`.
|
||||
|
@ -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.
|
||||
# @return True if no error, otherwise False.
|
||||
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
|
||||
# @param out_trans[out] Type: BMap::BMMeshTransition*. Use ctypes.byref(data) pass it.
|
||||
# @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.
|
||||
# @return True if no error, otherwise False.
|
||||
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 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.
|
||||
# @return True if no error, otherwise False.
|
||||
BM3dObject_GetWorldMatrix = _create_bmap_func('BM3dObject_GetWorldMatrix', [bm_void_p, bm_CKID, bm_VxMatrix_p])
|
||||
## BM3dObject_SetWorldMatrix
|
||||
BM3dEntity_GetWorldMatrix = _create_bmap_func('BM3dEntity_GetWorldMatrix', [bm_void_p, bm_CKID, bm_VxMatrix_p])
|
||||
## BM3dEntity_SetWorldMatrix
|
||||
# @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 mat[in] Type: LibCmo::VxMath::VxMatrix.
|
||||
# @return True if no error, otherwise False.
|
||||
BM3dObject_SetWorldMatrix = _create_bmap_func('BM3dObject_SetWorldMatrix', [bm_void_p, bm_CKID, bm_VxMatrix])
|
||||
## BM3dObject_GetCurrentMesh
|
||||
BM3dEntity_SetWorldMatrix = _create_bmap_func('BM3dEntity_SetWorldMatrix', [bm_void_p, bm_CKID, bm_VxMatrix])
|
||||
## BM3dEntity_GetCurrentMesh
|
||||
# @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_meshid[out] Type: LibCmo::CK2::CK_ID. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BM3dObject_GetCurrentMesh = _create_bmap_func('BM3dObject_GetCurrentMesh', [bm_void_p, bm_CKID, bm_CKID_p])
|
||||
## BM3dObject_SetCurrentMesh
|
||||
BM3dEntity_GetCurrentMesh = _create_bmap_func('BM3dEntity_GetCurrentMesh', [bm_void_p, bm_CKID, bm_CKID_p])
|
||||
## BM3dEntity_SetCurrentMesh
|
||||
# @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 meshid[in] Type: LibCmo::CK2::CK_ID.
|
||||
# @return True if no error, otherwise False.
|
||||
BM3dObject_SetCurrentMesh = _create_bmap_func('BM3dObject_SetCurrentMesh', [bm_void_p, bm_CKID, bm_CKID])
|
||||
## BM3dObject_GetVisibility
|
||||
BM3dEntity_SetCurrentMesh = _create_bmap_func('BM3dEntity_SetCurrentMesh', [bm_void_p, bm_CKID, bm_CKID])
|
||||
## BM3dEntity_GetVisibility
|
||||
# @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_isVisible[out] Type: bool. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BM3dObject_GetVisibility = _create_bmap_func('BM3dObject_GetVisibility', [bm_void_p, bm_CKID, bm_bool_p])
|
||||
## BM3dObject_SetVisibility
|
||||
BM3dEntity_GetVisibility = _create_bmap_func('BM3dEntity_GetVisibility', [bm_void_p, bm_CKID, bm_bool_p])
|
||||
## BM3dEntity_SetVisibility
|
||||
# @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 is_visible[in] Type: bool.
|
||||
# @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 #####
|
||||
|
||||
|
@ -476,10 +476,10 @@ class BMMesh(BMObject):
|
||||
except StopIteration:
|
||||
_Utils.raise_out_of_length_exception()
|
||||
|
||||
class BM3dObject(BMObject):
|
||||
class BM3dEntity(BMObject):
|
||||
def get_world_matrix(self) -> virtools_types.VxMatrix:
|
||||
mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix()
|
||||
bmap.BM3dObject_GetWorldMatrix(self._get_pointer(), self._get_ckid(), ctypes.byref(mat))
|
||||
bmap.BM3dEntity_GetWorldMatrix(self._get_pointer(), self._get_ckid(), ctypes.byref(mat))
|
||||
# use cast & pointer to get matrix data conveniently
|
||||
flat: bmap.bm_CKFLOAT_p = ctypes.cast(ctypes.byref(mat), bmap.bm_CKFLOAT_p)
|
||||
ret: virtools_types.VxMatrix = virtools_types.VxMatrix()
|
||||
@ -489,11 +489,11 @@ class BM3dObject(BMObject):
|
||||
def set_world_matrix(self, mat_: virtools_types.VxMatrix) -> None:
|
||||
# star syntax expand the tuple as the argument.
|
||||
mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix(*(mat_.to_const()))
|
||||
bmap.BM3dObject_SetWorldMatrix(self._get_pointer(), self._get_ckid(), mat)
|
||||
bmap.BM3dEntity_SetWorldMatrix(self._get_pointer(), self._get_ckid(), mat)
|
||||
|
||||
def get_current_mesh(self) -> BMMesh | None:
|
||||
ckid: bmap.bm_CKID = bmap.bm_CKID()
|
||||
bmap.BM3dObject_GetCurrentMesh(self._get_pointer(), self._get_ckid(), ctypes.byref(ckid))
|
||||
bmap.BM3dEntity_GetCurrentMesh(self._get_pointer(), self._get_ckid(), ctypes.byref(ckid))
|
||||
if ckid.value == g_InvalidCKID:
|
||||
return None
|
||||
else:
|
||||
@ -503,12 +503,60 @@ class BM3dObject(BMObject):
|
||||
ckid: bmap.bm_CKID = bmap.bm_CKID(g_InvalidCKID)
|
||||
if mesh is not None:
|
||||
ckid = mesh._get_ckid()
|
||||
bmap.BM3dObject_SetCurrentMesh(self._get_pointer(), self._get_ckid(), ckid)
|
||||
bmap.BM3dEntity_SetCurrentMesh(self._get_pointer(), self._get_ckid(), ckid)
|
||||
|
||||
def get_visibility(self) -> bool:
|
||||
return self._get_bool_value(bmap.BM3dObject_GetVisibility)
|
||||
return self._get_bool_value(bmap.BM3dEntity_GetVisibility)
|
||||
def set_visibility(self, visb_: bool) -> None:
|
||||
self._set_bool_value(bmap.BM3dObject_SetVisibility, visb_)
|
||||
self._set_bool_value(bmap.BM3dEntity_SetVisibility, visb_)
|
||||
|
||||
class BM3dObject(BM3dEntity):
|
||||
pass
|
||||
|
||||
class BMLight(BM3dEntity):
|
||||
def get_type(self) -> virtools_types.VXLIGHT_TYPE:
|
||||
return self._get_enum_value(virtools_types.VXLIGHT_TYPE, bmap.BMLight_GetType)
|
||||
def set_type(self, data_: virtools_types.VXLIGHT_TYPE) -> None:
|
||||
self._set_enum_value(bmap.BMLight_SetType, data_)
|
||||
|
||||
def get_color(self) -> virtools_types.VxColor:
|
||||
return self._get_vxcolor_value(bmap.BMLight_GetColor)
|
||||
def set_color(self, col: virtools_types.VxColor) -> None:
|
||||
self._set_vxcolor_value(bmap.BMLight_SetColor, col)
|
||||
|
||||
def get_constant_attenuation(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetConstantAttenuation)
|
||||
def set_constant_attenuation(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetConstantAttenuation, val_)
|
||||
def get_linear_attenuation(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetLinearAttenuation)
|
||||
def set_linear_attenuation(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetLinearAttenuation, val_)
|
||||
def get_quadratic_attenuation(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetQuadraticAttenuation)
|
||||
def set_quadratic_attenuation(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetQuadraticAttenuation, val_)
|
||||
|
||||
def get_range(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetRange)
|
||||
def set_range(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetRange, val_)
|
||||
|
||||
def get_hot_spot(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetHotSpot)
|
||||
def set_hot_spot(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetHotSpot, val_)
|
||||
def get_falloff(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetFalloff)
|
||||
def set_falloff(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetFalloff, val_)
|
||||
def get_falloff_shape(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetFalloffShape)
|
||||
def set_falloff_shape(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetFalloffShape, val_)
|
||||
|
||||
class BMTargetLight(BMLight):
|
||||
pass
|
||||
|
||||
class BMGroup(BMObject):
|
||||
def add_object(self, member: BM3dObject) -> None:
|
||||
@ -603,6 +651,10 @@ class BMFileReader(_AbstractPointer):
|
||||
return self.__get_ckobject_count(bmap.BMFile_GetGroupCount)
|
||||
def get_groups(self) -> typing.Iterator[BMGroup]:
|
||||
return self.__get_ckobjects(BMGroup, bmap.BMFile_GetGroupCount, bmap.BMFile_GetGroup)
|
||||
def get_target_light_count(self) -> int:
|
||||
return self.__get_ckobject_count(bmap.BMFile_GetTargetLightCount)
|
||||
def get_target_lights(self) -> typing.Iterator[BMTargetLight]:
|
||||
return self.__get_ckobjects(BMTargetLight, bmap.BMFile_GetTargetLightCount, bmap.BMFile_GetTargetLight)
|
||||
|
||||
class BMFileWriter(_AbstractPointer):
|
||||
def __init__(self, temp_folder_: str, texture_folder_: str, encodings_: tuple[str]):
|
||||
@ -663,6 +715,8 @@ class BMFileWriter(_AbstractPointer):
|
||||
return self.__create_ckobject(BM3dObject, bmap.BMFile_Create3dObject)
|
||||
def create_group(self) -> BMGroup:
|
||||
return self.__create_ckobject(BMGroup, bmap.BMFile_CreateGroup)
|
||||
def create_target_light(self) -> BMTargetLight:
|
||||
return self.__create_ckobject(BMTargetLight, bmap.BMFile_CreateTargetLight)
|
||||
|
||||
class BMMeshTrans(_AbstractPointer):
|
||||
def __init__(self):
|
||||
|
@ -221,6 +221,15 @@ class VX_PIXELFORMAT(enum.IntEnum):
|
||||
_4_ABGR8888_CLUT = 30 ##< 4 bits indexed CLUT (ABGR)
|
||||
_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):
|
||||
"""!
|
||||
Blend Mode Flags
|
||||
|
@ -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`.
|
||||
|
||||
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`.
|
||||
|
@ -1,13 +1,14 @@
|
||||
import os
|
||||
import argparse
|
||||
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...')
|
||||
|
||||
file_name: str = 'Level_02.NMO'
|
||||
temp_folder: str = 'Temp'
|
||||
texture_folder: str = 'F:\\Ballance\\Ballance\\Textures'
|
||||
encodings: tuple[str, ...] = ('cp1252', )
|
||||
# file_name: str = 'LightCameraTest.nmo'
|
||||
# temp_folder: str = 'Temp'
|
||||
# texture_folder: str = 'F:\\Ballance\\Ballance\\Textures'
|
||||
# encodings: tuple[str, ...] = ('cp1252', )
|
||||
with bmap.BMFileReader(file_name, temp_folder, texture_folder, encodings) as reader:
|
||||
test_common(reader)
|
||||
test_equatable(reader)
|
||||
@ -38,37 +39,37 @@ def test_common(reader: bmap.BMFileReader):
|
||||
# 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('===== Materials =====')
|
||||
# for mtl in reader.get_materials():
|
||||
# print(mtl.get_name())
|
||||
|
||||
print(f'\tDiffuse: {mtl.get_diffuse().to_const_rgba()}')
|
||||
print(f'\tAmbient: {mtl.get_ambient().to_const_rgba()}')
|
||||
print(f'\tSpecular: {mtl.get_specular().to_const_rgba()}')
|
||||
print(f'\tEmissive: {mtl.get_emissive().to_const_rgba()}')
|
||||
# print(f'\tDiffuse: {mtl.get_diffuse().to_const_rgba()}')
|
||||
# print(f'\tAmbient: {mtl.get_ambient().to_const_rgba()}')
|
||||
# print(f'\tSpecular: {mtl.get_specular().to_const_rgba()}')
|
||||
# print(f'\tEmissive: {mtl.get_emissive().to_const_rgba()}')
|
||||
|
||||
print(f'\tSpecular Power: {mtl.get_specular_power()}')
|
||||
# print(f'\tSpecular Power: {mtl.get_specular_power()}')
|
||||
|
||||
print(f'\tTexture Border Color: {mtl.get_texture_border_color().to_const_rgba()}')
|
||||
# print(f'\tTexture Border Color: {mtl.get_texture_border_color().to_const_rgba()}')
|
||||
|
||||
print(f'\tTexture Blend Mode: {mtl.get_texture_blend_mode()}')
|
||||
print(f'\tTexture 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'\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 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 Ref: {mtl.get_alpha_ref()}')
|
||||
|
||||
print(f'\tAlpha Func: {mtl.get_alpha_func()}')
|
||||
print(f'\tZ Func: {mtl.get_z_func()}')
|
||||
# print(f'\tAlpha Func: {mtl.get_alpha_func()}')
|
||||
# print(f'\tZ Func: {mtl.get_z_func()}')
|
||||
|
||||
# print('===== Textures =====')
|
||||
# for tex in reader.get_textures():
|
||||
@ -78,6 +79,23 @@ def test_common(reader: bmap.BMFileReader):
|
||||
# print(f'\tSave Options: {tex.get_save_options()}')
|
||||
# print(f'\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 =====')
|
||||
|
||||
def test_equatable(reader: bmap.BMFileReader):
|
||||
@ -129,4 +147,32 @@ def test_equatable(reader: bmap.BMFileReader):
|
||||
assert second_3dobj in test_dict
|
||||
|
||||
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
6
CMake/VTVersion.hpp.in
Normal 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@"
|
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
project(NeMo
|
||||
VERSION 0.2.0
|
||||
VERSION 0.3.0
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
@ -53,7 +53,7 @@ endif ()
|
||||
install(EXPORT LibCmoTargets
|
||||
FILE LibCmoTargets.cmake
|
||||
NAMESPACE NeMo::
|
||||
DESTINATION ${YYCC_INSTALL_LIB_PATH}/cmake/LibCmo
|
||||
DESTINATION ${NEMO_INSTALL_LIB_PATH}/cmake/LibCmo
|
||||
)
|
||||
# Package configuration file
|
||||
include(CMakePackageConfigHelpers)
|
||||
@ -65,7 +65,7 @@ write_basic_package_version_file(
|
||||
configure_package_config_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/CMake/LibCmoConfig.cmake.in
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfig.cmake"
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LibCmo
|
||||
INSTALL_DESTINATION ${NEMO_INSTALL_LIB_PATH}/cmake/LibCmo
|
||||
)
|
||||
# Copy package files to install destination
|
||||
install(
|
||||
@ -73,5 +73,5 @@ FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfig.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/LibCmoConfigVersion.cmake"
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}/cmake/LibCmo
|
||||
${NEMO_INSTALL_LIB_PATH}/cmake/LibCmo
|
||||
)
|
||||
|
@ -188,6 +188,7 @@ public class CSharpWriter {
|
||||
break;
|
||||
case "CK_TEXTURE_SAVEOPTIONS":
|
||||
case "VX_PIXELFORMAT":
|
||||
case "VXLIGHT_TYPE":
|
||||
case "VXTEXTURE_BLENDMODE":
|
||||
case "VXTEXTURE_FILTERMODE":
|
||||
case "VXTEXTURE_ADDRESSMODE":
|
||||
|
@ -28,6 +28,7 @@ public class PythonWriter {
|
||||
cache.put("VxMatrix", "VxMatrix");
|
||||
cache.put("CK_TEXTURE_SAVEOPTIONS", "enum");
|
||||
cache.put("VX_PIXELFORMAT", "enum");
|
||||
cache.put("VXLIGHT_TYPE", "enum");
|
||||
cache.put("VXTEXTURE_BLENDMODE", "enum");
|
||||
cache.put("VXTEXTURE_FILTERMODE", "enum");
|
||||
cache.put("VXTEXTURE_ADDRESSMODE", "enum");
|
||||
|
@ -170,6 +170,14 @@ public class MainRunner {
|
||||
PythonWriter.writeAccVal("dest/CK_BITMAPDATA_FLAGS.AccVal.py", 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.
|
||||
System.out.println("DONE!");
|
||||
}
|
||||
|
4
CodeGen/EnumsMigration/src/CK_CAMERA_PROJECTION.txt
Normal file
4
CodeGen/EnumsMigration/src/CK_CAMERA_PROJECTION.txt
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
#define CK_PERSPECTIVEPROJECTION 1
|
||||
|
||||
#define CK_ORTHOGRAPHICPROJECTION 2
|
@ -41,6 +41,25 @@ typedef enum VX_PIXELFORMAT {
|
||||
_4_ARGB8888_CLUT = 31 // 4 bits indexed CLUT (ARGB)
|
||||
} 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}
|
||||
Summary: Blend Mode Flags
|
||||
|
3
CodeGen/VectorGen/.gitignore
vendored
3
CodeGen/VectorGen/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
# Result
|
||||
*.hpp
|
||||
VxTypes.hpp
|
||||
VxTypes.cpp
|
||||
|
@ -1,3 +1,3 @@
|
||||
# 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.
|
||||
|
178
CodeGen/VectorGen/VxTypes.cpp.jinja
Normal file
178
CodeGen/VectorGen/VxTypes.cpp.jinja
Normal 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
|
65
CodeGen/VectorGen/VxTypes.hpp.jinja
Normal file
65
CodeGen/VectorGen/VxTypes.hpp.jinja
Normal 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 ===== */
|
||||
};
|
21
CodeGen/VectorGen/VxTypes.shared.jinja
Normal file
21
CodeGen/VectorGen/VxTypes.shared.jinja
Normal 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 %}
|
63
CodeGen/VectorGen/VxVectorGen.py
Normal file
63
CodeGen/VectorGen/VxVectorGen.py
Normal 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', ))
|
@ -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', )))
|
@ -264,8 +264,7 @@ namespace LibCmo::CK2 {
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, fmt);
|
||||
XContainer::XString result;
|
||||
YYCC::StringHelper::VPrintf(fmt, argptr);
|
||||
XContainer::XString result(YYCC::StringHelper::VPrintf(fmt, argptr));
|
||||
va_end(argptr);
|
||||
|
||||
// use c_str(), not XContainer::NSXString::ToCKSTRING because we want make sure this paramter is not nullptr.
|
||||
|
@ -141,6 +141,28 @@ namespace LibCmo::CK2 {
|
||||
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
|
||||
|
||||
|
||||
|
@ -256,4 +256,9 @@ namespace LibCmo::CK2 {
|
||||
CKBITMAPDATA_DYNAMIC = 64,
|
||||
};
|
||||
|
||||
enum class CK_CAMERA_PROJECTION : CKDWORD {
|
||||
CK_PERSPECTIVEPROJECTION = 1,
|
||||
CK_ORTHOGRAPHICPROJECTION = 2,
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -44,9 +44,9 @@ namespace LibCmo::CK2 {
|
||||
|
||||
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* GetBase(void) { return this->m_MemBegin; }
|
||||
CKDWORD GetSize(void) { return this->m_MemSize; }
|
||||
CKDWORD GetCursor(void) { return this->m_MemPos; }
|
||||
void* GetBase() { return this->m_MemBegin; }
|
||||
CKDWORD GetSize() { return this->m_MemSize; }
|
||||
CKDWORD GetCursor() { return this->m_MemPos; }
|
||||
void MoveCursor(CKINT off) { this->m_MemPos += off; }
|
||||
void SetCursor(CKDWORD off) { this->m_MemPos = off; }
|
||||
void Read(void* data, CKDWORD data_size) {
|
||||
|
@ -89,20 +89,49 @@ namespace LibCmo::CK2 {
|
||||
// reset crc field of header
|
||||
rawHeader.Crc = 0u;
|
||||
|
||||
// compute crc
|
||||
// Compute and check CRC in theory (< Virtools 4.0)
|
||||
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);
|
||||
parser->MoveCursor(this->m_FileInfo.Hdr1PackSize);
|
||||
gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_FileInfo.DataPackSize, gotten_crc);
|
||||
|
||||
if (gotten_crc != this->m_FileInfo.Crc) {
|
||||
this->m_Ctx->OutputToConsole(u8"Virtools file CRC error.");
|
||||
return CKERROR::CKERR_FILECRCERROR;
|
||||
// MARK:
|
||||
// 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
|
||||
parser->SetCursor(sizeof(CKRawFileInfo));
|
||||
parser->SetCursor(CKSizeof(CKRawFileInfo));
|
||||
|
||||
// compare size to decide wheher use compress feature
|
||||
if (this->m_FileInfo.Hdr1PackSize != this->m_FileInfo.Hdr1UnPackSize) {
|
||||
@ -189,7 +218,7 @@ namespace LibCmo::CK2 {
|
||||
if (this->m_FileInfo.FileVersion >= 8) {
|
||||
// file ver >= 8, use header offset
|
||||
// because it have compress feature
|
||||
ParserPtr->SetCursor(this->m_FileInfo.Hdr1PackSize + sizeof(CKRawFileInfo));
|
||||
ParserPtr->SetCursor(this->m_FileInfo.Hdr1PackSize + CKSizeof(CKRawFileInfo));
|
||||
} else {
|
||||
// otherwise, sync with current parser.
|
||||
ParserPtr->SetCursor(parser->GetCursor());
|
||||
@ -397,7 +426,7 @@ namespace LibCmo::CK2 {
|
||||
}
|
||||
|
||||
// ========== finalize work ==========
|
||||
|
||||
|
||||
|
||||
// set done flag and return
|
||||
this->m_Done = true;
|
||||
|
@ -20,6 +20,10 @@
|
||||
#include "ObjImpls/CKTexture.hpp"
|
||||
#include "ObjImpls/CKMaterial.hpp"
|
||||
#include "ObjImpls/CKMesh.hpp"
|
||||
#include "ObjImpls/CKLight.hpp"
|
||||
#include "ObjImpls/CKTargetLight.hpp"
|
||||
#include "ObjImpls/CKCamera.hpp"
|
||||
#include "ObjImpls/CKTargetCamera.hpp"
|
||||
|
||||
namespace LibCmo::CK2 {
|
||||
|
||||
@ -439,6 +443,10 @@ CKClassRegister(cid, parentCid, \
|
||||
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::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 EasyClassRegWithNotify
|
||||
|
@ -265,8 +265,8 @@ namespace LibCmo::CK2 {
|
||||
#pragma region Read Function
|
||||
|
||||
public:
|
||||
void StartRead(void);
|
||||
void StopRead(void);
|
||||
void StartRead();
|
||||
void StopRead();
|
||||
|
||||
/* ========== Identifier Functions ==========*/
|
||||
|
||||
@ -556,7 +556,7 @@ namespace LibCmo::CK2 {
|
||||
/*
|
||||
* Actually this function mix various functions, including CloseChunk(), UpdateSize() and etc.
|
||||
*/
|
||||
void StopWrite(void);
|
||||
void StopWrite();
|
||||
|
||||
|
||||
/* ========== Identifier Functions ==========*/
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
namespace LibCmo::CK2 {
|
||||
|
||||
void CKStateChunk::StartRead(void) {
|
||||
void CKStateChunk::StartRead() {
|
||||
if (this->m_Parser.m_Status != CKStateChunkStatus::IDLE) return;
|
||||
|
||||
this->m_Parser.m_CurrentPos = 0u;
|
||||
@ -13,7 +13,7 @@ namespace LibCmo::CK2 {
|
||||
this->m_Parser.m_Status = CKStateChunkStatus::READ;
|
||||
}
|
||||
|
||||
void CKStateChunk::StopRead(void) {
|
||||
void CKStateChunk::StopRead() {
|
||||
if (this->m_Parser.m_Status != CKStateChunkStatus::READ) return;
|
||||
|
||||
this->m_Parser.m_CurrentPos = 0u;
|
||||
@ -220,7 +220,7 @@ namespace LibCmo::CK2 {
|
||||
return true;
|
||||
}
|
||||
|
||||
//CKStateChunk* CKStateChunk::ReadSubChunk(void) {
|
||||
//CKStateChunk* CKStateChunk::ReadSubChunk() {
|
||||
// CKStateChunk* subchunk = nullptr;
|
||||
|
||||
// // get size and do a enough space check
|
||||
|
@ -32,7 +32,7 @@ namespace LibCmo::CK2 {
|
||||
this->m_Parser.m_Status = CKStateChunkStatus::WRITE;
|
||||
}
|
||||
|
||||
void CKStateChunk::StopWrite(void) {
|
||||
void CKStateChunk::StopWrite() {
|
||||
if (this->m_Parser.m_Status != CKStateChunkStatus::WRITE) return;
|
||||
|
||||
// update buffer size
|
||||
|
@ -157,7 +157,7 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
|
||||
// read matrix
|
||||
// reset
|
||||
m_WorldMatrix.ResetToIdentity();
|
||||
m_WorldMatrix.SetIdentity();
|
||||
// force read as vector3
|
||||
chunk->ReadStruct(reinterpret_cast<VxMath::VxVector3*>(&m_WorldMatrix[0]));
|
||||
chunk->ReadStruct(reinterpret_cast<VxMath::VxVector3*>(&m_WorldMatrix[1]));
|
||||
|
@ -11,7 +11,7 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
virtual ~CK3dEntity();
|
||||
YYCC_DEL_CLS_COPY_MOVE(CK3dEntity);
|
||||
|
||||
virtual CK_CLASSID GetClassID(void) override {
|
||||
virtual CK_CLASSID GetClassID() override {
|
||||
return CK_CLASSID::CKCID_3DENTITY;
|
||||
}
|
||||
|
||||
@ -48,6 +48,8 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
CKDWORD m_ZOrder; // replace the whole heavy CKSceneGraphNode
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
@ -13,7 +13,7 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
virtual ~CK3dObject() {}
|
||||
YYCC_DEL_CLS_COPY_MOVE(CK3dObject);
|
||||
|
||||
virtual CK_CLASSID GetClassID(void) override {
|
||||
virtual CK_CLASSID GetClassID() override {
|
||||
return CK_CLASSID::CKCID_3DOBJECT;
|
||||
}
|
||||
// CK3dObject do not implement any load/save functions
|
||||
|
@ -11,7 +11,7 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
virtual ~CKBeObject();
|
||||
YYCC_DEL_CLS_COPY_MOVE(CKBeObject);
|
||||
|
||||
virtual CK_CLASSID GetClassID(void) override {
|
||||
virtual CK_CLASSID GetClassID() override {
|
||||
return CK_CLASSID::CKCID_BEOBJECT;
|
||||
}
|
||||
|
||||
|
155
LibCmo/CK2/ObjImpls/CKCamera.cpp
Normal file
155
LibCmo/CK2/ObjImpls/CKCamera.cpp
Normal 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
|
||||
|
||||
}
|
58
LibCmo/CK2/ObjImpls/CKCamera.hpp
Normal file
58
LibCmo/CK2/ObjImpls/CKCamera.hpp
Normal 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;
|
||||
};
|
||||
|
||||
}
|
@ -11,7 +11,7 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
virtual ~CKGroup();
|
||||
YYCC_DEL_CLS_COPY_MOVE(CKGroup);
|
||||
|
||||
virtual CK_CLASSID GetClassID(void) override {
|
||||
virtual CK_CLASSID GetClassID() override {
|
||||
return CK_CLASSID::CKCID_GROUP;
|
||||
}
|
||||
|
||||
|
232
LibCmo/CK2/ObjImpls/CKLight.cpp
Normal file
232
LibCmo/CK2/ObjImpls/CKLight.cpp
Normal 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
|
||||
|
||||
}
|
75
LibCmo/CK2/ObjImpls/CKLight.hpp
Normal file
75
LibCmo/CK2/ObjImpls/CKLight.hpp
Normal 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;
|
||||
};
|
||||
|
||||
}
|
@ -12,7 +12,7 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
virtual ~CKMaterial();
|
||||
YYCC_DEL_CLS_COPY_MOVE(CKMaterial);
|
||||
|
||||
virtual CK_CLASSID GetClassID(void) override {
|
||||
virtual CK_CLASSID GetClassID() override {
|
||||
return CK_CLASSID::CKCID_MATERIAL;
|
||||
}
|
||||
|
||||
|
@ -573,7 +573,7 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
// get diff by distance
|
||||
VxMath::VxVector3 diff = m_VertexNormal[vid] - generated[vid];
|
||||
// abs the diff and add into accumulated diff
|
||||
VxMath::NSVxVector::Abs(diff);
|
||||
VxMath::NSVxVector::Absolute(diff);
|
||||
accnml += diff;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
virtual ~CKMesh();
|
||||
YYCC_DEL_CLS_COPY_MOVE(CKMesh);
|
||||
|
||||
virtual CK_CLASSID GetClassID(void) override {
|
||||
virtual CK_CLASSID GetClassID() override {
|
||||
return CK_CLASSID::CKCID_MESH;
|
||||
}
|
||||
|
||||
|
@ -16,16 +16,16 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
|
||||
#pragma region Non-virtual Functions
|
||||
|
||||
CK_ID CKObject::GetID(void) const {
|
||||
CK_ID CKObject::GetID() const {
|
||||
return m_ID;
|
||||
}
|
||||
CKSTRING CKObject::GetName(void) const {
|
||||
CKSTRING CKObject::GetName() const {
|
||||
return XContainer::NSXString::ToCKSTRING(m_Name);
|
||||
}
|
||||
void CKObject::SetName(CKSTRING 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;
|
||||
}
|
||||
void CKObject::SetObjectFlags(CK_OBJECT_FLAGS flags) {
|
||||
|
@ -42,15 +42,15 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
virtual ~CKObject();
|
||||
YYCC_DEL_CLS_COPY_MOVE(CKObject);
|
||||
|
||||
CK_ID GetID(void) const;
|
||||
CKSTRING GetName(void) const;
|
||||
CK_ID GetID() const;
|
||||
CKSTRING GetName() const;
|
||||
void SetName(CKSTRING u8_name);
|
||||
CK_OBJECT_FLAGS GetObjectFlags(void) const;
|
||||
CK_OBJECT_FLAGS GetObjectFlags() const;
|
||||
void SetObjectFlags(CK_OBJECT_FLAGS flags);
|
||||
bool IsToBeDeleted() const;
|
||||
CKContext* GetCKContext() const;
|
||||
|
||||
virtual CK_CLASSID GetClassID(void) {
|
||||
virtual CK_CLASSID GetClassID() {
|
||||
return CK_CLASSID::CKCID_OBJECT;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
virtual ~CKRenderObject() {}
|
||||
YYCC_DEL_CLS_COPY_MOVE(CKRenderObject);
|
||||
|
||||
virtual CK_CLASSID GetClassID(void) override {
|
||||
virtual CK_CLASSID GetClassID() override {
|
||||
return CK_CLASSID::CKCID_RENDEROBJECT;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
virtual ~CKSceneObject() {}
|
||||
YYCC_DEL_CLS_COPY_MOVE(CKSceneObject);
|
||||
|
||||
virtual CK_CLASSID GetClassID(void) override {
|
||||
virtual CK_CLASSID GetClassID() override {
|
||||
return CK_CLASSID::CKCID_SCENEOBJECT;
|
||||
}
|
||||
// CKSceneObject do not override any RW functions.
|
||||
|
91
LibCmo/CK2/ObjImpls/CKTargetCamera.cpp
Normal file
91
LibCmo/CK2/ObjImpls/CKTargetCamera.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
33
LibCmo/CK2/ObjImpls/CKTargetCamera.hpp
Normal file
33
LibCmo/CK2/ObjImpls/CKTargetCamera.hpp
Normal 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;
|
||||
};
|
||||
|
||||
}
|
95
LibCmo/CK2/ObjImpls/CKTargetLight.cpp
Normal file
95
LibCmo/CK2/ObjImpls/CKTargetLight.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
33
LibCmo/CK2/ObjImpls/CKTargetLight.hpp
Normal file
33
LibCmo/CK2/ObjImpls/CKTargetLight.hpp
Normal 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;
|
||||
};
|
||||
|
||||
}
|
@ -12,7 +12,7 @@ namespace LibCmo::CK2::ObjImpls {
|
||||
virtual ~CKTexture();
|
||||
YYCC_DEL_CLS_COPY_MOVE(CKTexture);
|
||||
|
||||
virtual CK_CLASSID GetClassID(void) override {
|
||||
virtual CK_CLASSID GetClassID() override {
|
||||
return CK_CLASSID::CKCID_TEXTURE;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
add_library(LibCmo STATIC "")
|
||||
# Setup static library sources
|
||||
@ -30,8 +37,13 @@ PRIVATE
|
||||
CK2/ObjImpls/CKMesh.cpp
|
||||
CK2/ObjImpls/CKObject.cpp
|
||||
CK2/ObjImpls/CKTexture.cpp
|
||||
CK2/ObjImpls/CKLight.cpp
|
||||
CK2/ObjImpls/CKTargetLight.cpp
|
||||
CK2/ObjImpls/CKCamera.cpp
|
||||
CK2/ObjImpls/CKTargetCamera.cpp
|
||||
# VxMath
|
||||
VxMath/VxMemoryMappedFile.cpp
|
||||
VxMath/VxTypes.cpp
|
||||
VxMath/VxMath.cpp
|
||||
# X Container
|
||||
XContainer/XTypes.cpp
|
||||
@ -42,6 +54,7 @@ PUBLIC
|
||||
FILE_SET HEADERS
|
||||
FILES
|
||||
# Asststant header files
|
||||
VTVersion.hpp
|
||||
VTInternal.hpp
|
||||
VTEncoding.hpp
|
||||
VTUtils.hpp
|
||||
@ -73,6 +86,10 @@ FILES
|
||||
CK2/ObjImpls/CK3dObject.hpp
|
||||
CK2/ObjImpls/CKRenderObject.hpp
|
||||
CK2/ObjImpls/CKSceneObject.hpp
|
||||
CK2/ObjImpls/CKLight.hpp
|
||||
CK2/ObjImpls/CKTargetLight.hpp
|
||||
CK2/ObjImpls/CKCamera.hpp
|
||||
CK2/ObjImpls/CKTargetCamera.hpp
|
||||
# VxMath
|
||||
VxMath/VxTypes.hpp
|
||||
VxMath/VxMath.hpp
|
||||
|
@ -34,6 +34,10 @@
|
||||
#include "CK2/ObjImpls/CKTexture.hpp"
|
||||
#include "CK2/ObjImpls/CKMaterial.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
|
||||
#include "CK2/MgrImpls/CKBaseManager.hpp"
|
||||
|
@ -36,7 +36,7 @@ namespace LibCmo::EncodingHelper {
|
||||
* In underlying implementation, it actually is \c nullptr.
|
||||
* 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.
|
||||
|
@ -4,9 +4,9 @@
|
||||
* \file
|
||||
* The top header file for LibCom self development.
|
||||
* 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,
|
||||
* 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.
|
||||
* 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.
|
||||
* 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.
|
||||
* 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.
|
||||
// It provides various convenient stuff, for example:
|
||||
// - General LibCmo specific custom exception.
|
||||
|
@ -45,6 +45,21 @@ namespace LibCmo::VxMath {
|
||||
_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
|
||||
Remarks:
|
||||
|
@ -134,39 +134,4 @@ namespace LibCmo::VxMath {
|
||||
|
||||
#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
|
||||
|
||||
|
||||
}
|
||||
|
@ -95,56 +95,5 @@ namespace LibCmo::VxMath {
|
||||
*/
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ namespace LibCmo::VxMath {
|
||||
this->m_bIsValid = true;
|
||||
}
|
||||
|
||||
VxMemoryMappedFile::~VxMemoryMappedFile(void) {
|
||||
VxMemoryMappedFile::~VxMemoryMappedFile() {
|
||||
if (this->m_bIsValid) {
|
||||
// only success mapping need free
|
||||
this->m_bIsValid = false;
|
||||
|
529
LibCmo/VxMath/VxTypes.cpp
Normal file
529
LibCmo/VxMath/VxTypes.cpp
Normal 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
|
||||
|
||||
}
|
@ -7,7 +7,6 @@
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
|
||||
/**
|
||||
* @brief The VxMath part of LibCmo.
|
||||
@ -23,191 +22,75 @@ namespace LibCmo::VxMath {
|
||||
|
||||
class VxMemoryMappedFile;
|
||||
|
||||
// Misc
|
||||
// ========== Vector-like Definition ==========
|
||||
|
||||
/**
|
||||
* @brief The representation of a Vector in 2 dimensions.
|
||||
* @remarks In original Virtools SDK, it was named Vx2DVector.
|
||||
* @see VxVector3
|
||||
*/
|
||||
struct VxVector2 {
|
||||
CKFLOAT x, y;
|
||||
VxVector2() : x(0.0f), y(0.0f) {}
|
||||
VxVector2(CKFLOAT _x, CKFLOAT _y) : x(_x), y(_y) {}
|
||||
VxVector2();
|
||||
VxVector2(CKFLOAT _x, CKFLOAT _y);
|
||||
YYCC_DEF_CLS_COPY_MOVE(VxVector2);
|
||||
CKFLOAT& operator[](size_t i) {
|
||||
switch (i) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
default: throw LogicException("Invalid index for VxVector2::operator[].");
|
||||
}
|
||||
}
|
||||
const CKFLOAT& operator[](size_t i) const {
|
||||
switch (i) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
default: throw LogicException("Invalid index for VxVector2::operator[].");
|
||||
}
|
||||
}
|
||||
VxVector2& operator+=(const VxVector2& rhs) {
|
||||
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-=(const VxVector2& rhs) {
|
||||
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);
|
||||
}
|
||||
CKFLOAT& operator[](size_t i);
|
||||
const CKFLOAT& operator[](size_t i) const;
|
||||
bool operator==(const VxVector2& rhs) const;
|
||||
auto operator<=>(const VxVector2& rhs) const;
|
||||
VxVector2 operator+() const;
|
||||
VxVector2 operator-() const;
|
||||
VxVector2& operator+=(const VxVector2& rhs);
|
||||
friend VxVector2 operator+(const VxVector2& lhs, const VxVector2& rhs);
|
||||
VxVector2& operator-=(const VxVector2& rhs);
|
||||
friend VxVector2 operator-(const VxVector2& lhs, const VxVector2& rhs);
|
||||
VxVector2& operator*=(CKFLOAT rhs);
|
||||
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/=(CKFLOAT rhs);
|
||||
friend VxVector2 operator/(const VxVector2& lhs, CKFLOAT rhs);
|
||||
CKFLOAT SquaredLength() const;
|
||||
CKFLOAT Length() const;
|
||||
void Normalized();
|
||||
VxVector2 Normalize() const;
|
||||
|
||||
/* ===== BEGIN USER CUSTOM ===== */
|
||||
/* ===== END USER CUSTOM ===== */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The representation of a Vector in 3 dimensions
|
||||
* @remarks In original Virtools SDK, it was named VxVector.
|
||||
*/
|
||||
struct VxVector3 {
|
||||
CKFLOAT x, y, z;
|
||||
VxVector3() : x(0.0f), y(0.0f), z(0.0f) {}
|
||||
VxVector3(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z) : x(_x), y(_y), z(_z) {}
|
||||
VxVector3();
|
||||
VxVector3(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z);
|
||||
YYCC_DEF_CLS_COPY_MOVE(VxVector3);
|
||||
CKFLOAT& 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& 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[].");
|
||||
}
|
||||
}
|
||||
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-=(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);
|
||||
}
|
||||
CKFLOAT& operator[](size_t i);
|
||||
const CKFLOAT& operator[](size_t i) const;
|
||||
bool operator==(const VxVector3& rhs) const;
|
||||
auto operator<=>(const VxVector3& rhs) const;
|
||||
VxVector3 operator+() const;
|
||||
VxVector3 operator-() const;
|
||||
VxVector3& operator+=(const VxVector3& rhs);
|
||||
friend VxVector3 operator+(const VxVector3& lhs, const VxVector3& rhs);
|
||||
VxVector3& operator-=(const VxVector3& rhs);
|
||||
friend VxVector3 operator-(const VxVector3& lhs, const VxVector3& rhs);
|
||||
VxVector3& operator*=(CKFLOAT rhs);
|
||||
friend VxVector3 operator*(const VxVector3& lhs, CKFLOAT rhs);
|
||||
friend VxVector3 operator*(CKFLOAT lhs, const VxVector3& rhs);
|
||||
friend CKFLOAT operator*(const VxVector3& lhs, const VxVector3& rhs);
|
||||
VxVector3& operator/=(CKFLOAT rhs);
|
||||
friend VxVector3 operator/(const VxVector3& lhs, CKFLOAT rhs);
|
||||
CKFLOAT SquaredLength() const;
|
||||
CKFLOAT Length() const;
|
||||
void Normalized();
|
||||
VxVector3 Normalize() const;
|
||||
|
||||
/* ===== BEGIN USER CUSTOM ===== */
|
||||
/* ===== END USER CUSTOM ===== */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -215,107 +98,37 @@ namespace LibCmo::VxMath {
|
||||
* @details
|
||||
* 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.
|
||||
* @remarks In original Virtools SDK, it was named VxVector4. Not changed.
|
||||
* @see VxVector3
|
||||
*/
|
||||
struct VxVector4 {
|
||||
CKFLOAT x, y, z, w;
|
||||
VxVector4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {}
|
||||
VxVector4(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w) : x(_x), y(_y), z(_z), w(_w) {}
|
||||
VxVector4();
|
||||
VxVector4(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w);
|
||||
YYCC_DEF_CLS_COPY_MOVE(VxVector4);
|
||||
CKFLOAT& 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& 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[].");
|
||||
}
|
||||
}
|
||||
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-=(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);
|
||||
}
|
||||
CKFLOAT& operator[](size_t i);
|
||||
const CKFLOAT& operator[](size_t i) const;
|
||||
bool operator==(const VxVector4& rhs) const;
|
||||
auto operator<=>(const VxVector4& rhs) const;
|
||||
VxVector4 operator+() const;
|
||||
VxVector4 operator-() const;
|
||||
VxVector4& operator+=(const VxVector4& rhs);
|
||||
friend VxVector4 operator+(const VxVector4& lhs, const VxVector4& rhs);
|
||||
VxVector4& operator-=(const VxVector4& rhs);
|
||||
friend VxVector4 operator-(const VxVector4& lhs, const VxVector4& rhs);
|
||||
VxVector4& operator*=(CKFLOAT rhs);
|
||||
friend VxVector4 operator*(const VxVector4& lhs, CKFLOAT rhs);
|
||||
friend VxVector4 operator*(CKFLOAT lhs, const VxVector4& rhs);
|
||||
friend CKFLOAT operator*(const VxVector4& lhs, const VxVector4& rhs);
|
||||
VxVector4& operator/=(CKFLOAT rhs);
|
||||
friend VxVector4 operator/(const VxVector4& lhs, CKFLOAT rhs);
|
||||
CKFLOAT SquaredLength() const;
|
||||
CKFLOAT Length() const;
|
||||
void Normalized();
|
||||
VxVector4 Normalize() const;
|
||||
|
||||
/* ===== BEGIN USER CUSTOM ===== */
|
||||
/* ===== END USER CUSTOM ===== */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -323,42 +136,22 @@ namespace LibCmo::VxMath {
|
||||
* @details
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* Quaternions can be converted to VxMatrix or Euler Angles.
|
||||
* @see VxMatrix, VxVector3
|
||||
*/
|
||||
struct VxQuaternion {
|
||||
CKFLOAT x, y, z, w;
|
||||
VxQuaternion() : x(0.0f), y(0.0f), z(0.0f), w(1.0f) {} // set your custom init.
|
||||
VxQuaternion(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w) : x(_x), y(_y), z(_z), w(_w) {}
|
||||
VxQuaternion();
|
||||
VxQuaternion(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w);
|
||||
YYCC_DEF_CLS_COPY_MOVE(VxQuaternion);
|
||||
CKFLOAT& 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& 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;
|
||||
}
|
||||
CKFLOAT& operator[](size_t i);
|
||||
const CKFLOAT& operator[](size_t i) const;
|
||||
bool operator==(const VxQuaternion& rhs) const;
|
||||
auto operator<=>(const VxQuaternion& rhs) const;
|
||||
|
||||
/* ===== BEGIN USER CUSTOM ===== */
|
||||
/* ===== END USER CUSTOM ===== */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -366,69 +159,26 @@ namespace LibCmo::VxMath {
|
||||
* @details
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* Most methods are used to construct a VxColor or to convert it to a 32 bit ARGB format.
|
||||
*/
|
||||
struct VxColor {
|
||||
CKFLOAT r, g, b, a;
|
||||
VxColor() : r(0.0f), g(0.0f), b(0.0f), a(1.0f) {} // set your custom init.
|
||||
VxColor(CKFLOAT _r, CKFLOAT _g, CKFLOAT _b, CKFLOAT _a) : r(_r), g(_g), b(_b), a(_a) {}
|
||||
VxColor(CKDWORD argb) { FromARGB(argb); }
|
||||
VxColor();
|
||||
VxColor(CKFLOAT _r, CKFLOAT _g, CKFLOAT _b, CKFLOAT _a);
|
||||
YYCC_DEF_CLS_COPY_MOVE(VxColor);
|
||||
void 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 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 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;
|
||||
}
|
||||
CKFLOAT& operator[](size_t i);
|
||||
const CKFLOAT& operator[](size_t i) const;
|
||||
bool operator==(const VxColor& rhs) const;
|
||||
auto operator<=>(const VxColor& rhs) const;
|
||||
|
||||
/* ===== BEGIN USER CUSTOM ===== */
|
||||
VxColor(CKDWORD argb);
|
||||
VxColor(CKFLOAT _r, CKFLOAT _g, CKFLOAT _b);
|
||||
void FromARGB(CKDWORD argb);
|
||||
CKDWORD ToARGB() const;
|
||||
void Regulate();
|
||||
/* ===== END USER CUSTOM ===== */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -441,26 +191,111 @@ namespace LibCmo::VxMath {
|
||||
private:
|
||||
CKFLOAT m_Data[4][4];
|
||||
public:
|
||||
VxMatrix() : m_Data() { ResetToIdentity(); }
|
||||
VxMatrix(CKFLOAT m[4][4]) : m_Data() { std::memcpy(m_Data, m, sizeof(m_Data)); }
|
||||
VxMatrix();
|
||||
VxMatrix(CKFLOAT m[4][4]);
|
||||
YYCC_DEF_CLS_COPY_MOVE(VxMatrix);
|
||||
void ResetToIdentity() {
|
||||
std::memset(m_Data, 0, sizeof(m_Data));
|
||||
m_Data[0][0] = m_Data[1][1] = m_Data[2][2] = m_Data[3][3] = 1.0f;
|
||||
}
|
||||
VxVector4& operator[](size_t i) {
|
||||
if (i >= 4) throw LogicException("Invalid index for VxMatrix::operator[].");
|
||||
return *(reinterpret_cast<VxVector4*>(m_Data) + i);
|
||||
}
|
||||
const VxVector4& operator[](size_t i) const {
|
||||
if (i >= 4) throw LogicException("Invalid index for VxMatrix::operator[].");
|
||||
return *(reinterpret_cast<const VxVector4*>(m_Data) + i);
|
||||
}
|
||||
bool operator==(const VxMatrix& rhs) const {
|
||||
return std::memcmp(m_Data, rhs.m_Data, sizeof(m_Data)) == 0;
|
||||
}
|
||||
VxVector4& operator[](size_t i);
|
||||
const VxVector4& operator[](size_t i) const;
|
||||
bool operator==(const VxMatrix& rhs) const;
|
||||
auto operator<=>(const VxMatrix& rhs) const;
|
||||
|
||||
/* ===== BEGIN USER CUSTOM ===== */
|
||||
void Clear();
|
||||
void SetIdentity();
|
||||
/**
|
||||
* @brief Constructs a perspective projection matrix.
|
||||
* @param[in] Fov Field of View.
|
||||
* @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
|
||||
*
|
||||
* 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.
|
||||
* @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 */
|
||||
};
|
||||
|
||||
// ========== 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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -383,6 +383,10 @@ namespace Unvirt::AccessibleValue {
|
||||
{ LibCmo::CK2::CK_BITMAPDATA_FLAGS::CKBITMAPDATA_FREEVIDEOMEMORY, { u8"CKBITMAPDATA_FREEVIDEOMEMORY" } },
|
||||
{ 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 {
|
||||
{ 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_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 {
|
||||
{ LibCmo::VxMath::VXTEXTURE_BLENDMODE::VXTEXTUREBLEND_DECAL, { u8"VXTEXTUREBLEND_DECAL" } },
|
||||
{ LibCmo::VxMath::VXTEXTURE_BLENDMODE::VXTEXTUREBLEND_MODULATE, { u8"VXTEXTUREBLEND_MODULATE" } },
|
||||
|
@ -102,8 +102,10 @@ namespace Unvirt {
|
||||
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_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::VXLIGHT_TYPE> VXLIGHT_TYPE;
|
||||
extern const GeneralReflectionArray<LibCmo::VxMath::VXTEXTURE_BLENDMODE> VXTEXTURE_BLENDMODE;
|
||||
extern const GeneralReflectionArray<LibCmo::VxMath::VXTEXTURE_FILTERMODE> VXTEXTURE_FILTERMODE;
|
||||
extern const GeneralReflectionArray<LibCmo::VxMath::VXBLEND_MODE> VXBLEND_MODE;
|
||||
|
@ -362,8 +362,8 @@ namespace Unvirt::CmdHelper {
|
||||
throw std::invalid_argument("root node should not be inserted as child node.");
|
||||
// check conflict
|
||||
const auto& new_node_set = new_node_ptr->GetConflictSet();
|
||||
for (auto& node : m_Nodes) {
|
||||
const auto& node_set = node->GetConflictSet();
|
||||
for (auto& child_node : m_Nodes) {
|
||||
const auto& node_set = child_node->GetConflictSet();
|
||||
if (new_node_set.IsConflictWith(node_set))
|
||||
throw std::invalid_argument("try to add a conflict node. please check your code.");
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ namespace Unvirt::StructFormatter {
|
||||
// print current mesh
|
||||
{
|
||||
auto curmesh = obj->GetCurrentMesh();
|
||||
Console::Format(u8"->\t%s\t%s",
|
||||
Console::FormatLine(u8"->\t%s\t%s",
|
||||
PrintPointer(curmesh).c_str(),
|
||||
(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) {
|
||||
PrintCK3dEntityDetail(obj);
|
||||
@ -560,6 +624,18 @@ namespace Unvirt::StructFormatter {
|
||||
case LibCmo::CK2::CK_CLASSID::CKCID_3DENTITY:
|
||||
PrintCK3dEntityDetail(static_cast<LibCmo::CK2::ObjImpls::CK3dEntity*>(mobj));
|
||||
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:
|
||||
PrintCK3dObjectDetail(static_cast<LibCmo::CK2::ObjImpls::CK3dObject*>(mobj));
|
||||
break;
|
||||
|
@ -281,7 +281,7 @@ namespace Unvirt::Context {
|
||||
YYCC::ConsoleHelper::EnableColorfulConsole();
|
||||
|
||||
// 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.");
|
||||
|
||||
// start process loop
|
||||
|
Reference in New Issue
Block a user