Compare commits

13 Commits

Author SHA1 Message Date
305c0b1b65 doc: fix README 2024-11-08 15:17:45 +08:00
6f7202a86b feat: improve BMap bindings.
- Add IEquatable<T> interface for BMapSharp 2 abstract base classes to make they can be used in HashSet or Dictionary.
- Add corresponding testbench for this new added interface to make sure it works.
- Also add set and dict test for PyBMap although it has been proven works.
2024-11-08 14:58:50 +08:00
512729ed05 feat: improve PyBMap
- re-raise exception for run out of next() function to make end user know this is their fault, not PyBMap.
- write some primitive type getter setter for short code and less latent bugs.
- remove bmfile parameter in BMMeshTrans::Parse.
2024-11-07 20:56:16 +08:00
e2e7121c16 feat: update PyBMap and its testbench
- update PyBMap testbench according to BMapSharp testbench.
- use some wrapper function to fetch commonly used type in PyBMap to reduce line count.
- re-place some utils functions in PyBMap.
2024-11-07 17:28:11 +08:00
9dd46b88d9 dep: update stb.
- use a nasty way to update stb-image library (do not use new resize library, use moved depracted one. because idk how to program with new one. that lack doc).
2024-11-04 17:19:51 +08:00
7e7b21544d chore: update build script. 2024-11-04 14:58:53 +08:00
e72102496b fix: update YYCC dependency
- move EnumsHelper into YYCC because it is widely used.
- rename all calling to EnumsHelper due to this modification.
- add version checker in code to make sure that user use correct YYCC library to compile.
- modify some include syntax because the include directory layout changes of YYCC.
- update CMake script to resolve the bug that we can not export LibCmo (thanks doyaGu and BLumia).
2024-11-03 19:05:27 +08:00
73f1a1f829 fix: fix fatal layout issue about VxColor.
- fix wrong memory layout of VxColor.
2024-11-01 13:31:03 +08:00
33dc9a54be feat: finish BMapSharp
- basically finish BMapSharp bindings however done test does not cover all scenarios.
2024-11-01 11:13:05 +08:00
6eb95ddd1f feat: update BMapSharp
- finish BMMesh bindings.
- finish a half of BMMeshTrans bindings.
- use getGenericValue and setGenericValue for most bindings.
2024-11-01 10:48:45 +08:00
e8fedc8bff feat: update BMapSharp
- update virtools type defines in BMapSharp. expand its ctor for convenient usage.
- finish BMMaterial bindings.
- create a generic value getter setter for convenient calling.
- fix codegen error of BMapSharp (accident fallthrough for CKBYTE type and wrong marshal type for enum type).
2024-10-31 17:15:06 +08:00
74268d4ad4 feat: update BMapSharp
- finish BMTexture bindings and quater of BMMaterial.
- fix compile manual.
2024-10-30 15:41:17 +08:00
f7644319f0 doc: update build manual 2024-10-29 17:44:55 +08:00
34 changed files with 1132 additions and 917 deletions

View File

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

View File

@ -293,7 +293,7 @@ namespace BMapSharp {
#region Function Defines #region Function Defines
// ##### GENERATED FUNCTIONS BEGIN ##### // ##### GENERATED FUNCTIONS BEGIN #####
/// <summary>BMInit</summary> /// <summary>BMInit</summary>
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMInit", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMInit", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
@ -336,7 +336,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMFile_Save", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMFile_Save", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMFile_Save([In, MarshalAs(UnmanagedType.SysInt)] IntPtr map_file, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "In")] string file_name, [In, MarshalAs(UnmanagedType.U4)] uint texture_save_opt, [In, MarshalAs(UnmanagedType.U1)] bool use_compress, [In, MarshalAs(UnmanagedType.I4)] int compreess_level); internal static extern bool BMFile_Save([In, MarshalAs(UnmanagedType.SysInt)] IntPtr map_file, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BMStringMarshaler), MarshalCookie = "In")] string file_name, [In, MarshalAs(UnmanagedType.U4)] CK_TEXTURE_SAVEOPTIONS texture_save_opt, [In, MarshalAs(UnmanagedType.U1)] bool use_compress, [In, MarshalAs(UnmanagedType.I4)] int compreess_level);
/// <summary>BMFile_Free</summary> /// <summary>BMFile_Free</summary>
/// <param name="map_file">Type: BMap::BMFile*. </param> /// <param name="map_file">Type: BMap::BMFile*. </param>
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
@ -636,7 +636,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_GetSaveOptions", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMTexture_GetSaveOptions", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMTexture_GetSaveOptions([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_saveopt); internal static extern bool BMTexture_GetSaveOptions([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out CK_TEXTURE_SAVEOPTIONS out_saveopt);
/// <summary>BMTexture_SetSaveOptions</summary> /// <summary>BMTexture_SetSaveOptions</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -644,7 +644,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_SetSaveOptions", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMTexture_SetSaveOptions", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMTexture_SetSaveOptions([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint saveopt); internal static extern bool BMTexture_SetSaveOptions([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] CK_TEXTURE_SAVEOPTIONS saveopt);
/// <summary>BMTexture_GetVideoFormat</summary> /// <summary>BMTexture_GetVideoFormat</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -652,7 +652,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_GetVideoFormat", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMTexture_GetVideoFormat", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMTexture_GetVideoFormat([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_vfmt); internal static extern bool BMTexture_GetVideoFormat([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VX_PIXELFORMAT out_vfmt);
/// <summary>BMTexture_SetVideoFormat</summary> /// <summary>BMTexture_SetVideoFormat</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -660,7 +660,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_SetVideoFormat", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMTexture_SetVideoFormat", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMTexture_SetVideoFormat([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint vfmt); internal static extern bool BMTexture_SetVideoFormat([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VX_PIXELFORMAT vfmt);
/// <summary>BMMaterial_GetDiffuse</summary> /// <summary>BMMaterial_GetDiffuse</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -780,7 +780,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureBlendMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureBlendMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetTextureBlendMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetTextureBlendMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXTEXTURE_BLENDMODE out_val);
/// <summary>BMMaterial_SetTextureBlendMode</summary> /// <summary>BMMaterial_SetTextureBlendMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -788,7 +788,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureBlendMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureBlendMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetTextureBlendMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetTextureBlendMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXTEXTURE_BLENDMODE val);
/// <summary>BMMaterial_GetTextureMinMode</summary> /// <summary>BMMaterial_GetTextureMinMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -796,7 +796,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureMinMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureMinMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetTextureMinMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetTextureMinMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXTEXTURE_FILTERMODE out_val);
/// <summary>BMMaterial_SetTextureMinMode</summary> /// <summary>BMMaterial_SetTextureMinMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -804,7 +804,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureMinMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureMinMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetTextureMinMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetTextureMinMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXTEXTURE_FILTERMODE val);
/// <summary>BMMaterial_GetTextureMagMode</summary> /// <summary>BMMaterial_GetTextureMagMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -812,7 +812,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureMagMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureMagMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetTextureMagMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetTextureMagMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXTEXTURE_FILTERMODE out_val);
/// <summary>BMMaterial_SetTextureMagMode</summary> /// <summary>BMMaterial_SetTextureMagMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -820,7 +820,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureMagMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureMagMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetTextureMagMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetTextureMagMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXTEXTURE_FILTERMODE val);
/// <summary>BMMaterial_GetTextureAddressMode</summary> /// <summary>BMMaterial_GetTextureAddressMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -828,7 +828,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureAddressMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureAddressMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetTextureAddressMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetTextureAddressMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXTEXTURE_ADDRESSMODE out_val);
/// <summary>BMMaterial_SetTextureAddressMode</summary> /// <summary>BMMaterial_SetTextureAddressMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -836,7 +836,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureAddressMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureAddressMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetTextureAddressMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetTextureAddressMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXTEXTURE_ADDRESSMODE val);
/// <summary>BMMaterial_GetSourceBlend</summary> /// <summary>BMMaterial_GetSourceBlend</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -844,7 +844,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetSourceBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetSourceBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetSourceBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetSourceBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXBLEND_MODE out_val);
/// <summary>BMMaterial_SetSourceBlend</summary> /// <summary>BMMaterial_SetSourceBlend</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -852,7 +852,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetSourceBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetSourceBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetSourceBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetSourceBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXBLEND_MODE val);
/// <summary>BMMaterial_GetDestBlend</summary> /// <summary>BMMaterial_GetDestBlend</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -860,7 +860,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetDestBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetDestBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetDestBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetDestBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXBLEND_MODE out_val);
/// <summary>BMMaterial_SetDestBlend</summary> /// <summary>BMMaterial_SetDestBlend</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -868,7 +868,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetDestBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetDestBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetDestBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetDestBlend([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXBLEND_MODE val);
/// <summary>BMMaterial_GetFillMode</summary> /// <summary>BMMaterial_GetFillMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -876,7 +876,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetFillMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetFillMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetFillMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetFillMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXFILL_MODE out_val);
/// <summary>BMMaterial_SetFillMode</summary> /// <summary>BMMaterial_SetFillMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -884,7 +884,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetFillMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetFillMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetFillMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetFillMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXFILL_MODE val);
/// <summary>BMMaterial_GetShadeMode</summary> /// <summary>BMMaterial_GetShadeMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -892,7 +892,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetShadeMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetShadeMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetShadeMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetShadeMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXSHADE_MODE out_val);
/// <summary>BMMaterial_SetShadeMode</summary> /// <summary>BMMaterial_SetShadeMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -900,7 +900,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetShadeMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetShadeMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetShadeMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetShadeMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXSHADE_MODE val);
/// <summary>BMMaterial_GetAlphaTestEnabled</summary> /// <summary>BMMaterial_GetAlphaTestEnabled</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -988,7 +988,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetAlphaRef", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetAlphaRef", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetAlphaRef([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetAlphaRef([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U1)] out byte out_val);
/// <summary>BMMaterial_SetAlphaRef</summary> /// <summary>BMMaterial_SetAlphaRef</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -996,7 +996,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetAlphaRef", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetAlphaRef", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetAlphaRef([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetAlphaRef([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U1)] byte val);
/// <summary>BMMaterial_GetAlphaFunc</summary> /// <summary>BMMaterial_GetAlphaFunc</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -1004,7 +1004,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetAlphaFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetAlphaFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetAlphaFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetAlphaFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXCMPFUNC out_val);
/// <summary>BMMaterial_SetAlphaFunc</summary> /// <summary>BMMaterial_SetAlphaFunc</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -1012,7 +1012,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetAlphaFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetAlphaFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetAlphaFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetAlphaFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXCMPFUNC val);
/// <summary>BMMaterial_GetZFunc</summary> /// <summary>BMMaterial_GetZFunc</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -1020,7 +1020,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetZFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_GetZFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_GetZFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_val); internal static extern bool BMMaterial_GetZFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXCMPFUNC out_val);
/// <summary>BMMaterial_SetZFunc</summary> /// <summary>BMMaterial_SetZFunc</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -1028,7 +1028,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetZFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMaterial_SetZFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMaterial_SetZFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint val); internal static extern bool BMMaterial_SetZFunc([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXCMPFUNC val);
/// <summary>BMMesh_GetLitMode</summary> /// <summary>BMMesh_GetLitMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -1036,7 +1036,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMesh_GetLitMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMesh_GetLitMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMesh_GetLitMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out uint out_mode); internal static extern bool BMMesh_GetLitMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [Out, MarshalAs(UnmanagedType.U4)] out VXMESH_LITMODE out_mode);
/// <summary>BMMesh_SetLitMode</summary> /// <summary>BMMesh_SetLitMode</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>
@ -1044,7 +1044,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns> /// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMesh_SetLitMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] [DllImport(g_DllName, EntryPoint = "BMMesh_SetLitMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static extern bool BMMesh_SetLitMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] uint mode); internal static extern bool BMMesh_SetLitMode([In, MarshalAs(UnmanagedType.SysInt)] IntPtr bmfile, [In, MarshalAs(UnmanagedType.U4)] uint objid, [In, MarshalAs(UnmanagedType.U4)] VXMESH_LITMODE mode);
/// <summary>BMMesh_GetVertexCount</summary> /// <summary>BMMesh_GetVertexCount</summary>
/// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param> /// <param name="bmfile">Type: BMap::BMFile*. The pointer to corresponding BMFile.</param>
/// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param> /// <param name="objid">Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.</param>

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using BMapSharp.VirtoolsTypes; using BMapSharp.VirtoolsTypes;
@ -34,7 +35,7 @@ namespace BMapSharp.BMapWrapper {
/// It just writes the data in console. /// It just writes the data in console.
/// </summary> /// </summary>
internal static void BMapSharpCallback(string msg) { internal static void BMapSharpCallback(string msg) {
Console.WriteLine(msg); Console.WriteLine($"[BMapSharp] {msg}");
} }
#endregion #endregion
@ -45,7 +46,7 @@ namespace BMapSharp.BMapWrapper {
var stride = Marshal.SizeOf<T>(); var stride = Marshal.SizeOf<T>();
var itor = iem.GetEnumerator(); var itor = iem.GetEnumerator();
for (uint i = 0; i < count; ++i) { for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(itor.MoveNext()); if (!itor.MoveNext()) throw new BMapException("The length of given data is too short when assigning struct array.");
Marshal.StructureToPtr<T>(itor.Current, pstruct, false); Marshal.StructureToPtr<T>(itor.Current, pstruct, false);
pstruct += stride; pstruct += stride;
} }
@ -57,8 +58,14 @@ namespace BMapSharp.BMapWrapper {
internal static void CKFaceIndicesAssigner(IntPtr pstruct, uint count, IEnumerable<CKFaceIndices> iem) internal static void CKFaceIndicesAssigner(IntPtr pstruct, uint count, IEnumerable<CKFaceIndices> iem)
=> StructAssigner<CKFaceIndices>(pstruct, count, iem); => StructAssigner<CKFaceIndices>(pstruct, count, iem);
internal static void CKShortFaceIndicesAssigner(IntPtr pstruct, uint count, IEnumerable<CKShortFaceIndices> iem) internal static void CKShortFaceIndicesAssigner(IntPtr pstruct, uint count, IEnumerable<CKShortFaceIndices> iem)
=> StructAssigner<CKShortFaceIndices>(pstruct, count, iem); // TODO: There is a padding bug!!! => StructAssigner<CKShortFaceIndices>(pstruct, count, iem);
internal static void ShortAssigner(IntPtr pstruct, uint count, IEnumerable<short> iem)
=> StructAssigner<short>(pstruct, count, iem);
internal static void CKIDAssigner(IntPtr pstruct, uint count, IEnumerable<uint> iem)
=> StructAssigner<uint>(pstruct, count, iem);
internal static void CKDWORDAssigner(IntPtr pstruct, uint count, IEnumerable<uint> iem)
=> StructAssigner<uint>(pstruct, count, iem);
private static IEnumerable<T> StructIterator<T>(IntPtr pstruct, uint count) { private static IEnumerable<T> StructIterator<T>(IntPtr pstruct, uint count) {
var stride = Marshal.SizeOf<T>(); var stride = Marshal.SizeOf<T>();
for (uint i = 0; i < count; ++i) { for (uint i = 0; i < count; ++i) {
@ -73,7 +80,13 @@ namespace BMapSharp.BMapWrapper {
internal static IEnumerable<CKFaceIndices> CKFaceIndicesIterator(IntPtr pstruct, uint count) internal static IEnumerable<CKFaceIndices> CKFaceIndicesIterator(IntPtr pstruct, uint count)
=> StructIterator<CKFaceIndices>(pstruct, count); => StructIterator<CKFaceIndices>(pstruct, count);
internal static IEnumerable<CKShortFaceIndices> CKShortFaceIndicesIterator(IntPtr pstruct, uint count) internal static IEnumerable<CKShortFaceIndices> CKShortFaceIndicesIterator(IntPtr pstruct, uint count)
=> StructIterator<CKShortFaceIndices>(pstruct, count); // TODO: There is a padding bug!!! => StructIterator<CKShortFaceIndices>(pstruct, count);
internal static IEnumerable<short> ShortIterator(IntPtr pstruct, uint count)
=> StructIterator<short>(pstruct, count);
internal static IEnumerable<uint> CKIDIterator(IntPtr pstruct, uint count)
=> StructIterator<uint>(pstruct, count);
internal static IEnumerable<uint> CKDWORDIterator(IntPtr pstruct, uint count)
=> StructIterator<uint>(pstruct, count);
#endregion #endregion
@ -87,7 +100,10 @@ namespace BMapSharp.BMapWrapper {
#endregion #endregion
} }
public abstract class AbstractPointer : SafeHandle { // TODO: Maybe I need to implement IEquatable, IComparable<T>, and IComparable for AbstractPointer and AbstractCKObject.
// But I give it up. I am lazy. What I have written barely works for me now.
public abstract class AbstractPointer : SafeHandle, IEquatable<AbstractPointer> {
internal AbstractPointer(IntPtr raw_pointer) : base(Utils.INVALID_PTR, true) { internal AbstractPointer(IntPtr raw_pointer) : base(Utils.INVALID_PTR, true) {
this.handle = raw_pointer; this.handle = raw_pointer;
} }
@ -98,47 +114,42 @@ namespace BMapSharp.BMapWrapper {
internal bool isValid() => this.handle != Utils.INVALID_PTR; internal bool isValid() => this.handle != Utils.INVALID_PTR;
internal IntPtr getPointer() => this.handle; internal IntPtr getPointer() => this.handle;
// protected AbstractPointer(IntPtr raw_pointer) : base(raw_pointer, true) {} #region IEquatable
// protected IntPtr GetPointer() => this.handle; public override bool Equals(object obj) => this.Equals(obj as AbstractPointer);
// public override bool IsInvalid { get { return this.handle == Utils.INVALID_PTR; } } public bool Equals(AbstractPointer obj) {
if (obj is null) return false;
// Optimization for a common success case
if (Object.ReferenceEquals(this, obj)) return true;
// If run-time types are not exactly the same, return false.
if (this.GetType() != obj.GetType()) return false;
// Return true if the fields match.
return this.handle == obj.handle;
}
// #region IComparable public override int GetHashCode() => this.handle.GetHashCode();
// public int CompareTo(AbstractPointer other) { public static bool operator ==(AbstractPointer lhs, AbstractPointer rhs) {
// return m_RawPointer.CompareTo(other.m_RawPointer); if (lhs is null) {
// } if (rhs is null) return true;
// Only left side is null.
return false;
}
// Equals handles case of null on right side
return lhs.Equals(rhs);
}
public static bool operator !=(AbstractPointer lhs, AbstractPointer rhs) => !(lhs == rhs);
// #endregion #endregion
// #region IEquatable
// public override bool Equals(object obj) => this.Equals(obj as AbstractPointer);
// public bool Equals(AbstractPointer other) {
// if (other is null) return false;
// if (Object.ReferenceEquals(this, other)) return true;
// // if (this.GetType() != other.GetType()) return false;
// return this.m_RawPointer == other.m_RawPointer;
// }
// public static bool operator ==(AbstractPointer lhs, AbstractPointer rhs) {
// if (lhs is null) {
// if (rhs is null) return true;
// return false;
// }
// return lhs.Equals(rhs);
// }
// public static bool operator !=(AbstractPointer lhs, AbstractPointer rhs) => !(lhs == rhs);
// #endregion
#region Misc #region Misc
public override int GetHashCode() => this.handle.GetHashCode();
public override string ToString() => this.handle.ToString(); public override string ToString() => this.handle.ToString();
#endregion #endregion
} }
public abstract class AbstractCKObject : SafeHandle { public abstract class AbstractCKObject : SafeHandle, IEquatable<AbstractCKObject> {
// Same as AbstractPointer, but not own this handle. // Same as AbstractPointer, but not own this handle.
internal AbstractCKObject(IntPtr raw_pointer, uint ckid) : base(Utils.INVALID_PTR, false) { internal AbstractCKObject(IntPtr raw_pointer, uint ckid) : base(Utils.INVALID_PTR, false) {
this.handle = raw_pointer; this.handle = raw_pointer;
@ -153,104 +164,235 @@ namespace BMapSharp.BMapWrapper {
internal IntPtr getPointer() => this.handle; internal IntPtr getPointer() => this.handle;
internal uint getCKID() => m_CKID; internal uint getCKID() => m_CKID;
// private uint m_CKID; #region IEquatable
// protected AbstractCKObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer) { public override bool Equals(object obj) => this.Equals(obj as AbstractCKObject);
// m_CKID = ckid; public bool Equals(AbstractCKObject obj) {
// } if (obj is null) return false;
// Optimization for a common success case
if (Object.ReferenceEquals(this, obj)) return true;
// If run-time types are not exactly the same, return false.
if (this.GetType() != obj.GetType()) return false;
// Return true if the fields match.
return (this.m_CKID == obj.m_CKID) && (this.handle == obj.handle);
}
// protected override bool IsValid() => base.IsValid() && m_CKID != Utils.INVALID_CKID; public override int GetHashCode() => HashCode.Combine(this.handle, m_CKID);
// protected uint GetCKID() => m_CKID;
// #region IComparable public static bool operator ==(AbstractCKObject lhs, AbstractCKObject rhs) {
if (lhs is null) {
if (rhs is null) return true;
// Only left side is null.
return false;
}
// Equals handles case of null on right side
return lhs.Equals(rhs);
}
public static bool operator !=(AbstractCKObject lhs, AbstractCKObject rhs) => !(lhs == rhs);
// public int CompareTo(AbstractCKObject other) { #endregion
// var ret = base.CompareTo((AbstractPointer)other);
// if (ret != 0) return ret;
// return m_CKID.CompareTo(other.m_CKID);
// }
// #endregion
// #region IEquatable
// public override bool Equals(object obj) => this.Equals(obj as AbstractCKObject);
// public bool Equals(AbstractCKObject other) {
// if (other is null) return false;
// if (Object.ReferenceEquals(this, other)) return true;
// }
// public static bool operator ==(AbstractCKObject left, AbstractCKObject right) =>
// ((AbstractPointer)left == (AbstractPointer)right) && left.m_CKID == right.m_CKID;
// public static bool operator !=(AbstractCKObject left, AbstractCKObject right) =>
// ((AbstractPointer)left != (AbstractPointer)right) || left.m_CKID != right.m_CKID;
// #endregion
#region Misc #region Misc
public override int GetHashCode() => HashCode.Combine(this.handle, m_CKID);
public override string ToString() => $"{this.handle}, {m_CKID}"; public override string ToString() => $"{this.handle}, {m_CKID}";
#endregion #endregion
#region Subclass Utilities
protected delegate bool FctGenericValueGetter<T>(IntPtr bmf, uint id, out T val);
protected delegate bool FctGenericValueSetter<T>(IntPtr bmf, uint id, T val);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected T getGenericValue<T>(FctGenericValueGetter<T> fct) {
BMapException.ThrowIfFailed(fct(getPointer(), getCKID(), out T out_val));
return out_val;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void setGenericValue<T>(FctGenericValueSetter<T> fct, T val) {
BMapException.ThrowIfFailed(fct(getPointer(), getCKID(), val));
}
#endregion
} }
public class BMObject : AbstractCKObject { public class BMObject : AbstractCKObject {
internal BMObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { } internal BMObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public string GetName() { public string GetName() => getGenericValue<string>(BMap.BMObject_GetName);
BMapException.ThrowIfFailed(BMap.BMObject_GetName(getPointer(), getCKID(), out string out_name)); public void SetName(string name) => setGenericValue<string>(BMap.BMObject_SetName, name);
return out_name;
}
public void SetName(string name) {
BMapException.ThrowIfFailed(BMap.BMObject_SetName(getPointer(), getCKID(), name));
}
} }
public class BMTexture : BMObject { public class BMTexture : BMObject {
internal BMTexture(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { } internal BMTexture(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public string GetFileName() => getGenericValue<string>(BMap.BMTexture_GetFileName);
public void LoadImage(string filepath) {
BMapException.ThrowIfFailed(BMap.BMTexture_LoadImage(getPointer(), getCKID(), filepath));
}
public void SaveImage(string filepath) {
BMapException.ThrowIfFailed(BMap.BMTexture_SaveImage(getPointer(), getCKID(), filepath));
}
public CK_TEXTURE_SAVEOPTIONS GetSaveOptions() => getGenericValue<CK_TEXTURE_SAVEOPTIONS>(BMap.BMTexture_GetSaveOptions);
public void SetSaveOptions(CK_TEXTURE_SAVEOPTIONS opt) => setGenericValue<CK_TEXTURE_SAVEOPTIONS>(BMap.BMTexture_SetSaveOptions, opt);
public VX_PIXELFORMAT GetVideoFormat() => getGenericValue<VX_PIXELFORMAT>(BMap.BMTexture_GetVideoFormat);
public void SetVideoFormat(VX_PIXELFORMAT vfmt) => setGenericValue<VX_PIXELFORMAT>(BMap.BMTexture_SetVideoFormat, vfmt);
} }
public class BMMaterial : BMObject { public class BMMaterial : BMObject {
internal BMMaterial(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { } internal BMMaterial(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public VxColor GetDiffuse() => getGenericValue<VxColor>(BMap.BMMaterial_GetDiffuse);
public void SetDiffuse(VxColor col) => setGenericValue<VxColor>(BMap.BMMaterial_SetDiffuse, col);
public VxColor GetAmbient() => getGenericValue<VxColor>(BMap.BMMaterial_GetAmbient);
public void SetAmbient(VxColor col) => setGenericValue<VxColor>(BMap.BMMaterial_SetAmbient, col);
public VxColor GetSpecular() => getGenericValue<VxColor>(BMap.BMMaterial_GetSpecular);
public void SetSpecular(VxColor col) => setGenericValue<VxColor>(BMap.BMMaterial_SetSpecular, col);
public VxColor GetEmissive() => getGenericValue<VxColor>(BMap.BMMaterial_GetEmissive);
public void SetEmissive(VxColor col) => setGenericValue<VxColor>(BMap.BMMaterial_SetEmissive, col);
public float GetSpecularPower() => getGenericValue<float>(BMap.BMMaterial_GetSpecularPower);
public void SetSpecularPower(float val) => setGenericValue<float>(BMap.BMMaterial_SetSpecularPower, val);
public VxColor GetTextureBorderColor() {
BMapException.ThrowIfFailed(BMap.BMMaterial_GetTextureBorderColor(getPointer(), getCKID(), out uint out_val));
return new VxColor(out_val);
}
public void SetTextureBorderColor(VxColor col) {
BMapException.ThrowIfFailed(BMap.BMMaterial_SetTextureBorderColor(getPointer(), getCKID(), col.ToDword()));
}
public VXTEXTURE_BLENDMODE GetTextureBlendMode() => getGenericValue<VXTEXTURE_BLENDMODE>(BMap.BMMaterial_GetTextureBlendMode);
public void SetTextureBlendMode(VXTEXTURE_BLENDMODE val) => setGenericValue<VXTEXTURE_BLENDMODE>(BMap.BMMaterial_SetTextureBlendMode, val);
public VXTEXTURE_FILTERMODE GetTextureMinMode() => getGenericValue<VXTEXTURE_FILTERMODE>(BMap.BMMaterial_GetTextureMinMode);
public void SetTextureMinMode(VXTEXTURE_FILTERMODE val) => setGenericValue<VXTEXTURE_FILTERMODE>(BMap.BMMaterial_SetTextureMinMode, val);
public VXTEXTURE_FILTERMODE GetTextureMagMode() => getGenericValue<VXTEXTURE_FILTERMODE>(BMap.BMMaterial_GetTextureMagMode);
public void SetTextureMagMode(VXTEXTURE_FILTERMODE val) => setGenericValue<VXTEXTURE_FILTERMODE>(BMap.BMMaterial_SetTextureMagMode, val);
public VXTEXTURE_ADDRESSMODE GetTextureAddressMode() => getGenericValue<VXTEXTURE_ADDRESSMODE>(BMap.BMMaterial_GetTextureAddressMode);
public void SetTextureAddressMode(VXTEXTURE_ADDRESSMODE val) => setGenericValue<VXTEXTURE_ADDRESSMODE>(BMap.BMMaterial_SetTextureAddressMode, val);
public VXBLEND_MODE GetSourceBlend() => getGenericValue<VXBLEND_MODE>(BMap.BMMaterial_GetSourceBlend);
public void SetSourceBlend(VXBLEND_MODE val) => setGenericValue<VXBLEND_MODE>(BMap.BMMaterial_SetSourceBlend, val);
public VXBLEND_MODE GetDestBlend() => getGenericValue<VXBLEND_MODE>(BMap.BMMaterial_GetDestBlend);
public void SetDestBlend(VXBLEND_MODE val) => setGenericValue<VXBLEND_MODE>(BMap.BMMaterial_SetDestBlend, val);
public VXFILL_MODE GetFillMode() => getGenericValue<VXFILL_MODE>(BMap.BMMaterial_GetFillMode);
public void SetFillMode(VXFILL_MODE val) => setGenericValue<VXFILL_MODE>(BMap.BMMaterial_SetFillMode, val);
public VXSHADE_MODE GetShadeMode() => getGenericValue<VXSHADE_MODE>(BMap.BMMaterial_GetShadeMode);
public void SetShadeMode(VXSHADE_MODE val) => setGenericValue<VXSHADE_MODE>(BMap.BMMaterial_SetShadeMode, val);
public bool GetAlphaTestEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetAlphaTestEnabled);
public void SetAlphaTestEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetAlphaTestEnabled, val);
public bool GetAlphaBlendEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetAlphaBlendEnabled);
public void SetAlphaBlendEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetAlphaBlendEnabled, val);
public bool GetPerspectiveCorrectionEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetPerspectiveCorrectionEnabled);
public void SetPerspectiveCorrectionEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetPerspectiveCorrectionEnabled, val);
public bool GetZWriteEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetZWriteEnabled);
public void SetZWriteEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetZWriteEnabled, val);
public bool GetTwoSidedEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetTwoSidedEnabled);
public void SetTwoSidedEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetTwoSidedEnabled, val);
public byte GetAlphaRef() => getGenericValue<byte>(BMap.BMMaterial_GetAlphaRef);
public void SetAlphaRef(byte val) => setGenericValue<byte>(BMap.BMMaterial_SetAlphaRef, val);
public VXCMPFUNC GetAlphaFunc() => getGenericValue<VXCMPFUNC>(BMap.BMMaterial_GetAlphaFunc);
public void SetAlphaFunc(VXCMPFUNC val) => setGenericValue<VXCMPFUNC>(BMap.BMMaterial_SetAlphaFunc, val);
public VXCMPFUNC GetZFunc() => getGenericValue<VXCMPFUNC>(BMap.BMMaterial_GetZFunc);
public void SetZFunc(VXCMPFUNC val) => setGenericValue<VXCMPFUNC>(BMap.BMMaterial_SetZFunc, val);
} }
public class BMMesh : BMObject { public class BMMesh : BMObject {
internal BMMesh(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { } internal BMMesh(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public VXMESH_LITMODE GetLitMode() => getGenericValue<VXMESH_LITMODE>(BMap.BMMesh_GetLitMode);
public void SetLitMode(VXMESH_LITMODE mode) => setGenericValue<VXMESH_LITMODE>(BMap.BMMesh_SetLitMode, mode);
public uint GetVertexCount() => getGenericValue<uint>(BMap.BMMesh_GetVertexCount);
public void SetVertexCount(uint count) => setGenericValue<uint>(BMap.BMMesh_SetVertexCount, count);
public IEnumerable<VxVector3> GetVertexPositions() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexPositions(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.VxVector3Iterator(out_mem, GetVertexCount());
}
public void SetVertexPositions(IEnumerable<VxVector3> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexPositions(getPointer(), getCKID(), out IntPtr out_mem));
Utils.VxVector3Assigner(out_mem, GetVertexCount(), iem);
}
public IEnumerable<VxVector3> GetVertexNormals() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexNormals(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.VxVector3Iterator(out_mem, GetVertexCount());
}
public void SetVertexNormals(IEnumerable<VxVector3> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexNormals(getPointer(), getCKID(), out IntPtr out_mem));
Utils.VxVector3Assigner(out_mem, GetVertexCount(), iem);
}
public IEnumerable<VxVector2> GetVertexUVs() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexUVs(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.VxVector2Iterator(out_mem, GetVertexCount());
}
public void SetVertexUVs(IEnumerable<VxVector2> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexUVs(getPointer(), getCKID(), out IntPtr out_mem));
Utils.VxVector2Assigner(out_mem, GetVertexCount(), iem);
}
public uint GetFaceCount() => getGenericValue<uint>(BMap.BMMesh_GetFaceCount);
public void SetFaceCount(uint count) => setGenericValue<uint>(BMap.BMMesh_SetFaceCount, count);
public IEnumerable<CKShortFaceIndices> GetFaceIndices() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceIndices(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.CKShortFaceIndicesIterator(out_mem, GetFaceCount());
}
public void SetFaceIndices(IEnumerable<CKShortFaceIndices> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceIndices(getPointer(), getCKID(), out IntPtr out_mem));
Utils.CKShortFaceIndicesAssigner(out_mem, GetFaceCount(), iem);
}
public IEnumerable<short> GetFaceMaterialSlotIndexs() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceMaterialSlotIndexs(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.ShortIterator(out_mem, GetFaceCount());
}
public void SetFaceMaterialSlotIndexs(IEnumerable<short> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceMaterialSlotIndexs(getPointer(), getCKID(), out IntPtr out_mem));
Utils.ShortAssigner(out_mem, GetFaceCount(), iem);
}
public uint GetMaterialSlotCount() => getGenericValue<uint>(BMap.BMMesh_GetMaterialSlotCount);
public void SetMaterialSlotCount(uint count) => setGenericValue<uint>(BMap.BMMesh_SetMaterialSlotCount, count);
public IEnumerable<BMMaterial> GetMaterialSlots() {
uint count = GetMaterialSlotCount();
for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetMaterialSlot(getPointer(), getCKID(), i, out uint out_mtlid));
if (out_mtlid == Utils.INVALID_CKID) yield return null;
else yield return new BMMaterial(getPointer(), out_mtlid);
}
}
public void SetMaterialSlots(IEnumerable<BMMaterial> iem) {
uint count = GetMaterialSlotCount();
var itor = iem.GetEnumerator();
for (uint i = 0; i < count; ++i) {
if (!itor.MoveNext()) throw new BMapException("The length of given material array is too short when assigning material slots.");
uint mtlid = itor.Current is null ? Utils.INVALID_CKID : itor.Current.getCKID();
BMapException.ThrowIfFailed(BMap.BMMesh_SetMaterialSlot(getPointer(), getCKID(), i, mtlid));
}
}
} }
public class BM3dObject : BMObject { public class BM3dObject : BMObject {
internal BM3dObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { } internal BM3dObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public VxMatrix GetWorldMatrix() { public VxMatrix GetWorldMatrix() => getGenericValue<VxMatrix>(BMap.BM3dObject_GetWorldMatrix);
BMapException.ThrowIfFailed(BMap.BM3dObject_GetWorldMatrix(getPointer(), getCKID(), out VxMatrix out_mat)); public void SetWorldMatrix(VxMatrix mat) => setGenericValue<VxMatrix>(BMap.BM3dObject_SetWorldMatrix, mat);
return out_mat;
}
public void SetWorldMatrix(VxMatrix mat) {
BMapException.ThrowIfFailed(BMap.BM3dObject_SetWorldMatrix(getPointer(), getCKID(), mat));
}
public BMMesh GetCurrentMesh() { public BMMesh GetCurrentMesh() {
BMapException.ThrowIfFailed(BMap.BM3dObject_GetCurrentMesh(getPointer(), getCKID(), out uint out_meshid)); BMapException.ThrowIfFailed(BMap.BM3dObject_GetCurrentMesh(getPointer(), getCKID(), out uint out_meshid));
if (out_meshid == Utils.INVALID_CKID) return null; if (out_meshid == Utils.INVALID_CKID) return null;
else return new BMMesh(getPointer(), out_meshid); else return new BMMesh(getPointer(), out_meshid);
} }
public void SetCurrentMesh(BMMesh mesh) { public void SetCurrentMesh(BMMesh mesh) {
uint meshid = (mesh is null) ? Utils.INVALID_CKID : mesh.getCKID(); uint meshid = (mesh is null) ? Utils.INVALID_CKID : mesh.getCKID();
BMapException.ThrowIfFailed(BMap.BM3dObject_SetCurrentMesh(getPointer(), getCKID(), meshid)); BMapException.ThrowIfFailed(BMap.BM3dObject_SetCurrentMesh(getPointer(), getCKID(), meshid));
} }
public bool GetVisibility() { public bool GetVisibility() => getGenericValue<bool>(BMap.BM3dObject_GetVisibility);
BMapException.ThrowIfFailed(BMap.BM3dObject_GetVisibility(getPointer(), getCKID(), out bool out_isVisible)); public void SetVisibility(bool visb) => setGenericValue<bool>(BMap.BM3dObject_SetVisibility, visb);
return out_isVisible;
}
public void SetVisibility(bool visb) {
BMapException.ThrowIfFailed(BMap.BM3dObject_SetVisibility(getPointer(), getCKID(), visb));
}
} }
public class BMGroup : BMObject { public class BMGroup : BMObject {
@ -260,11 +402,7 @@ namespace BMapSharp.BMapWrapper {
BMapException.ThrowIfFailed(BMap.BMGroup_AddObject(getPointer(), getCKID(), member.getCKID())); BMapException.ThrowIfFailed(BMap.BMGroup_AddObject(getPointer(), getCKID(), member.getCKID()));
} }
public uint GetObjectCount() { public uint GetObjectCount() => getGenericValue<uint>(BMap.BMGroup_GetObjectCount);
BMapException.ThrowIfFailed(BMap.BMGroup_GetObjectCount(getPointer(), getCKID(), out uint out_count));
return out_count;
}
public IEnumerable<BM3dObject> GetObjects() { public IEnumerable<BM3dObject> GetObjects() {
var size = GetObjectCount(); var size = GetObjectCount();
for (uint i = 0; i < size; ++i) { for (uint i = 0; i < size; ++i) {
@ -344,6 +482,16 @@ namespace BMapSharp.BMapWrapper {
public BMFileWriter(string temp_folder, string texture_folder, string[] encodings) public BMFileWriter(string temp_folder, string texture_folder, string[] encodings)
: base(allocateHandle(temp_folder, texture_folder, encodings)) { } : base(allocateHandle(temp_folder, texture_folder, encodings)) { }
public void Save(string filename, CK_TEXTURE_SAVEOPTIONS texture_save_opt, bool use_compress, int compress_level) {
BMapException.ThrowIfFailed(BMap.BMFile_Save(
getPointer(),
filename,
texture_save_opt,
use_compress,
compress_level
));
}
private delegate bool FctProtoCreateObject(IntPtr bmf, out uint id); private delegate bool FctProtoCreateObject(IntPtr bmf, out uint id);
private delegate T FctProtoCreateInstance<T>(IntPtr bmf, uint id); private delegate T FctProtoCreateInstance<T>(IntPtr bmf, uint id);
private T createCKObject<T>(FctProtoCreateObject fct_crt, FctProtoCreateInstance<T> fct_inst) { private T createCKObject<T>(FctProtoCreateObject fct_crt, FctProtoCreateInstance<T> fct_inst) {
@ -368,6 +516,59 @@ namespace BMapSharp.BMapWrapper {
} }
public BMMeshTrans() : base(allocateHandle()) { } public BMMeshTrans() : base(allocateHandle()) { }
public void Parse(BMMesh objmesh) {
BMapException.ThrowIfFailed(BMap.BMMeshTrans_Parse(
getPointer(),
objmesh.getPointer(),
objmesh.getCKID()
));
}
public void PrepareVertex(uint count, IEnumerable<VxVector3> iem) {
// Prepare count first
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareVertexCount(getPointer(), count));
// Then put data
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareVertex(getPointer(), out IntPtr out_mem));
Utils.VxVector3Assigner(out_mem, count, iem);
}
public void PrepareNormal(uint count, IEnumerable<VxVector3> iem) {
// Prepare count first
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareNormalCount(getPointer(), count));
// Then put data
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareNormal(getPointer(), out IntPtr out_mem));
Utils.VxVector3Assigner(out_mem, count, iem);
}
public void PrepareUV(uint count, IEnumerable<VxVector2> iem) {
// Prepare count first
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareUVCount(getPointer(), count));
// Then put data
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareUV(getPointer(), out IntPtr out_mem));
Utils.VxVector2Assigner(out_mem, count, iem);
}
public void PrepareMtlSlot(uint count, IEnumerable<BMMaterial> iem) {
// Prepare count first
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareMtlSlotCount(getPointer(), count));
// Then put data
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareMtlSlot(getPointer(), out IntPtr out_mem));
var cast_iem = iem.Select((mtl) => mtl is null ? Utils.INVALID_CKID : mtl.getCKID());
Utils.CKIDAssigner(out_mem, count, cast_iem);
}
public void PrepareFace(uint count, IEnumerable<CKFaceIndices> vec_idx, IEnumerable<CKFaceIndices> nml_idx, IEnumerable<CKFaceIndices> uv_idx, IEnumerable<uint> mtl_idx) {
// Prepare count first
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareFaceCount(getPointer(), count));
// Get data address
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareFaceVertexIndices(getPointer(), out IntPtr raw_vec_idx));
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareFaceNormalIndices(getPointer(), out IntPtr raw_nml_idx));
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareFaceUVIndices(getPointer(), out IntPtr raw_uv_idx));
BMapException.ThrowIfFailed(BMap.BMMeshTrans_PrepareFaceMtlSlot(getPointer(), out IntPtr raw_mtl_idx));
// Assign data
Utils.CKFaceIndicesAssigner(raw_vec_idx, count, vec_idx);
Utils.CKFaceIndicesAssigner(raw_nml_idx, count, nml_idx);
Utils.CKFaceIndicesAssigner(raw_uv_idx, count, uv_idx);
Utils.CKDWORDAssigner(raw_mtl_idx, count, mtl_idx);
}
} }

View File

@ -15,12 +15,14 @@ namespace BMapSharp.VirtoolsTypes {
public float X, Y; public float X, Y;
public VxVector2(float _x = 0.0f, float _y = 0.0f) { public VxVector2(float _x = 0.0f, float _y = 0.0f) {
X = _x; X = _x; Y = _y;
Y = _y;
} }
public VxVector2(Vector2 vec) {
FromManaged(vec);
}
public void FromManaged(Vector2 vec) { public void FromManaged(Vector2 vec) {
X = vec.X; X = vec.X; Y = vec.Y;
Y = vec.Y;
} }
public Vector2 ToManaged() { public Vector2 ToManaged() {
return new Vector2(X, Y); return new Vector2(X, Y);
@ -33,14 +35,14 @@ namespace BMapSharp.VirtoolsTypes {
public float X, Y, Z; public float X, Y, Z;
public VxVector3(float _x = 0.0f, float _y = 0.0f, float _z = 0.0f) { public VxVector3(float _x = 0.0f, float _y = 0.0f, float _z = 0.0f) {
X = _x; X = _x; Y = _y; Z = _z;
Y = _y;
Z = _z;
} }
public VxVector3(Vector3 vec) {
FromManaged(vec);
}
public void FromManaged(Vector3 vec) { public void FromManaged(Vector3 vec) {
X = vec.X; X = vec.X; Y = vec.Y; Z = vec.Z;
Y = vec.Y;
Z = vec.Z;
} }
public Vector3 ToManaged() { public Vector3 ToManaged() {
return new Vector3(X, Y, Z); return new Vector3(X, Y, Z);
@ -50,29 +52,31 @@ namespace BMapSharp.VirtoolsTypes {
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)] [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct VxColor { public struct VxColor {
[MarshalAs(UnmanagedType.R4)] [MarshalAs(UnmanagedType.R4)]
public float A, R, G, B; public float R, G, B, A;
public VxColor(float _r, float _g, float _b, float _a) { public VxColor(float _r, float _g, float _b, float _a) {
A = _a; A = _a; R = _r; G = _g; B = _b;
R = _r;
G = _g;
B = _b;
Regulate(); Regulate();
} }
public VxColor(Vector4 col) {
FromManagedRGBA(col);
}
public VxColor(Vector3 col) {
FromManagedRGB(col);
}
public VxColor(uint val) {
FromDword(val);
}
public void FromManagedRGBA(Vector4 col) { public void FromManagedRGBA(Vector4 col) {
R = col.X; R = col.X; G = col.Y; B = col.Z; A = col.W;
G = col.Y;
B = col.Z;
A = col.W;
Regulate(); Regulate();
} }
public Vector4 ToManagedRGBA() { public Vector4 ToManagedRGBA() {
return new Vector4(R, G, B, A); return new Vector4(R, G, B, A);
} }
public void FromManagedRGB(Vector3 col) { public void FromManagedRGB(Vector3 col) {
R = col.X; R = col.X; G = col.Y; B = col.Z; A = 1.0f;
G = col.Y;
B = col.Z;
Regulate(); Regulate();
} }
public Vector3 ToManagedRGB() { public Vector3 ToManagedRGB() {
@ -101,6 +105,7 @@ namespace BMapSharp.VirtoolsTypes {
val |= (uint)(B * 255.0f); val |= (uint)(B * 255.0f);
return val; return val;
} }
public static float ClampFactor(float factor) { public static float ClampFactor(float factor) {
return System.Math.Clamp(factor, 0.0f, 1.0f); return System.Math.Clamp(factor, 0.0f, 1.0f);
} }

View File

@ -1,8 +1,12 @@
using BMapSharp.BMapWrapper;
using System; using System;
using System.Text; using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
namespace BMapSharpTestbench { namespace BMapSharpTestbench {
internal class Program { internal class Program {
static void Main(string[] args) { static void Main(string[] args) {
// Check environment // Check environment
Console.OutputEncoding = Encoding.UTF8; Console.OutputEncoding = Encoding.UTF8;
@ -23,45 +27,120 @@ namespace BMapSharpTestbench {
string[] encodings = ["cp1252", "gb2312"]; string[] encodings = ["cp1252", "gb2312"];
using (var reader = new BMapSharp.BMapWrapper.BMFileReader(file_name, temp_folder, texture_folder, encodings)) { using (var reader = new BMapSharp.BMapWrapper.BMFileReader(file_name, temp_folder, texture_folder, encodings)) {
// Console.WriteLine("===== Groups ====="); TestCommon(reader);
// foreach (var gp in reader.GetGroups()) { TestIEquatable(reader);
// Console.WriteLine(gp.GetName());
// foreach (var gp_item in gp.GetObjects()) {
// Console.WriteLine($"\t{gp_item.GetName()}");
// }
// }
Console.WriteLine("===== 3dObjects =====");
foreach (var obj in reader.Get3dObjects()) {
Console.WriteLine(obj.GetName());
var current_mesh = obj.GetCurrentMesh();
var mesh_name = current_mesh is null ? "<null>" : current_mesh.GetName();
Console.WriteLine($"\tMesh: {mesh_name}");
Console.WriteLine($"\tVisibility: {obj.GetVisibility()}");
Console.WriteLine($"\tMatrix: {obj.GetWorldMatrix().ToManaged()}");
}
// Console.WriteLine("===== Meshes =====");
// foreach (var mesh in reader.GetMeshes()) {
// Console.WriteLine(mesh.GetName());
// }
// Console.WriteLine("===== Materials =====");
// foreach (var mtl in reader.GetMaterials()) {
// Console.WriteLine(mtl.GetName());
// }
// Console.WriteLine("===== Textures =====");
// foreach (var tex in reader.GetTextures()) {
// Console.WriteLine(tex.GetName());
// }
} }
Console.WriteLine("===== Done ====="); Console.WriteLine("Press any key to quit...");
Console.ReadKey(true); Console.ReadKey(true);
} }
static void TestCommon(BMapSharp.BMapWrapper.BMFileReader reader) {
// Console.WriteLine("===== Groups =====");
// foreach (var gp in reader.GetGroups()) {
// Console.WriteLine(gp.GetName());
// foreach (var gp_item in gp.GetObjects()) {
// Console.WriteLine($"\t{gp_item.GetName()}");
// }
// }
// Console.WriteLine("===== 3dObjects =====");
// foreach (var obj in reader.Get3dObjects()) {
// Console.WriteLine(obj.GetName());
// var current_mesh = obj.GetCurrentMesh();
// var mesh_name = current_mesh is null ? "<null>" : current_mesh.GetName();
// Console.WriteLine($"\tMesh: {mesh_name}");
// Console.WriteLine($"\tVisibility: {obj.GetVisibility()}");
// Console.WriteLine($"\tMatrix: {obj.GetWorldMatrix().ToManaged()}");
// }
// Console.WriteLine("===== Meshes =====");
// foreach (var mesh in reader.GetMeshes()) {
// Console.WriteLine(mesh.GetName());
// Console.WriteLine($"\tLit Mode: {mesh.GetLitMode()}");
// Console.WriteLine($"\tVertex Count: {mesh.GetVertexCount()}");
// Console.WriteLine($"\tFace Count: {mesh.GetFaceCount()}");
// Console.WriteLine($"\tMaterial Slot Count: {mesh.GetMaterialSlotCount()}");
// }
Console.WriteLine("===== Materials =====");
foreach (var mtl in reader.GetMaterials()) {
Console.WriteLine(mtl.GetName());
Console.WriteLine($"\tDiffuse: {mtl.GetDiffuse().ToManagedRGBA()}");
Console.WriteLine($"\tAmbient: {mtl.GetAmbient().ToManagedRGBA()}");
Console.WriteLine($"\tSpecular: {mtl.GetSpecular().ToManagedRGBA()}");
Console.WriteLine($"\tEmissive: {mtl.GetEmissive().ToManagedRGBA()}");
Console.WriteLine($"\tSpecular Power: {mtl.GetSpecularPower()}");
Console.WriteLine($"\tTexture Border Color: {mtl.GetTextureBorderColor().ToManagedRGBA()}");
Console.WriteLine($"\tTexture Blend Mode: {mtl.GetTextureBlendMode()}");
Console.WriteLine($"\tTexture Min Mode: {mtl.GetTextureMinMode()}");
Console.WriteLine($"\tTexture Mag Mode: {mtl.GetTextureMagMode()}");
Console.WriteLine($"\tSource Blend: {mtl.GetSourceBlend()}");
Console.WriteLine($"\tDest Blend: {mtl.GetDestBlend()}");
Console.WriteLine($"\tFill Mode: {mtl.GetFillMode()}");
Console.WriteLine($"\tShade Mode: {mtl.GetShadeMode()}");
Console.WriteLine($"\tAlpha Test Enabled: {mtl.GetAlphaTestEnabled()}");
Console.WriteLine($"\tAlpha Blend Enabled: {mtl.GetAlphaBlendEnabled()}");
Console.WriteLine($"\tPerspective Correction Enabled: {mtl.GetPerspectiveCorrectionEnabled()}");
Console.WriteLine($"\tZ Write Enabled: {mtl.GetZWriteEnabled()}");
Console.WriteLine($"\tTwo Sided Enabled: {mtl.GetTwoSidedEnabled()}");
Console.WriteLine($"\tAlpha Ref: {mtl.GetAlphaRef()}");
Console.WriteLine($"\tAlpha Func: {mtl.GetAlphaFunc()}");
Console.WriteLine($"\tZ Func: {mtl.GetZFunc()}");
}
// Console.WriteLine("===== Textures =====");
// foreach (var tex in reader.GetTextures()) {
// Console.WriteLine(tex.GetName());
// Console.WriteLine($"\tFile Name: {tex.GetFileName()}");
// Console.WriteLine($"\tSave Options: {tex.GetSaveOptions()}");
// Console.WriteLine($"\tVideo Format: {tex.GetVideoFormat()}");
// }
Console.WriteLine("===== END =====");
}
static void TestIEquatable(BMapSharp.BMapWrapper.BMFileReader reader) {
if (reader.Get3dObjectCount() < 2u) {
Debug.Fail(
"Invalid file for test IEquatable.",
"We can not perform IEquatable test because the length of 3dObject is too short (must greater than 2). Please choose another file to perform."
);
return;
}
// Prepare test variables
var all_3dobjects = new List<BM3dObject>(reader.Get3dObjects());
var first_3dobj = all_3dobjects[0];
var second_3dobj = all_3dobjects[1];
all_3dobjects = new List<BM3dObject>(reader.Get3dObjects());
var first_3dobj_again = all_3dobjects[0];
Debug.Assert(!Object.ReferenceEquals(first_3dobj, first_3dobj_again));
// Hashtable test
var test_hashset = new HashSet<BM3dObject>();
Debug.Assert(test_hashset.Add(first_3dobj));
Debug.Assert(!test_hashset.Add(first_3dobj_again));
Debug.Assert(test_hashset.Add(second_3dobj));
// Dictionary test
var test_dictionary = new Dictionary<BM3dObject, string>();
Debug.Assert(test_dictionary.TryAdd(first_3dobj, first_3dobj.GetName()));
Debug.Assert(!test_dictionary.TryAdd(first_3dobj_again, first_3dobj_again.GetName()));
Debug.Assert(test_dictionary.TryAdd(second_3dobj, second_3dobj.GetName()));
}
} }
} }

View File

@ -1,4 +1,4 @@
import ctypes, typing, atexit import ctypes, typing, atexit, enum
from . import bmap, virtools_types from . import bmap, virtools_types
#region Basic Class & Constant Defines #region Basic Class & Constant Defines
@ -13,12 +13,85 @@ def _python_callback(strl: bytes):
Simply add a prefix when output. Simply add a prefix when output.
Need a convertion before passing to BMFile. Need a convertion before passing to BMFile.
""" """
# the passing value is bytes, not bmap.bm_CKSTRING. # YYC Remarks:
# i think Python do a auto convertion here. # The passing value to this function is bytes, not bmap.bm_CKSTRING.
# I think Python do an auto convertion in there.
if strl is not None: if strl is not None:
print(f'[PyBMap] {strl.decode(g_BMapEncoding)}') print(f'[PyBMap] {strl.decode(g_BMapEncoding)}')
_g_RawCallback: bmap.bm_callback = bmap.bm_callback(_python_callback) _g_RawCallback: bmap.bm_callback = bmap.bm_callback(_python_callback)
#endregion
#region Help Functions
class _Utils:
@staticmethod
def raise_out_of_length_exception() -> None:
raise bmap.BMapException("The length of given data is too short when assigning struct array.")
@staticmethod
def _vector_assigner(pdata: typing.Any, item_count: int, factor_count: int, itor: typing.Iterator[tuple[typing.Any, ...]]) -> None:
idx: int = 0
try:
for _i in range(item_count):
user_vector: tuple[typing.Any, ...] = next(itor)
for _j in range(factor_count):
pdata[idx] = user_vector[_j]
idx += 1
except StopIteration:
_Utils.raise_out_of_length_exception()
@staticmethod
def _vector_iterator(pdata: typing.Any, item_count: int, factor_count: int) -> typing.Iterator[tuple[typing.Any, ...]]:
idx: int = 0
for _i in range(item_count):
yield tuple(map(
lambda _j: pdata[idx + _j],
range(factor_count)
))
idx += factor_count
@staticmethod
def vxvector3_assigner(pvector: bmap.bm_VxVector3_p, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
_Utils._vector_assigner(ctypes.cast(pvector, bmap.bm_CKFLOAT_p), count, 3, map(lambda v: (v.x, v.y, v.z), itor))
@staticmethod
def vxvector3_iterator(pvector: bmap.bm_VxVector3_p, count: int) -> typing.Iterator[virtools_types.VxVector3]:
return map(
lambda v: virtools_types.VxVector3(*v),
_Utils._vector_iterator(ctypes.cast(pvector, bmap.bm_CKFLOAT_p), count, 3)
)
@staticmethod
def vxvector2_assigner(pvector: bmap.bm_VxVector2_p, count: int, itor: typing.Iterator[virtools_types.VxVector2]) -> None:
_Utils._vector_assigner(ctypes.cast(pvector, bmap.bm_CKFLOAT_p), count, 2, map(lambda v: (v.x, v.y), itor))
@staticmethod
def vxvector2_iterator(pvector: bmap.bm_VxVector2_p, count: int) -> typing.Iterator[virtools_types.VxVector2]:
return map(
lambda v: virtools_types.VxVector2(*v),
_Utils._vector_iterator(ctypes.cast(pvector, bmap.bm_CKFLOAT_p), count, 2)
)
"""!
@remarks
bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p is just a type hint.
We actually do not need distinguish them in code.
Because the stride when increasing them is decided by their runtime type.
"""
@staticmethod
def ckfaceindices_assigner(pindices: bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p, count: int, itor: typing.Iterator[virtools_types.CKFaceIndices]) -> None:
_Utils._vector_assigner(pindices, count, 3, map(lambda v: (v.i1, v.i2, v.i3), itor))
@staticmethod
def ckfaceindices_iterator(pindices: bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p, count: int) -> typing.Iterator[virtools_types.CKFaceIndices]:
return map(
lambda v: virtools_types.CKFaceIndices(*v),
_Utils._vector_iterator(pindices, count, 3)
)
#endregion
#region Basic Classes
class _AbstractPointer(): class _AbstractPointer():
__mRawPointer: int __mRawPointer: int
@ -46,6 +119,11 @@ class _AbstractPointer():
def __hash__(self) -> int: def __hash__(self) -> int:
return hash(self.__mRawPointer) return hash(self.__mRawPointer)
TEnumType = typing.TypeVar('TEnumType', bound = enum.IntEnum)
TIntegralType = bmap.bm_CKDWORD | bmap.bm_CKWORD | bmap.bm_CKINT | bmap.bm_CKBYTE | bmap.bm_CKID
TFloatPointType = bmap.bm_CKFLOAT
TPointerType = typing.TypeVar('TPointerType')
class _AbstractCKObject(_AbstractPointer): class _AbstractCKObject(_AbstractPointer):
__mCKID: int __mCKID: int
@ -70,78 +148,76 @@ class _AbstractCKObject(_AbstractPointer):
def __hash__(self) -> int: def __hash__(self) -> int:
return hash((_AbstractPointer.__hash__(self), self.__mCKID)) return hash((_AbstractPointer.__hash__(self), self.__mCKID))
#endregion # Convenient Value Getter Setter
# Focusing on those which widely called types.
#region Help Function & Type Define def _get_primitive_value(self, primitive_type_: typing.Any, getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, typing.Any], bmap.bm_bool]) -> typing.Any:
data = primitive_type_()
getter_(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def _set_primitive_value(self, primitive_type_: typing.Any, setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, typing.Any], bmap.bm_bool], data_: typing.Any) -> None:
data = primitive_type_(data_)
setter_(self._get_pointer(), self._get_ckid(), data)
TCKObj = typing.TypeVar('TCKObj', bound = _AbstractCKObject) def _get_integral_value(self, integral_type_: type[TIntegralType], getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, typing.Any], bmap.bm_bool]) -> int:
return self._get_primitive_value(integral_type_, getter_)
def _set_integral_value(self, integral_type_: type[TIntegralType], setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, typing.Any], bmap.bm_bool], data_: int) -> None:
self._set_primitive_value(integral_type_, setter_, data_)
def _get_float_point_value(self, float_point_type_: type[TFloatPointType], getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, typing.Any], bmap.bm_bool]) -> float:
return self._get_primitive_value(float_point_type_, getter_)
def _set_float_point_value(self, float_point_type_: type[TFloatPointType], setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, typing.Any], bmap.bm_bool], data_: float) -> None:
self._set_primitive_value(float_point_type_, setter_, data_)
def _get_bool_value(self, getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_bool_p], bmap.bm_bool]) -> bool:
return self._get_primitive_value(bmap.bm_bool, getter_)
def _set_bool_value(self, setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_bool], bmap.bm_bool], data_: bool) -> None:
self._set_primitive_value(bmap.bm_bool, setter_, data_)
def _get_enum_value(self, enum_type_: type[TEnumType], getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_enum_p], bmap.bm_bool]) -> TEnumType:
return enum_type_(self._get_primitive_value(bmap.bm_enum, getter_))
def _set_enum_value(self, setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_enum], bmap.bm_bool], data_: TEnumType) -> None:
self._set_primitive_value(bmap.bm_enum, setter_, data_.value)
def _vxvector3_assigner(pvector: bmap.bm_VxVector3_p, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None: def _get_str_value(self, getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_CKSTRING_p], bmap.bm_bool]) -> str | None:
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p) data: bmap.bm_CKSTRING = bmap.bm_CKSTRING()
idx: int = 0 getter_(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
for _ in range(count): if data.value is None: return None
uservector: virtools_types.VxVector3 = next(itor) else: return data.value.decode(g_BMapEncoding)
pfloat[idx] = uservector.x def _set_str_value(self, setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_CKSTRING], bmap.bm_bool], data_: str | None) -> None:
pfloat[idx + 1] = uservector.y data: bmap.bm_CKSTRING
pfloat[idx + 2] = uservector.z if data_ is None: data = bmap.bm_CKSTRING(0)
idx += 3 else: data = bmap.bm_CKSTRING(data_.encode(g_BMapEncoding))
setter_(self._get_pointer(), self._get_ckid(), data)
def _vxvector3_iterator(pvector: bmap.bm_VxVector3_p, count: int) -> typing.Iterator[virtools_types.VxVector3]: def _set_vxcolor_value(self,
ret: virtools_types.VxVector3 = virtools_types.VxVector3() setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_VxColor], bmap.bm_bool],
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p) col_: virtools_types.VxColor) -> None:
idx: int = 0 # set to raw color
for _ in range(count): col: bmap.bm_VxColor = bmap.bm_VxColor()
ret.x = pfloat[idx] (col.r, col.g, col.b, col.a) = (col_.r, col_.g, col_.b, col_.a)
ret.y = pfloat[idx + 1] # assign
ret.z = pfloat[idx + 2] setter_(self._get_pointer(), self._get_ckid(), col)
idx += 3 def _get_vxcolor_value(self,
yield ret getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_VxColor_p], bmap.bm_bool]) -> virtools_types.VxColor:
# get raw color
def _vxvector2_assigner(pvector: bmap.bm_VxVector2_p, count: int, itor: typing.Iterator[virtools_types.VxVector2]) -> None: col: bmap.bm_VxColor = bmap.bm_VxColor()
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p) getter_(self._get_pointer(), self._get_ckid(), ctypes.byref(col))
idx: int = 0 # get from raw color
for _ in range(count): ret: virtools_types.VxColor = virtools_types.VxColor()
uservector: virtools_types.VxVector2 = next(itor) (ret.r, ret.g, ret.b, ret.a) = (col.r, col.g, col.b, col.a)
pfloat[idx] = uservector.x return ret
pfloat[idx + 1] = uservector.y
idx += 2 def _get_pointer_value(self, ptr_type_: type[TPointerType], getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, typing.Any], bmap.bm_bool]) -> TPointerType:
data = ptr_type_()
getter_(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data
def _vxvector2_iterator(pvector: bmap.bm_VxVector2_p, count: int) -> typing.Iterator[virtools_types.VxVector2]: TCKObject = typing.TypeVar('TCKObject', bound = _AbstractCKObject)
ret: virtools_types.VxVector2 = virtools_types.VxVector2()
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p)
idx: int = 0
for _ in range(count):
ret.x = pfloat[idx]
ret.y = pfloat[idx + 1]
idx += 2
yield ret
# bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p is just a type hint
# wo do not need distinguish them in code.
# because the type of pindices is decided by runtime.
def _ckfaceindices_assigner(pindices: bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p, count: int, itor: typing.Iterator[virtools_types.CKFaceIndices]) -> None:
idx: int = 0
for _ in range(count):
userindices: virtools_types.CKFaceIndices = next(itor)
pindices[idx] = userindices.i1
pindices[idx + 1] = userindices.i2
pindices[idx + 2] = userindices.i3
idx += 3
def _ckfaceindices_iterator(pindices: bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p, count: int) -> typing.Iterator[virtools_types.CKFaceIndices]:
ret: virtools_types.CKFaceIndices = virtools_types.CKFaceIndices()
idx: int = 0
for _ in range(count):
ret.i1 = pindices[idx]
ret.i2 = pindices[idx + 1]
ret.i3 = pindices[idx + 2]
idx += 3
yield ret
#endregion #endregion
#region Valid Check, Init and Dispose #region Validation Check, Init and Dispose
def is_bmap_available() -> bool: def is_bmap_available() -> bool:
return bmap.is_bmap_available() return bmap.is_bmap_available()
@ -159,7 +235,7 @@ if is_bmap_available():
#region Real Type Defines #region Real Type Defines
"""! """!
@remark @remarks
BMFileReader, BMFileWriter, and BMMeshTrans can be create by given constructor. BMFileReader, BMFileWriter, and BMMeshTrans can be create by given constructor.
But they must be destroyed by calling dispose(). Otherwise it may cause memory leak. But they must be destroyed by calling dispose(). Otherwise it may cause memory leak.
You also can use python `with` statement to achieve this automatically. You also can use python `with` statement to achieve this automatically.
@ -173,337 +249,204 @@ We just provide them as a visitor.
class BMObject(_AbstractCKObject): class BMObject(_AbstractCKObject):
def get_name(self) -> str | None: def get_name(self) -> str | None:
name: bmap.bm_CKSTRING = bmap.bm_CKSTRING() return self._get_str_value(bmap.BMObject_GetName)
bmap.BMObject_GetName(self._get_pointer(), self._get_ckid(), ctypes.byref(name))
if name.value is None:
return None
else:
return name.value.decode(g_BMapEncoding)
def set_name(self, name_: str | None) -> None: def set_name(self, name_: str | None) -> None:
name: bmap.bm_CKSTRING self._set_str_value(bmap.BMObject_SetName, name_)
if name_ is None:
name = bmap.bm_CKSTRING(0)
else:
name = bmap.bm_CKSTRING(name_.encode(g_BMapEncoding))
bmap.BMObject_SetName(self._get_pointer(), self._get_ckid(), name)
class BMTexture(BMObject): class BMTexture(BMObject):
def get_file_name(self) -> str | None: def get_file_name(self) -> str | None:
filename: bmap.bm_CKSTRING = bmap.bm_CKSTRING() return self._get_str_value(bmap.BMTexture_GetFileName)
bmap.BMTexture_GetFileName(self._get_pointer(), self._get_ckid(), ctypes.byref(filename))
if filename.value is None:
return None
else:
return filename.value.decode(g_BMapEncoding)
def load_image(self, filepath: str) -> None: def load_image(self, filepath: str) -> None:
filename: bmap.bm_CKSTRING = bmap.bm_CKSTRING(filepath.encode(g_BMapEncoding)) filename: bmap.bm_CKSTRING = bmap.bm_CKSTRING(filepath.encode(g_BMapEncoding))
bmap.BMTexture_LoadImage(self._get_pointer(), self._get_ckid(), filename) bmap.BMTexture_LoadImage(self._get_pointer(), self._get_ckid(), filename)
def save_image(self, filepath: str) -> None: def save_image(self, filepath: str) -> None:
filename: bmap.bm_CKSTRING = bmap.bm_CKSTRING(filepath.encode(g_BMapEncoding)) filename: bmap.bm_CKSTRING = bmap.bm_CKSTRING(filepath.encode(g_BMapEncoding))
bmap.BMTexture_SaveImage(self._get_pointer(), self._get_ckid(), filename) bmap.BMTexture_SaveImage(self._get_pointer(), self._get_ckid(), filename)
def get_save_options(self) -> virtools_types.CK_TEXTURE_SAVEOPTIONS: def get_save_options(self) -> virtools_types.CK_TEXTURE_SAVEOPTIONS:
opt: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.CK_TEXTURE_SAVEOPTIONS, bmap.BMTexture_GetSaveOptions)
bmap.BMTexture_GetSaveOptions(self._get_pointer(), self._get_ckid(), ctypes.byref(opt))
return virtools_types.CK_TEXTURE_SAVEOPTIONS(opt.value)
def set_save_options(self, opt_: virtools_types.CK_TEXTURE_SAVEOPTIONS) -> None: def set_save_options(self, opt_: virtools_types.CK_TEXTURE_SAVEOPTIONS) -> None:
opt: bmap.bm_enum = bmap.bm_enum(opt_.value) self._set_enum_value(bmap.BMTexture_SetSaveOptions, opt_)
bmap.BMTexture_SetSaveOptions(self._get_pointer(), self._get_ckid(), opt)
def get_video_format(self) -> virtools_types.VX_PIXELFORMAT: def get_video_format(self) -> virtools_types.VX_PIXELFORMAT:
fmt: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.VX_PIXELFORMAT, bmap.BMTexture_GetVideoFormat)
bmap.BMTexture_GetVideoFormat(self._get_pointer(), self._get_ckid(), ctypes.byref(fmt))
return virtools_types.VX_PIXELFORMAT(fmt.value)
def set_video_format(self, fmt_: virtools_types.VX_PIXELFORMAT) -> None: def set_video_format(self, fmt_: virtools_types.VX_PIXELFORMAT) -> None:
fmt: bmap.bm_enum = bmap.bm_enum(fmt_.value) self._set_enum_value(bmap.BMTexture_SetVideoFormat, fmt_)
bmap.BMTexture_SetVideoFormat(self._get_pointer(), self._get_ckid(), fmt)
class BMMaterial(BMObject): class BMMaterial(BMObject):
def _set_vxcolor(self,
setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_VxColor], bool],
col_: virtools_types.VxColor) -> None:
# set to raw color
col: bmap.bm_VxColor = bmap.bm_VxColor()
col.r = col_.r
col.g = col_.g
col.b = col_.b
col.a = col_.a
# assign
setter_(self._get_pointer(), self._get_ckid(), col)
def _get_vxcolor(self,
getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_VxColor_p], bool]) -> virtools_types.VxColor:
# get raw color
col: bmap.bm_VxColor = bmap.bm_VxColor()
getter_(self._get_pointer(), self._get_ckid(), ctypes.byref(col))
# get from raw color
ret: virtools_types.VxColor = virtools_types.VxColor()
ret.r = col.r
ret.g = col.g
ret.b = col.b
ret.a = col.a
return ret
def get_diffuse(self) -> virtools_types.VxColor: def get_diffuse(self) -> virtools_types.VxColor:
return self._get_vxcolor(bmap.BMMaterial_GetDiffuse) return self._get_vxcolor_value(bmap.BMMaterial_GetDiffuse)
def set_diffuse(self, col: virtools_types.VxColor) -> None: def set_diffuse(self, col: virtools_types.VxColor) -> None:
self._set_vxcolor(bmap.BMMaterial_SetDiffuse, col) self._set_vxcolor_value(bmap.BMMaterial_SetDiffuse, col)
def get_ambient(self) -> virtools_types.VxColor: def get_ambient(self) -> virtools_types.VxColor:
return self._get_vxcolor(bmap.BMMaterial_GetAmbient) return self._get_vxcolor_value(bmap.BMMaterial_GetAmbient)
def set_ambient(self, col: virtools_types.VxColor) -> None: def set_ambient(self, col: virtools_types.VxColor) -> None:
self._set_vxcolor(bmap.BMMaterial_SetAmbient, col) self._set_vxcolor_value(bmap.BMMaterial_SetAmbient, col)
def get_specular(self) -> virtools_types.VxColor: def get_specular(self) -> virtools_types.VxColor:
return self._get_vxcolor(bmap.BMMaterial_GetSpecular) return self._get_vxcolor_value(bmap.BMMaterial_GetSpecular)
def set_specular(self, col: virtools_types.VxColor) -> None: def set_specular(self, col: virtools_types.VxColor) -> None:
self._set_vxcolor(bmap.BMMaterial_SetSpecular, col) self._set_vxcolor_value(bmap.BMMaterial_SetSpecular, col)
def get_emissive(self) -> virtools_types.VxColor: def get_emissive(self) -> virtools_types.VxColor:
return self._get_vxcolor(bmap.BMMaterial_GetEmissive) return self._get_vxcolor_value(bmap.BMMaterial_GetEmissive)
def set_emissive(self, col: virtools_types.VxColor) -> None: def set_emissive(self, col: virtools_types.VxColor) -> None:
self._set_vxcolor(bmap.BMMaterial_SetEmissive, col) self._set_vxcolor_value(bmap.BMMaterial_SetEmissive, col)
def get_specular_power(self) -> float: def get_specular_power(self) -> float:
power: bmap.bm_CKFLOAT = bmap.bm_CKFLOAT() return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMMaterial_GetSpecularPower)
bmap.BMMaterial_GetSpecularPower(self._get_pointer(), self._get_ckid(), ctypes.byref(power))
return power.value
def set_specular_power(self, power_: float) -> None: def set_specular_power(self, power_: float) -> None:
power: bmap.bm_CKFLOAT = bmap.bm_CKFLOAT(power_) self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMMaterial_SetSpecularPower, power_)
bmap.BMMaterial_SetSpecularPower(self._get_pointer(), self._get_ckid(), power)
def get_texture(self) -> BMTexture | None: def get_texture(self) -> BMTexture | None:
objid: bmap.bm_CKID = bmap.bm_CKID() objid: bmap.bm_CKID = bmap.bm_CKID()
bmap.BMMaterial_GetTexture(self._get_pointer(), self._get_ckid(), ctypes.byref(objid)) bmap.BMMaterial_GetTexture(self._get_pointer(), self._get_ckid(), ctypes.byref(objid))
if objid.value == g_InvalidCKID: if objid.value == g_InvalidCKID: return None
return None else: return BMTexture(self._get_pointer(), objid)
else:
return BMTexture(self._get_pointer(), objid)
def set_texture(self, tex_: BMTexture | None) -> None: def set_texture(self, tex_: BMTexture | None) -> None:
objid: bmap.bm_CKID = bmap.bm_CKID(g_InvalidCKID) objid: bmap.bm_CKID = bmap.bm_CKID(g_InvalidCKID)
if tex_ is not None: if tex_ is not None: objid = tex_._get_ckid()
objid = tex_._get_ckid()
bmap.BMMaterial_SetTexture(self._get_pointer(), self._get_ckid(), objid) bmap.BMMaterial_SetTexture(self._get_pointer(), self._get_ckid(), objid)
def get_texture_border_color(self) -> virtools_types.VxColor: def get_texture_border_color(self) -> virtools_types.VxColor:
col: bmap.bm_CKDWORD = bmap.bm_CKDWORD() dword_color: int = self._get_integral_value(bmap.bm_CKDWORD, bmap.BMMaterial_GetTextureBorderColor)
bmap.BMMaterial_GetTextureBorderColor(self._get_pointer(), self._get_ckid(), ctypes.byref(col))
ret: virtools_types.VxColor = virtools_types.VxColor() ret: virtools_types.VxColor = virtools_types.VxColor()
ret.from_dword(col.value) ret.from_dword(dword_color)
return ret return ret
def set_texture_border_color(self, col_: virtools_types.VxColor) -> None: def set_texture_border_color(self, col_: virtools_types.VxColor) -> None:
col: bmap.bm_CKDWORD = bmap.bm_CKDWORD(col_.to_dword()) self._set_integral_value(bmap.bm_CKDWORD, bmap.BMMaterial_SetTextureBorderColor, col_.to_dword())
bmap.BMMaterial_SetTextureBorderColor(self._get_pointer(), self._get_ckid(), col)
def get_texture_blend_mode(self) -> virtools_types.VXTEXTURE_BLENDMODE: def get_texture_blend_mode(self) -> virtools_types.VXTEXTURE_BLENDMODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.VXTEXTURE_BLENDMODE, bmap.BMMaterial_GetTextureBlendMode)
bmap.BMMaterial_GetTextureBlendMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXTEXTURE_BLENDMODE(data.value)
def set_texture_blend_mode(self, data_: virtools_types.VXTEXTURE_BLENDMODE) -> None: def set_texture_blend_mode(self, data_: virtools_types.VXTEXTURE_BLENDMODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum_value(bmap.BMMaterial_SetTextureBlendMode, data_)
bmap.BMMaterial_SetTextureBlendMode(self._get_pointer(), self._get_ckid(), data)
def get_texture_min_mode(self) -> virtools_types.VXTEXTURE_FILTERMODE: def get_texture_min_mode(self) -> virtools_types.VXTEXTURE_FILTERMODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.VXTEXTURE_FILTERMODE, bmap.BMMaterial_GetTextureMinMode)
bmap.BMMaterial_GetTextureMinMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXTEXTURE_FILTERMODE(data.value)
def set_texture_min_mode(self, data_: virtools_types.VXTEXTURE_FILTERMODE) -> None: def set_texture_min_mode(self, data_: virtools_types.VXTEXTURE_FILTERMODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum_value(bmap.BMMaterial_SetTextureMinMode, data_)
bmap.BMMaterial_SetTextureMinMode(self._get_pointer(), self._get_ckid(), data)
def get_texture_mag_mode(self) -> virtools_types.VXTEXTURE_FILTERMODE: def get_texture_mag_mode(self) -> virtools_types.VXTEXTURE_FILTERMODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.VXTEXTURE_FILTERMODE, bmap.BMMaterial_GetTextureMagMode)
bmap.BMMaterial_GetTextureMagMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXTEXTURE_FILTERMODE(data.value)
def set_texture_mag_mode(self, data_: virtools_types.VXTEXTURE_FILTERMODE) -> None: def set_texture_mag_mode(self, data_: virtools_types.VXTEXTURE_FILTERMODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum_value(bmap.BMMaterial_SetTextureMagMode, data_)
bmap.BMMaterial_SetTextureMagMode(self._get_pointer(), self._get_ckid(), data)
def get_texture_address_mode(self) -> virtools_types.VXTEXTURE_ADDRESSMODE: def get_texture_address_mode(self) -> virtools_types.VXTEXTURE_ADDRESSMODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.VXTEXTURE_ADDRESSMODE, bmap.BMMaterial_GetTextureAddressMode)
bmap.BMMaterial_GetTextureAddressMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXTEXTURE_ADDRESSMODE(data.value)
def set_texture_address_mode(self, data_: virtools_types.VXTEXTURE_ADDRESSMODE) -> None: def set_texture_address_mode(self, data_: virtools_types.VXTEXTURE_ADDRESSMODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum_value(bmap.BMMaterial_SetTextureAddressMode, data_)
bmap.BMMaterial_SetTextureAddressMode(self._get_pointer(), self._get_ckid(), data)
def get_source_blend(self) -> virtools_types.VXBLEND_MODE: def get_source_blend(self) -> virtools_types.VXBLEND_MODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.VXBLEND_MODE, bmap.BMMaterial_GetSourceBlend)
bmap.BMMaterial_GetSourceBlend(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXBLEND_MODE(data.value)
def set_source_blend(self, data_: virtools_types.VXBLEND_MODE) -> None: def set_source_blend(self, data_: virtools_types.VXBLEND_MODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum_value(bmap.BMMaterial_SetSourceBlend, data_)
bmap.BMMaterial_SetSourceBlend(self._get_pointer(), self._get_ckid(), data)
def get_dest_blend(self) -> virtools_types.VXBLEND_MODE: def get_dest_blend(self) -> virtools_types.VXBLEND_MODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.VXBLEND_MODE, bmap.BMMaterial_GetDestBlend)
bmap.BMMaterial_GetDestBlend(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXBLEND_MODE(data.value)
def set_dest_blend(self, data_: virtools_types.VXBLEND_MODE) -> None: def set_dest_blend(self, data_: virtools_types.VXBLEND_MODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum_value(bmap.BMMaterial_SetDestBlend, data_)
bmap.BMMaterial_SetDestBlend(self._get_pointer(), self._get_ckid(), data)
def get_fill_mode(self) -> virtools_types.VXFILL_MODE: def get_fill_mode(self) -> virtools_types.VXFILL_MODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.VXFILL_MODE, bmap.BMMaterial_GetFillMode)
bmap.BMMaterial_GetFillMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXFILL_MODE(data.value)
def set_fill_mode(self, data_: virtools_types.VXFILL_MODE) -> None: def set_fill_mode(self, data_: virtools_types.VXFILL_MODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum_value(bmap.BMMaterial_SetFillMode, data_)
bmap.BMMaterial_SetFillMode(self._get_pointer(), self._get_ckid(), data)
def get_shade_mode(self) -> virtools_types.VXSHADE_MODE: def get_shade_mode(self) -> virtools_types.VXSHADE_MODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.VXSHADE_MODE, bmap.BMMaterial_GetShadeMode)
bmap.BMMaterial_GetShadeMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXSHADE_MODE(data.value)
def set_shade_mode(self, data_: virtools_types.VXSHADE_MODE) -> None: def set_shade_mode(self, data_: virtools_types.VXSHADE_MODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum_value(bmap.BMMaterial_SetShadeMode, data_)
bmap.BMMaterial_SetShadeMode(self._get_pointer(), self._get_ckid(), data)
def get_alpha_test_enabled(self) -> bool: def get_alpha_test_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool() return self._get_bool_value(bmap.BMMaterial_GetAlphaTestEnabled)
bmap.BMMaterial_GetAlphaTestEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def set_alpha_test_enabled(self, data_: bool) -> None: def set_alpha_test_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_) self._set_bool_value(bmap.BMMaterial_SetAlphaTestEnabled, data_)
bmap.BMMaterial_SetAlphaTestEnabled(self._get_pointer(), self._get_ckid(), data)
def get_alpha_blend_enabled(self) -> bool: def get_alpha_blend_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool() return self._get_bool_value(bmap.BMMaterial_GetAlphaBlendEnabled)
bmap.BMMaterial_GetAlphaBlendEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def set_alpha_blend_enabled(self, data_: bool) -> None: def set_alpha_blend_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_) self._set_bool_value(bmap.BMMaterial_SetAlphaBlendEnabled, data_)
bmap.BMMaterial_SetAlphaBlendEnabled(self._get_pointer(), self._get_ckid(), data)
def get_perspective_correction_enabled(self) -> bool: def get_perspective_correction_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool() return self._get_bool_value(bmap.BMMaterial_GetPerspectiveCorrectionEnabled)
bmap.BMMaterial_GetPerspectiveCorrectionEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def set_perspective_correction_enabled(self, data_: bool) -> None: def set_perspective_correction_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_) self._set_bool_value(bmap.BMMaterial_SetPerspectiveCorrectionEnabled, data_)
bmap.BMMaterial_SetPerspectiveCorrectionEnabled(self._get_pointer(), self._get_ckid(), data)
def get_z_write_enabled(self) -> bool: def get_z_write_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool() return self._get_bool_value(bmap.BMMaterial_GetZWriteEnabled)
bmap.BMMaterial_GetZWriteEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def set_z_write_enabled(self, data_: bool) -> None: def set_z_write_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_) self._set_bool_value(bmap.BMMaterial_SetZWriteEnabled, data_)
bmap.BMMaterial_SetZWriteEnabled(self._get_pointer(), self._get_ckid(), data)
def get_two_sided_enabled(self) -> bool: def get_two_sided_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool() return self._get_bool_value(bmap.BMMaterial_GetTwoSidedEnabled)
bmap.BMMaterial_GetTwoSidedEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def set_two_sided_enabled(self, data_: bool) -> None: def set_two_sided_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_) self._set_bool_value(bmap.BMMaterial_SetTwoSidedEnabled, data_)
bmap.BMMaterial_SetTwoSidedEnabled(self._get_pointer(), self._get_ckid(), data)
def get_alpha_ref(self) -> int: def get_alpha_ref(self) -> int:
data: bmap.bm_CKBYTE = bmap.bm_CKBYTE() return self._get_integral_value(bmap.bm_CKBYTE, bmap.BMMaterial_GetAlphaRef)
bmap.BMMaterial_GetAlphaRef(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def set_alpha_ref(self, data_: int): def set_alpha_ref(self, data_: int):
data: bmap.bm_CKBYTE = bmap.bm_CKBYTE(data_) self._set_integral_value(bmap.bm_CKBYTE, bmap.BMMaterial_SetAlphaRef, data_)
bmap.BMMaterial_SetAlphaRef(self._get_pointer(), self._get_ckid(), data)
def get_alpha_func(self) -> virtools_types.VXCMPFUNC: def get_alpha_func(self) -> virtools_types.VXCMPFUNC:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.VXCMPFUNC, bmap.BMMaterial_GetAlphaFunc)
bmap.BMMaterial_GetAlphaFunc(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXCMPFUNC(data.value)
def set_alpha_func(self, data_: virtools_types.VXCMPFUNC) -> None: def set_alpha_func(self, data_: virtools_types.VXCMPFUNC) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum_value(bmap.BMMaterial_SetAlphaFunc, data_)
bmap.BMMaterial_SetAlphaFunc(self._get_pointer(), self._get_ckid(), data)
def get_z_func(self) -> virtools_types.VXCMPFUNC: def get_z_func(self) -> virtools_types.VXCMPFUNC:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.VXCMPFUNC, bmap.BMMaterial_GetZFunc)
bmap.BMMaterial_GetZFunc(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXCMPFUNC(data.value)
def set_z_func(self, data_: virtools_types.VXCMPFUNC) -> None: def set_z_func(self, data_: virtools_types.VXCMPFUNC) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum_value(bmap.BMMaterial_SetZFunc, data_)
bmap.BMMaterial_SetZFunc(self._get_pointer(), self._get_ckid(), data)
class BMMesh(BMObject): class BMMesh(BMObject):
def get_lit_mode(self) -> virtools_types.VXMESH_LITMODE: def get_lit_mode(self) -> virtools_types.VXMESH_LITMODE:
mode: bmap.bm_enum = bmap.bm_enum() return self._get_enum_value(virtools_types.VXMESH_LITMODE, bmap.BMMesh_GetLitMode)
bmap.BMMesh_GetLitMode(self._get_pointer(), self._get_ckid(), ctypes.byref(mode))
return virtools_types.VXMESH_LITMODE(mode.value)
def set_lit_mode(self, mode_: virtools_types.VXMESH_LITMODE) -> None: def set_lit_mode(self, mode_: virtools_types.VXMESH_LITMODE) -> None:
mode: bmap.bm_enum = bmap.bm_enum(mode_.value) self._set_enum_value(bmap.BMMesh_SetLitMode, mode_)
bmap.BMMesh_SetLitMode(self._get_pointer(), self._get_ckid(), mode)
def get_vertex_count(self) -> int: def get_vertex_count(self) -> int:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD() return self._get_integral_value(bmap.bm_CKDWORD, bmap.BMMesh_GetVertexCount)
bmap.BMMesh_GetVertexCount(self._get_pointer(), self._get_ckid(), ctypes.byref(count))
return count.value
def set_vertex_count(self, count_: int) -> None: def set_vertex_count(self, count_: int) -> None:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count_) self._set_integral_value(bmap.bm_CKDWORD, bmap.BMMesh_SetVertexCount, count_)
bmap.BMMesh_SetVertexCount(self._get_pointer(), self._get_ckid(), count)
def get_vertex_positions(self) -> typing.Iterator[virtools_types.VxVector3]: def get_vertex_positions(self) -> typing.Iterator[virtools_types.VxVector3]:
# get raw pointer and return # get raw pointer and return
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p() raw_vector = self._get_pointer_value(bmap.bm_VxVector3_p, bmap.BMMesh_GetVertexPositions)
bmap.BMMesh_GetVertexPositions(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector)) return _Utils.vxvector3_iterator(raw_vector, self.get_vertex_count())
return _vxvector3_iterator(raw_vector, self.get_vertex_count())
def set_vertex_positions(self, itor: typing.Iterator[virtools_types.VxVector3]) -> None: def set_vertex_positions(self, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
# get raw float pointer and assign # get raw float pointer and assign
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p() raw_vector = self._get_pointer_value(bmap.bm_VxVector3_p, bmap.BMMesh_GetVertexPositions)
bmap.BMMesh_GetVertexPositions(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector)) _Utils.vxvector3_assigner(raw_vector, self.get_vertex_count(), itor)
_vxvector3_assigner(raw_vector, self.get_vertex_count(), itor)
def get_vertex_normals(self) -> typing.Iterator[virtools_types.VxVector3]: def get_vertex_normals(self) -> typing.Iterator[virtools_types.VxVector3]:
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p() raw_vector = self._get_pointer_value(bmap.bm_VxVector3_p, bmap.BMMesh_GetVertexNormals)
bmap.BMMesh_GetVertexNormals(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector)) return _Utils.vxvector3_iterator(raw_vector, self.get_vertex_count())
return _vxvector3_iterator(raw_vector, self.get_vertex_count())
def set_vertex_normals(self, itor: typing.Iterator[virtools_types.VxVector3]) -> None: def set_vertex_normals(self, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p() raw_vector = self._get_pointer_value(bmap.bm_VxVector3_p, bmap.BMMesh_GetVertexNormals)
bmap.BMMesh_GetVertexNormals(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector)) _Utils.vxvector3_assigner(raw_vector, self.get_vertex_count(), itor)
_vxvector3_assigner(raw_vector, self.get_vertex_count(), itor)
def get_vertex_uvs(self) -> typing.Iterator[virtools_types.VxVector2]: def get_vertex_uvs(self) -> typing.Iterator[virtools_types.VxVector2]:
raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p() raw_vector = self._get_pointer_value(bmap.bm_VxVector2_p, bmap.BMMesh_GetVertexUVs)
bmap.BMMesh_GetVertexUVs(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector)) return _Utils.vxvector2_iterator(raw_vector, self.get_vertex_count())
return _vxvector2_iterator(raw_vector, self.get_vertex_count())
def set_vertex_uvs(self, itor: typing.Iterator[virtools_types.VxVector2]) -> None: def set_vertex_uvs(self, itor: typing.Iterator[virtools_types.VxVector2]) -> None:
raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p() raw_vector = self._get_pointer_value(bmap.bm_VxVector2_p, bmap.BMMesh_GetVertexUVs)
bmap.BMMesh_GetVertexUVs(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector)) _Utils.vxvector2_assigner(raw_vector, self.get_vertex_count(), itor)
_vxvector2_assigner(raw_vector, self.get_vertex_count(), itor)
def get_face_count(self) -> int: def get_face_count(self) -> int:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD() return self._get_integral_value(bmap.bm_CKDWORD, bmap.BMMesh_GetFaceCount)
bmap.BMMesh_GetFaceCount(self._get_pointer(), self._get_ckid(), ctypes.byref(count))
return count.value
def set_face_count(self, count_: int) -> None: def set_face_count(self, count_: int) -> None:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count_) self._set_integral_value(bmap.bm_CKDWORD, bmap.BMMesh_SetFaceCount, count_)
bmap.BMMesh_SetFaceCount(self._get_pointer(), self._get_ckid(), count)
def get_face_indices(self) -> typing.Iterator[virtools_types.CKFaceIndices]: def get_face_indices(self) -> typing.Iterator[virtools_types.CKFaceIndices]:
raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p() raw_idx = self._get_pointer_value(bmap.bm_CKWORD_p, bmap.BMMesh_GetFaceIndices)
bmap.BMMesh_GetFaceIndices(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_idx)) return _Utils.ckfaceindices_iterator(raw_idx, self.get_face_count())
return _ckfaceindices_iterator(raw_idx, self.get_face_count())
def set_face_indices(self, itor: typing.Iterator[virtools_types.CKFaceIndices]) -> None: def set_face_indices(self, itor: typing.Iterator[virtools_types.CKFaceIndices]) -> None:
raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p() raw_idx = self._get_pointer_value(bmap.bm_CKWORD_p, bmap.BMMesh_GetFaceIndices)
bmap.BMMesh_GetFaceIndices(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_idx)) _Utils.ckfaceindices_assigner(raw_idx, self.get_face_count(), itor)
_ckfaceindices_assigner(raw_idx, self.get_face_count(), itor)
def get_face_material_slot_indexs(self) -> typing.Iterator[int]: def get_face_material_slot_indexs(self) -> typing.Iterator[int]:
raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p() raw_idx = self._get_pointer_value(bmap.bm_CKWORD_p, bmap.BMMesh_GetFaceMaterialSlotIndexs)
bmap.BMMesh_GetFaceMaterialSlotIndexs(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_idx))
for i in range(self.get_face_count()): for i in range(self.get_face_count()):
yield raw_idx[i] yield raw_idx[i]
def set_face_material_slot_indexs(self, itor: typing.Iterator[int]) -> None: def set_face_material_slot_indexs(self, itor: typing.Iterator[int]) -> None:
raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p() raw_idx = self._get_pointer_value(bmap.bm_CKWORD_p, bmap.BMMesh_GetFaceMaterialSlotIndexs)
bmap.BMMesh_GetFaceMaterialSlotIndexs(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_idx)) try:
for i in range(self.get_face_count()): for i in range(self.get_face_count()):
raw_idx[i] = next(itor) raw_idx[i] = next(itor)
except StopIteration:
_Utils.raise_out_of_length_exception()
def get_material_slot_count(self) -> int: def get_material_slot_count(self) -> int:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD() return self._get_integral_value(bmap.bm_CKDWORD, bmap.BMMesh_GetMaterialSlotCount)
bmap.BMMesh_GetMaterialSlotCount(self._get_pointer(), self._get_ckid(), ctypes.byref(count))
return count.value
def set_material_slot_count(self, count_: int) -> None: def set_material_slot_count(self, count_: int) -> None:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count_) self._set_integral_value(bmap.bm_CKDWORD, bmap.BMMesh_SetMaterialSlotCount, count_)
bmap.BMMesh_SetMaterialSlotCount(self._get_pointer(), self._get_ckid(), count)
def get_material_slots(self) -> typing.Iterator[BMMaterial | None]: def get_material_slots(self) -> typing.Iterator[BMMaterial | None]:
idx: bmap.bm_CKDWORD = bmap.bm_CKDWORD() idx: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
@ -519,16 +462,19 @@ class BMMesh(BMObject):
def set_material_slots(self, itor: typing.Iterator[BMMaterial | None]) -> None: def set_material_slots(self, itor: typing.Iterator[BMMaterial | None]) -> None:
idx: bmap.bm_CKDWORD = bmap.bm_CKDWORD() idx: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
mtlid: bmap.bm_CKID = bmap.bm_CKID() mtlid: bmap.bm_CKID = bmap.bm_CKID()
for i in range(self.get_material_slot_count()): try:
idx.value = i for i in range(self.get_material_slot_count()):
# analyze mtl item idx.value = i
mtlobj: BMMaterial | None = next(itor) # analyze mtl item
if mtlobj is None: mtlobj: BMMaterial | None = next(itor)
mtlid.value = g_InvalidCKID if mtlobj is None:
else: mtlid.value = g_InvalidCKID
mtlid = mtlobj._get_ckid() else:
# set mtlid = mtlobj._get_ckid()
bmap.BMMesh_SetMaterialSlot(self._get_pointer(), self._get_ckid(), idx, mtlid) # set
bmap.BMMesh_SetMaterialSlot(self._get_pointer(), self._get_ckid(), idx, mtlid)
except StopIteration:
_Utils.raise_out_of_length_exception()
class BM3dObject(BMObject): class BM3dObject(BMObject):
def get_world_matrix(self) -> virtools_types.VxMatrix: def get_world_matrix(self) -> virtools_types.VxMatrix:
@ -560,26 +506,20 @@ class BM3dObject(BMObject):
bmap.BM3dObject_SetCurrentMesh(self._get_pointer(), self._get_ckid(), ckid) bmap.BM3dObject_SetCurrentMesh(self._get_pointer(), self._get_ckid(), ckid)
def get_visibility(self) -> bool: def get_visibility(self) -> bool:
visb: bmap.bm_bool = bmap.bm_bool() return self._get_bool_value(bmap.BM3dObject_GetVisibility)
bmap.BM3dObject_GetVisibility(self._get_pointer(), self._get_ckid(), ctypes.byref(visb))
return visb.value
def set_visibility(self, visb_: bool) -> None: def set_visibility(self, visb_: bool) -> None:
visb: bmap.bm_bool = bmap.bm_bool(visb_) self._set_bool_value(bmap.BM3dObject_SetVisibility, visb_)
bmap.BM3dObject_SetVisibility(self._get_pointer(), self._get_ckid(), visb)
class BMGroup(BMObject): class BMGroup(BMObject):
def add_object(self, member: BM3dObject) -> None: def add_object(self, member: BM3dObject) -> None:
bmap.BMGroup_AddObject(self._get_pointer(), self._get_ckid(), member._get_ckid()) bmap.BMGroup_AddObject(self._get_pointer(), self._get_ckid(), member._get_ckid())
def get_object_count(self) -> int: def get_object_count(self) -> int:
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD() return self._get_integral_value(bmap.bm_CKDWORD, bmap.BMGroup_GetObjectCount)
bmap.BMGroup_GetObjectCount(self._get_pointer(), self._get_ckid(), ctypes.byref(csize))
return csize.value
def get_objects(self) -> typing.Iterator[BM3dObject]: def get_objects(self) -> typing.Iterator[BM3dObject]:
# get list size
csize: int = self.get_object_count() csize: int = self.get_object_count()
# iterate list # iterate list
cidx: bmap.bm_CKDWORD = bmap.bm_CKDWORD() cidx: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
retid: bmap.bm_CKID = bmap.bm_CKID() retid: bmap.bm_CKID = bmap.bm_CKID()
@ -621,16 +561,16 @@ class BMFileReader(_AbstractPointer):
self._set_pointer(g_InvalidPtr) self._set_pointer(g_InvalidPtr)
def __get_ckobject_count(self, def __get_ckobject_count(self,
count_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD_p], bool]) -> int: count_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD_p], bmap.bm_bool]) -> int:
# get size # get size
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD() csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
count_getter(self._get_pointer(), ctypes.byref(csize)) count_getter(self._get_pointer(), ctypes.byref(csize))
return csize.value return csize.value
def __get_ckobjects(self, def __get_ckobjects(self,
class_type: type[TCKObj], class_type: type[TCKObject],
count_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD_p], bool], count_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD_p], bmap.bm_bool],
obj_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD, bmap.bm_CKID_p], bool]) -> typing.Iterator[TCKObj]: obj_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD, bmap.bm_CKID_p], bmap.bm_bool]) -> typing.Iterator[TCKObject]:
# get size first # get size first
csize: int = self.__get_ckobject_count(count_getter) csize: int = self.__get_ckobject_count(count_getter)
@ -646,47 +586,23 @@ class BMFileReader(_AbstractPointer):
def get_texture_count(self) -> int: def get_texture_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetTextureCount) return self.__get_ckobject_count(bmap.BMFile_GetTextureCount)
def get_textures(self) -> typing.Iterator[BMTexture]: def get_textures(self) -> typing.Iterator[BMTexture]:
return self.__get_ckobjects( return self.__get_ckobjects(BMTexture, bmap.BMFile_GetTextureCount, bmap.BMFile_GetTexture)
BMTexture,
bmap.BMFile_GetTextureCount,
bmap.BMFile_GetTexture
)
def get_material_count(self) -> int: def get_material_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetMaterialCount) return self.__get_ckobject_count(bmap.BMFile_GetMaterialCount)
def get_materials(self) -> typing.Iterator[BMMaterial]: def get_materials(self) -> typing.Iterator[BMMaterial]:
return self.__get_ckobjects( return self.__get_ckobjects(BMMaterial, bmap.BMFile_GetMaterialCount, bmap.BMFile_GetMaterial)
BMMaterial,
bmap.BMFile_GetMaterialCount,
bmap.BMFile_GetMaterial
)
def get_mesh_count(self) -> int: def get_mesh_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetMeshCount) return self.__get_ckobject_count(bmap.BMFile_GetMeshCount)
def get_meshs(self) -> typing.Iterator[BMMesh]: def get_meshs(self) -> typing.Iterator[BMMesh]:
return self.__get_ckobjects( return self.__get_ckobjects(BMMesh, bmap.BMFile_GetMeshCount, bmap.BMFile_GetMesh)
BMMesh,
bmap.BMFile_GetMeshCount,
bmap.BMFile_GetMesh
)
def get_3dobject_count(self) -> int: def get_3dobject_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_Get3dObjectCount) return self.__get_ckobject_count(bmap.BMFile_Get3dObjectCount)
def get_3dobjects(self) -> typing.Iterator[BM3dObject]: def get_3dobjects(self) -> typing.Iterator[BM3dObject]:
return self.__get_ckobjects( return self.__get_ckobjects(BM3dObject, bmap.BMFile_Get3dObjectCount, bmap.BMFile_Get3dObject)
BM3dObject,
bmap.BMFile_Get3dObjectCount,
bmap.BMFile_Get3dObject
)
def get_group_count(self) -> int: def get_group_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetGroupCount) return self.__get_ckobject_count(bmap.BMFile_GetGroupCount)
def get_groups(self) -> typing.Iterator[BMGroup]: def get_groups(self) -> typing.Iterator[BMGroup]:
return self.__get_ckobjects( return self.__get_ckobjects(BMGroup, bmap.BMFile_GetGroupCount, bmap.BMFile_GetGroup)
BMGroup,
bmap.BMFile_GetGroupCount,
bmap.BMFile_GetGroup
)
class BMFileWriter(_AbstractPointer): class BMFileWriter(_AbstractPointer):
def __init__(self, temp_folder_: str, texture_folder_: str, encodings_: tuple[str]): def __init__(self, temp_folder_: str, texture_folder_: str, encodings_: tuple[str]):
@ -728,8 +644,8 @@ class BMFileWriter(_AbstractPointer):
self._set_pointer(g_InvalidPtr) self._set_pointer(g_InvalidPtr)
def __create_ckobject(self, def __create_ckobject(self,
class_type: type[TCKObj], class_type: type[TCKObject],
creator: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID_p], bool]) -> TCKObj: creator: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID_p], bmap.bm_bool]) -> TCKObject:
# prepare id container # prepare id container
retid: bmap.bm_CKID = bmap.bm_CKID() retid: bmap.bm_CKID = bmap.bm_CKID()
# create new one # create new one
@ -738,34 +654,15 @@ class BMFileWriter(_AbstractPointer):
return class_type(self._get_pointer(), retid) return class_type(self._get_pointer(), retid)
def create_texture(self) -> BMTexture: def create_texture(self) -> BMTexture:
return self.__create_ckobject( return self.__create_ckobject(BMTexture, bmap.BMFile_CreateTexture)
BMTexture,
bmap.BMFile_CreateTexture
)
def create_material(self) -> BMMaterial: def create_material(self) -> BMMaterial:
return self.__create_ckobject( return self.__create_ckobject(BMMaterial, bmap.BMFile_CreateMaterial)
BMMaterial,
bmap.BMFile_CreateMaterial
)
def create_mesh(self) -> BMMesh: def create_mesh(self) -> BMMesh:
return self.__create_ckobject( return self.__create_ckobject(BMMesh, bmap.BMFile_CreateMesh)
BMMesh,
bmap.BMFile_CreateMesh
)
def create_3dobject(self) -> BM3dObject: def create_3dobject(self) -> BM3dObject:
return self.__create_ckobject( return self.__create_ckobject(BM3dObject, bmap.BMFile_Create3dObject)
BM3dObject,
bmap.BMFile_Create3dObject
)
def create_group(self) -> BMGroup: def create_group(self) -> BMGroup:
return self.__create_ckobject( return self.__create_ckobject(BMGroup, bmap.BMFile_CreateGroup)
BMGroup,
bmap.BMFile_CreateGroup
)
class BMMeshTrans(_AbstractPointer): class BMMeshTrans(_AbstractPointer):
def __init__(self): def __init__(self):
@ -784,8 +681,8 @@ class BMMeshTrans(_AbstractPointer):
bmap.BMMeshTrans_Delete(self._get_pointer()) bmap.BMMeshTrans_Delete(self._get_pointer())
self._set_pointer(g_InvalidPtr) self._set_pointer(g_InvalidPtr)
def parse(self, bmfile: BMFileWriter, objmesh: BMMesh) -> None: def parse(self, objmesh: BMMesh) -> None:
bmap.BMMeshTrans_Parse(self._get_pointer(), bmfile._get_pointer(), objmesh._get_ckid()) bmap.BMMeshTrans_Parse(self._get_pointer(), objmesh._get_pointer(), objmesh._get_ckid())
def prepare_vertex(self, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None: def prepare_vertex(self, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
# prepare count first # prepare count first
@ -795,7 +692,7 @@ class BMMeshTrans(_AbstractPointer):
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p() raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMeshTrans_PrepareVertex(self._get_pointer(), ctypes.byref(raw_vector)) bmap.BMMeshTrans_PrepareVertex(self._get_pointer(), ctypes.byref(raw_vector))
# set by pointer # set by pointer
_vxvector3_assigner(raw_vector, count, itor) _Utils.vxvector3_assigner(raw_vector, count, itor)
def prepare_normal(self, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None: def prepare_normal(self, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count) csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count)
@ -804,7 +701,7 @@ class BMMeshTrans(_AbstractPointer):
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p() raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMeshTrans_PrepareNormal(self._get_pointer(), ctypes.byref(raw_vector)) bmap.BMMeshTrans_PrepareNormal(self._get_pointer(), ctypes.byref(raw_vector))
_vxvector3_assigner(raw_vector, count, itor) _Utils.vxvector3_assigner(raw_vector, count, itor)
def prepare_uv(self, count: int, itor: typing.Iterator[virtools_types.VxVector2]) -> None: def prepare_uv(self, count: int, itor: typing.Iterator[virtools_types.VxVector2]) -> None:
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count) csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count)
@ -813,7 +710,7 @@ class BMMeshTrans(_AbstractPointer):
raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p() raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p()
bmap.BMMeshTrans_PrepareUV(self._get_pointer(), ctypes.byref(raw_vector)) bmap.BMMeshTrans_PrepareUV(self._get_pointer(), ctypes.byref(raw_vector))
_vxvector2_assigner(raw_vector, count, itor) _Utils.vxvector2_assigner(raw_vector, count, itor)
def prepare_mtl_slot(self, count: int, itor: typing.Iterator[BMMaterial | None]) -> None: def prepare_mtl_slot(self, count: int, itor: typing.Iterator[BMMaterial | None]) -> None:
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count) csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count)
@ -821,15 +718,17 @@ class BMMeshTrans(_AbstractPointer):
raw_ckid: bmap.bm_CKID_p = bmap.bm_CKID_p() raw_ckid: bmap.bm_CKID_p = bmap.bm_CKID_p()
bmap.BMMeshTrans_PrepareMtlSlot(self._get_pointer(), ctypes.byref(raw_ckid)) bmap.BMMeshTrans_PrepareMtlSlot(self._get_pointer(), ctypes.byref(raw_ckid))
try:
idx: int = 0 idx: int = 0
for _ in range(count): for _ in range(count):
usermtl: BMMaterial | None = next(itor) usermtl: BMMaterial | None = next(itor)
if usermtl is None: if usermtl is None:
raw_ckid[idx] = g_InvalidCKID raw_ckid[idx] = g_InvalidCKID
else: else:
raw_ckid[idx] = usermtl._get_ckid().value raw_ckid[idx] = usermtl._get_ckid().value
idx += 1 idx += 1
except StopIteration:
_Utils.raise_out_of_length_exception()
def prepare_face(self, def prepare_face(self,
count: int, count: int,
@ -853,13 +752,16 @@ class BMMeshTrans(_AbstractPointer):
# iterate and assign # iterate and assign
# assigne triple indices # assigne triple indices
_ckfaceindices_assigner(raw_vec_idx, count, vec_idx) _Utils.ckfaceindices_assigner(raw_vec_idx, count, vec_idx)
_ckfaceindices_assigner(raw_nml_idx, count, nml_idx) _Utils.ckfaceindices_assigner(raw_nml_idx, count, nml_idx)
_ckfaceindices_assigner(raw_uv_idx, count, uv_idx) _Utils.ckfaceindices_assigner(raw_uv_idx, count, uv_idx)
# assign mtl index # assign mtl index
idx: int = 0 try:
for _ in range(count): idx: int = 0
raw_mtl_idx[idx] = next(mtl_idx) for _ in range(count):
idx += 1 raw_mtl_idx[idx] = next(mtl_idx)
idx += 1
except StopIteration:
_Utils.raise_out_of_length_exception()
#endregion #endregion

View File

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

View File

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

View File

@ -18,13 +18,18 @@ Since libcmo21 0.2.0, we only provide it in CMake build system. So Windows user
### YYCCommonplace ### YYCCommonplace
You should clone YYCCommonplace and switch to the latest release tag (or specified commit hash provided with libcmo21 release infos if you are building for specific libcmo21 version). Then compile it **in C++ 20 mode** (this is crucial because libcmo21 use C++ 20, and YYCCommonplace's ABI is incompatible between C++ 17 version and C++ 20 version). Finally install it as CMake package. You should clone YYCCommonplace and switch to the latest release tag (or specified commit hash provided with libcmo21 release infos if you are building for specific libcmo21 version). When configuring YYCCommonplace, you should notice following infos:
* Please make sure that you have specified C++ 20 explicitly by passing `-DCMAKE_CXX_STANDARD=20` in command line. This is crucial because libcmo21 use C++ 20, and YYCCommonplace's ABI is incompatible between C++ 17 version and C++ 20 version.
* If you need `BMap` in final libcmo21 built artifacts, and you are in non-Windows system now, please specify position independent code flag by passing `-DCMAKE_POSITION_INDEPENDENT_CODE=True` in command line. GCC and Clang will reject linking if you don't flag it.
After configuring, you can normally build YYCCommonplace like a common CMake project.
Please note if your final program or dynamic library is provided for end user, please choose `RelWithDebInfo` build type (`Release` is not suggested because it will strip all debug infos and it is not good for bug reporter, which is embedded in program, to report crash). If final program is served for programmer debugging, please choose `Debug` build type. Please note if your final program or dynamic library is provided for end user, please choose `RelWithDebInfo` build type (`Release` is not suggested because it will strip all debug infos and it is not good for bug reporter, which is embedded in program, to report crash). If final program is served for programmer debugging, please choose `Debug` build type.
### stb ### stb
You should clone stb repository first. In ideally scenario, we suggest you switch to the latest commit. However, all builds are actually only run on a specific commit hash `5736b15f7ea0ffb08dd38af21067c314d6a3aae9`. So if the latest commit is not work, please switch to this commit hash instead. You should clone stb repository first, then switch to a specific commit hash `2e2bef463a5b53ddf8bb788e25da6b8506314c08`. In ideally scenario, people like to choose the latest commit. However, I not frequently update this dependency.
### zlib ### zlib
@ -36,7 +41,7 @@ If you are running on non-Windows system. You usually do not need to do anything
### Directory Hierarchy ### Directory Hierarchy
First, create subdirectory `Bin/build` and `Bin/install`. First, create subdirectory `Bin/build` and `Bin/install` at the root directory of libcmo21.
### Configuration ### Configuration
@ -54,8 +59,8 @@ The arguments in command should be replaced by:
The switches in command can be switched as you wish: The switches in command can be switched as you wish:
* `NEMO_BUILD_UNVIRT`: Build `unvirt`, a command line application debugging Virtools files. * `NEMO_BUILD_UNVIRT`: Build `Unvirt`, a command line application debugging Virtools files.
* `NEMO_BUILD_BMAP`: Build `BMap`, a dynamic library specific used for loading Ballance map file. * `NEMO_BUILD_BMAP`: Build `BMap`, a dynamic library specific used for loading Ballance map file. If you are coming from my another project [BallanceBlenderPlugin](https://github.com/yyc12345/BallanceBlenderHelper), this is what you need.
* `NEMO_BUILD_DOC`: Build the document of libcmo21. * `NEMO_BUILD_DOC`: Build the document of libcmo21.
### Build ### Build

View File

@ -118,6 +118,7 @@ public class CSharpWriter {
ret.mMarshalAs = "UnmanagedType.SysInt"; ret.mMarshalAs = "UnmanagedType.SysInt";
ret.mCsType = "IntPtr"; ret.mCsType = "IntPtr";
} }
break;
case "CK_ID": case "CK_ID":
if (vt_pointer_level == 0) { if (vt_pointer_level == 0) {
ret.mMarshalAs = "UnmanagedType.U4"; ret.mMarshalAs = "UnmanagedType.U4";
@ -195,11 +196,14 @@ public class CSharpWriter {
case "VXSHADE_MODE": case "VXSHADE_MODE":
case "VXCMPFUNC": case "VXCMPFUNC":
case "VXMESH_LITMODE": case "VXMESH_LITMODE":
// all enum share the same underlying type. // all enum type use the same strategy
if (vt_pointer_level == 0) { if (vt_pointer_level == 0) {
// all enum type should be marshaled as its underlying type
// but we can use its name in C# directly.
ret.mMarshalAs = "UnmanagedType.U4"; ret.mMarshalAs = "UnmanagedType.U4";
ret.mCsType = "uint"; ret.mCsType = vt_base_type;
} else { } else {
// for pointer type, use IntPtr instead.
ret.mMarshalAs = "UnmanagedType.SysInt"; ret.mMarshalAs = "UnmanagedType.SysInt";
ret.mCsType = "IntPtr"; ret.mCsType = "IntPtr";
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -86,19 +86,15 @@ target_include_directories(LibCmo
PUBLIC PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE
YYCC::YYCCommonplace
ZLIB::ZLIB
stb::stb-image
) )
target_link_libraries(LibCmo target_link_libraries(LibCmo
PRIVATE PUBLIC
YYCC::YYCCommonplace YYCC::YYCCommonplace
PRIVATE
ZLIB::ZLIB ZLIB::ZLIB
stb::stb-image stb::stb-image
) )
if (NOT WIN32) if (NOT WIN32)
target_include_directories(LibCmo PRIVATE Iconv::Iconv)
target_link_libraries(LibCmo PRIVATE Iconv::Iconv) target_link_libraries(LibCmo PRIVATE Iconv::Iconv)
endif () endif ()
# Setup C++ standard # Setup C++ standard

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
#include "VxMath.hpp" #include "VxMath.hpp"
#include <cmath> #include <cmath>
#include <stb_image_resize.h> #include <deprecated/stb_image_resize.h>
namespace LibCmo::VxMath { namespace LibCmo::VxMath {

View File

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

View File

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

3
Scripts/.gitignore vendored Normal file
View File

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

View File

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

View File

View File

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

View File

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

View File

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

View File

@ -61,7 +61,7 @@ namespace Unvirt {
} }
// check flag match // check flag match
if (LibCmo::EnumsHelper::Has(val, item.first)) { if (YYCC::EnumHelper::Has(val, item.first)) {
// add splittor if it not the first entry // add splittor if it not the first entry
if (strl.size() != 0u && splitor != nullptr) { if (strl.size() != 0u && splitor != nullptr) {
strl += splitor; strl += splitor;

View File

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