Compare commits

17 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
73cda9f905 feat: update BMapSharp
- add struct assigner and iterator but still has bugs (struct padding issue)
- add function bindings for BM3dObject and BMGroup.
- add basic ctor and dtor for BMMeshTrans.
2024-10-29 15:12:00 +08:00
4d04b38d52 feat: continue improving BMapSharp.
- add BMFileWriter in BMapSharp.
2024-10-27 11:41:49 +08:00
623334f863 feat: update BMapSharp.
- update the function calling in BMapSharp.BMFileReader. (hope JIT can optimize my bad code served for beauty)
- remove outdated content in COMPILE.md
2024-10-24 16:39:11 +08:00
f781bcd63d doc: fix compile manual
- move compile infos into an individual file.
- remove outdated compile manual, use latest one instead.
2024-10-18 15:04:54 +08:00
34 changed files with 1402 additions and 990 deletions

View File

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

View File

@ -58,11 +58,11 @@ namespace BMapSharp {
// the native memory we created is a simple array and each item is a pointer to a NULL-terminated UTF8 string.
// Please note the array self is also NULL-terminated otherwise we don't know its length.
public nint MarshalManagedToNative(object ManagedObj) {
public IntPtr MarshalManagedToNative(object ManagedObj) {
// Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return nint.Zero;
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return IntPtr.Zero;
// Check nullptr object.
if (ManagedObj is null) return nint.Zero;
if (ManagedObj is null) return IntPtr.Zero;
// Check argument type.
string[] castManagedObj = ManagedObj as string[];
if (castManagedObj is null)
@ -70,45 +70,45 @@ namespace BMapSharp {
// Allocate string items first
int szArrayItemCount = castManagedObj.Length;
int szArrayItemSize = Marshal.SizeOf<nint>();
nint[] apString = new nint[szArrayItemCount];
int szArrayItemSize = Marshal.SizeOf<IntPtr>();
IntPtr[] apString = new IntPtr[szArrayItemCount];
for (int i = 0; i < szArrayItemCount; ++i) {
// Check null string
string stringObj = castManagedObj[i];
if (stringObj is null) apString[i] = nint.Zero;
if (stringObj is null) apString[i] = IntPtr.Zero;
else apString[i] = BMStringMarshaler.ToNative(stringObj);
}
// Allocate array pointer now.
nint pArray = Marshal.AllocHGlobal(szArrayItemSize * (szArrayItemCount + 1));
IntPtr pArray = Marshal.AllocHGlobal(szArrayItemSize * (szArrayItemCount + 1));
// Copy string pointer data
Marshal.Copy(apString, 0, pArray, szArrayItemCount);
// Setup NULL ternimal
Marshal.WriteIntPtr(pArray + (szArrayItemSize * szArrayItemCount), nint.Zero);
Marshal.WriteIntPtr(pArray + (szArrayItemSize * szArrayItemCount), IntPtr.Zero);
// Return value
return pArray;
}
public object MarshalNativeToManaged(nint pNativeData) {
public object MarshalNativeToManaged(IntPtr pNativeData) {
// Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.Out)) return null;
// Check nullptr
if (pNativeData == nint.Zero) return null;
if (pNativeData == IntPtr.Zero) return null;
// Get the length of array
int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData);
int szArrayItemSize = Marshal.SizeOf<nint>();
int szArrayItemSize = Marshal.SizeOf<IntPtr>();
// Prepare array cache and read it.
nint[] apString = new nint[szArrayItemCount];
IntPtr[] apString = new IntPtr[szArrayItemCount];
Marshal.Copy(pNativeData, apString, 0, szArrayItemCount);
// Iterate the array and process each string one by one.
string[] ret = new string[szArrayItemCount];
for (int i = 0; i < szArrayItemCount; ++i) {
// Get string pointer
nint pString = apString[i];
if (pString == nint.Zero) {
IntPtr pString = apString[i];
if (pString == IntPtr.Zero) {
ret[i] = null;
continue;
}
@ -120,25 +120,25 @@ namespace BMapSharp {
return ret;
}
public void CleanUpNativeData(nint pNativeData) {
public void CleanUpNativeData(IntPtr pNativeData) {
// Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return;
// Check nullptr
if (pNativeData == nint.Zero) return;
if (pNativeData == IntPtr.Zero) return;
// Get the length of array
int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData);
int szArrayItemSize = Marshal.SizeOf<nint>();
int szArrayItemSize = Marshal.SizeOf<IntPtr>();
// Prepare array cache and read it.
nint[] apString = new nint[szArrayItemCount];
IntPtr[] apString = new IntPtr[szArrayItemCount];
Marshal.Copy(pNativeData, apString, 0, szArrayItemCount);
// Free array self
Marshal.FreeHGlobal(pNativeData);
// Iterate the string pointer array and free them one by one.
foreach (nint pString in apString) {
foreach (IntPtr pString in apString) {
// Free string pointer
if (pString == nint.Zero) continue;
if (pString == IntPtr.Zero) continue;
Marshal.FreeHGlobal(pString);
}
}
@ -157,9 +157,9 @@ namespace BMapSharp {
/// </summary>
/// <param name="ptr">The pointer to array for checking.</param>
/// <returns>The length of array (NULL terminal exclusive).</returns>
internal static int GetArrayLength(nint ptr) {
int count = 0, unit = Marshal.SizeOf<nint>();
while (Marshal.ReadIntPtr(ptr) != nint.Zero) {
internal static int GetArrayLength(IntPtr ptr) {
int count = 0, unit = Marshal.SizeOf<IntPtr>();
while (Marshal.ReadIntPtr(ptr) != IntPtr.Zero) {
ptr += unit;
++count;
}
@ -181,11 +181,11 @@ namespace BMapSharp {
m_MarshalerType = marshaler_type;
}
public nint MarshalManagedToNative(object ManagedObj) {
public IntPtr MarshalManagedToNative(object ManagedObj) {
// Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return nint.Zero;
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return IntPtr.Zero;
// Check requirements.
if (ManagedObj is null) return nint.Zero;
if (ManagedObj is null) return IntPtr.Zero;
string castManagedObj = ManagedObj as string;
if (castManagedObj is null)
throw new MarshalDirectiveException("BMStringMarshaler must be used on a string.");
@ -193,20 +193,20 @@ namespace BMapSharp {
return BMStringMarshaler.ToNative(castManagedObj);
}
public object MarshalNativeToManaged(nint pNativeData) {
public object MarshalNativeToManaged(IntPtr pNativeData) {
// Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.Out)) return null;
// Check nullptr
if (pNativeData == nint.Zero) return null;
if (pNativeData == IntPtr.Zero) return null;
// Call self
return BMStringMarshaler.ToManaged(pNativeData);
}
public void CleanUpNativeData(nint pNativeData) {
public void CleanUpNativeData(IntPtr pNativeData) {
// Check marshaler type
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return;
// Check nullptr
if (pNativeData == nint.Zero) return;
if (pNativeData == IntPtr.Zero) return;
// Free native pointer
Marshal.FreeHGlobal(pNativeData);
}
@ -225,7 +225,7 @@ namespace BMapSharp {
/// </summary>
/// <param name="ptr">The pointer for checking.</param>
/// <returns>The length of C style string (NUL exclusive).</returns>
internal static int GetCStringLength(nint ptr) {
internal static int GetCStringLength(IntPtr ptr) {
int count = 0, unit = Marshal.SizeOf<byte>();
while (Marshal.ReadByte(ptr) != (byte)0) {
ptr += unit;
@ -240,13 +240,13 @@ namespace BMapSharp {
/// </summary>
/// <param name="obj">String object. Caller must make sure this object is not null.</param>
/// <returns>The created native data pointer.</returns>
internal static nint ToNative(string obj) {
internal static IntPtr ToNative(string obj) {
// Encode string first
byte[] encString = Encoding.UTF8.GetBytes(obj);
// Allocate string memory with extra NUL.
int szStringItemCount = encString.Length;
int szStringItemSize = Marshal.SizeOf<byte>();
nint pString = Marshal.AllocHGlobal(szStringItemSize * (szStringItemCount + 1));
IntPtr pString = Marshal.AllocHGlobal(szStringItemSize * (szStringItemCount + 1));
// Copy encoded string data
Marshal.Copy(encString, 0, pString, szStringItemCount);
// Setup NUL
@ -260,7 +260,7 @@ namespace BMapSharp {
/// </summary>
/// <param name="ptr">Native pointer holding string data. Caller must make sure this pointer is not nullptr.</param>
/// <returns>The extracted managed string data.</returns>
internal static string ToManaged(nint ptr) {
internal static string ToManaged(IntPtr ptr) {
// Get the length of given string.
int szStringItemCount = BMStringMarshaler.GetCStringLength(ptr);
int szStringItemSize = Marshal.SizeOf<byte>();
@ -293,7 +293,7 @@ namespace BMapSharp {
#region Function Defines
// ##### GENERATED FUNCTIONS BEGIN #####
/// <summary>BMInit</summary>
/// <returns>True if no error, otherwise False.</returns>
[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>
[DllImport(g_DllName, EntryPoint = "BMFile_Save", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <param name="map_file">Type: BMap::BMFile*. </param>
/// <returns>True if no error, otherwise False.</returns>
@ -636,7 +636,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_GetSaveOptions", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -644,7 +644,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_SetSaveOptions", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -652,7 +652,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_GetVideoFormat", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -660,7 +660,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMTexture_SetVideoFormat", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -780,7 +780,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureBlendMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -788,7 +788,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureBlendMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -796,7 +796,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureMinMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -804,7 +804,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureMinMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -812,7 +812,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureMagMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -820,7 +820,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureMagMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -828,7 +828,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetTextureAddressMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -836,7 +836,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetTextureAddressMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -844,7 +844,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetSourceBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -852,7 +852,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetSourceBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -860,7 +860,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetDestBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -868,7 +868,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetDestBlend", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -876,7 +876,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetFillMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -884,7 +884,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetFillMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -892,7 +892,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetShadeMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -900,7 +900,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetShadeMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -988,7 +988,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetAlphaRef", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -996,7 +996,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetAlphaRef", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -1004,7 +1004,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetAlphaFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -1012,7 +1012,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetAlphaFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -1020,7 +1020,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_GetZFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -1028,7 +1028,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMaterial_SetZFunc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -1036,7 +1036,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMesh_GetLitMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>
@ -1044,7 +1044,7 @@ namespace BMapSharp {
/// <returns>True if no error, otherwise False.</returns>
[DllImport(g_DllName, EntryPoint = "BMMesh_SetLitMode", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
[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>
/// <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>

View File

@ -1,5 +1,5 @@
using System;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using BMapSharp.VirtoolsTypes;
@ -23,6 +23,9 @@ namespace BMapSharp.BMapWrapper {
}
public static class Utils {
#region Constant Values
/// <summary>The representation of invalid raw pointer.</summary>
internal static readonly IntPtr INVALID_PTR = IntPtr.Zero;
/// <summary>The representation of invalid CK_ID.</summary>
@ -32,16 +35,75 @@ namespace BMapSharp.BMapWrapper {
/// It just writes the data in console.
/// </summary>
internal static void BMapSharpCallback(string msg) {
Console.WriteLine(msg);
Console.WriteLine($"[BMapSharp] {msg}");
}
#endregion
#region Help Functions
private static void StructAssigner<T>(IntPtr pstruct, uint count, IEnumerable<T> iem) {
var stride = Marshal.SizeOf<T>();
var itor = iem.GetEnumerator();
for (uint i = 0; i < count; ++i) {
if (!itor.MoveNext()) throw new BMapException("The length of given data is too short when assigning struct array.");
Marshal.StructureToPtr<T>(itor.Current, pstruct, false);
pstruct += stride;
}
}
internal static void VxVector3Assigner(IntPtr pstruct, uint count, IEnumerable<VxVector3> iem)
=> StructAssigner<VxVector3>(pstruct, count, iem);
internal static void VxVector2Assigner(IntPtr pstruct, uint count, IEnumerable<VxVector2> iem)
=> StructAssigner<VxVector2>(pstruct, count, iem);
internal static void CKFaceIndicesAssigner(IntPtr pstruct, uint count, IEnumerable<CKFaceIndices> iem)
=> StructAssigner<CKFaceIndices>(pstruct, count, iem);
internal static void CKShortFaceIndicesAssigner(IntPtr pstruct, uint count, IEnumerable<CKShortFaceIndices> iem)
=> StructAssigner<CKShortFaceIndices>(pstruct, count, iem);
internal static void ShortAssigner(IntPtr pstruct, uint count, IEnumerable<short> iem)
=> StructAssigner<short>(pstruct, count, iem);
internal static void CKIDAssigner(IntPtr pstruct, uint count, IEnumerable<uint> iem)
=> StructAssigner<uint>(pstruct, count, iem);
internal static void CKDWORDAssigner(IntPtr pstruct, uint count, IEnumerable<uint> iem)
=> StructAssigner<uint>(pstruct, count, iem);
private static IEnumerable<T> StructIterator<T>(IntPtr pstruct, uint count) {
var stride = Marshal.SizeOf<T>();
for (uint i = 0; i < count; ++i) {
yield return Marshal.PtrToStructure<T>(pstruct);
pstruct += stride;
}
}
internal static IEnumerable<VxVector3> VxVector3Iterator(IntPtr pstruct, uint count)
=> StructIterator<VxVector3>(pstruct, count);
internal static IEnumerable<VxVector2> VxVector2Iterator(IntPtr pstruct, uint count)
=> StructIterator<VxVector2>(pstruct, count);
internal static IEnumerable<CKFaceIndices> CKFaceIndicesIterator(IntPtr pstruct, uint count)
=> StructIterator<CKFaceIndices>(pstruct, count);
internal static IEnumerable<CKShortFaceIndices> CKShortFaceIndicesIterator(IntPtr pstruct, uint count)
=> StructIterator<CKShortFaceIndices>(pstruct, count);
internal static IEnumerable<short> ShortIterator(IntPtr pstruct, uint count)
=> StructIterator<short>(pstruct, count);
internal static IEnumerable<uint> CKIDIterator(IntPtr pstruct, uint count)
=> StructIterator<uint>(pstruct, count);
internal static IEnumerable<uint> CKDWORDIterator(IntPtr pstruct, uint count)
=> StructIterator<uint>(pstruct, count);
#endregion
#region End User Exposed
private static readonly BMapGuard Singleton = new BMapGuard();
public static bool IsBMapAvailable() {
return !Singleton.IsInvalid;
}
#endregion
}
public abstract class AbstractPointer : SafeHandle {
// TODO: Maybe I need to implement IEquatable, IComparable<T>, and IComparable for AbstractPointer and AbstractCKObject.
// But I give it up. I am lazy. What I have written barely works for me now.
public abstract class AbstractPointer : SafeHandle, IEquatable<AbstractPointer> {
internal AbstractPointer(IntPtr raw_pointer) : base(Utils.INVALID_PTR, true) {
this.handle = raw_pointer;
}
@ -49,216 +111,463 @@ namespace BMapSharp.BMapWrapper {
public override bool IsInvalid => this.handle == Utils.INVALID_PTR;
protected override bool ReleaseHandle() => throw new NotImplementedException();
protected bool isValid() => this.handle != Utils.INVALID_PTR;
protected IntPtr getPointer() => this.handle;
internal bool isValid() => this.handle != Utils.INVALID_PTR;
internal IntPtr getPointer() => this.handle;
// protected AbstractPointer(IntPtr raw_pointer) : base(raw_pointer, true) {}
#region IEquatable
// protected IntPtr GetPointer() => this.handle;
// public override bool IsInvalid { get { return this.handle == Utils.INVALID_PTR; } }
public override bool Equals(object obj) => this.Equals(obj as AbstractPointer);
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) {
// return m_RawPointer.CompareTo(other.m_RawPointer);
// }
public static bool operator ==(AbstractPointer lhs, AbstractPointer 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 !=(AbstractPointer lhs, AbstractPointer rhs) => !(lhs == rhs);
// #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
#endregion
#region Misc
public override int GetHashCode() => this.handle.GetHashCode();
public override string ToString() => this.handle.ToString();
#endregion
}
public abstract class AbstractCKObject {
internal AbstractCKObject(IntPtr raw_pointer, uint ckid) {
m_RawPointer = raw_pointer;
public abstract class AbstractCKObject : SafeHandle, IEquatable<AbstractCKObject> {
// Same as AbstractPointer, but not own this handle.
internal AbstractCKObject(IntPtr raw_pointer, uint ckid) : base(Utils.INVALID_PTR, false) {
this.handle = raw_pointer;
m_CKID = ckid;
}
private readonly IntPtr m_RawPointer;
public override bool IsInvalid => this.handle == Utils.INVALID_PTR;
protected override bool ReleaseHandle() => throw new NotImplementedException();
private readonly uint m_CKID;
protected bool isValid() => m_RawPointer != Utils.INVALID_PTR && m_RawPointer != Utils.INVALID_CKID;
protected IntPtr getPointer() => m_RawPointer;
protected uint getCKID() => m_CKID;
internal bool isValid() => this.handle != Utils.INVALID_PTR && m_CKID != Utils.INVALID_CKID;
internal IntPtr getPointer() => this.handle;
internal uint getCKID() => m_CKID;
// private uint m_CKID;
#region IEquatable
// protected AbstractCKObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer) {
// m_CKID = ckid;
// }
public override bool Equals(object obj) => this.Equals(obj as AbstractCKObject);
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;
// protected uint GetCKID() => m_CKID;
public override int GetHashCode() => HashCode.Combine(this.handle, 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) {
// 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
#endregion
#region Misc
public override int GetHashCode() => HashCode.Combine(m_RawPointer, m_CKID);
public override string ToString() => $"{m_RawPointer}, {m_CKID}";
public override string ToString() => $"{this.handle}, {m_CKID}";
#endregion
#region Subclass Utilities
protected delegate bool FctGenericValueGetter<T>(IntPtr bmf, uint id, out T val);
protected delegate bool FctGenericValueSetter<T>(IntPtr bmf, uint id, T val);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected T getGenericValue<T>(FctGenericValueGetter<T> fct) {
BMapException.ThrowIfFailed(fct(getPointer(), getCKID(), out T out_val));
return out_val;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void setGenericValue<T>(FctGenericValueSetter<T> fct, T val) {
BMapException.ThrowIfFailed(fct(getPointer(), getCKID(), val));
}
#endregion
}
public class BMObject : AbstractCKObject {
internal BMObject(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {}
internal BMObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public string GetName() {
BMapException.ThrowIfFailed(BMap.BMObject_GetName(
this.getPointer(), this.getCKID(), out string out_name
));
return out_name;
}
public void SetName(string name) {
BMapException.ThrowIfFailed(BMap.BMObject_SetName(
this.getPointer(), this.getCKID(), name
));
}
public string GetName() => getGenericValue<string>(BMap.BMObject_GetName);
public void SetName(string name) => setGenericValue<string>(BMap.BMObject_SetName, name);
}
public class BMTexture : BMObject {
internal BMTexture(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {}
internal BMTexture(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public string GetFileName() => getGenericValue<string>(BMap.BMTexture_GetFileName);
public void LoadImage(string filepath) {
BMapException.ThrowIfFailed(BMap.BMTexture_LoadImage(getPointer(), getCKID(), filepath));
}
public void SaveImage(string filepath) {
BMapException.ThrowIfFailed(BMap.BMTexture_SaveImage(getPointer(), getCKID(), filepath));
}
public CK_TEXTURE_SAVEOPTIONS GetSaveOptions() => getGenericValue<CK_TEXTURE_SAVEOPTIONS>(BMap.BMTexture_GetSaveOptions);
public void SetSaveOptions(CK_TEXTURE_SAVEOPTIONS opt) => setGenericValue<CK_TEXTURE_SAVEOPTIONS>(BMap.BMTexture_SetSaveOptions, opt);
public VX_PIXELFORMAT GetVideoFormat() => getGenericValue<VX_PIXELFORMAT>(BMap.BMTexture_GetVideoFormat);
public void SetVideoFormat(VX_PIXELFORMAT vfmt) => setGenericValue<VX_PIXELFORMAT>(BMap.BMTexture_SetVideoFormat, vfmt);
}
public class BMMaterial : BMObject {
internal BMMaterial(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {}
internal BMMaterial(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public VxColor GetDiffuse() => getGenericValue<VxColor>(BMap.BMMaterial_GetDiffuse);
public void SetDiffuse(VxColor col) => setGenericValue<VxColor>(BMap.BMMaterial_SetDiffuse, col);
public VxColor GetAmbient() => getGenericValue<VxColor>(BMap.BMMaterial_GetAmbient);
public void SetAmbient(VxColor col) => setGenericValue<VxColor>(BMap.BMMaterial_SetAmbient, col);
public VxColor GetSpecular() => getGenericValue<VxColor>(BMap.BMMaterial_GetSpecular);
public void SetSpecular(VxColor col) => setGenericValue<VxColor>(BMap.BMMaterial_SetSpecular, col);
public VxColor GetEmissive() => getGenericValue<VxColor>(BMap.BMMaterial_GetEmissive);
public void SetEmissive(VxColor col) => setGenericValue<VxColor>(BMap.BMMaterial_SetEmissive, col);
public float GetSpecularPower() => getGenericValue<float>(BMap.BMMaterial_GetSpecularPower);
public void SetSpecularPower(float val) => setGenericValue<float>(BMap.BMMaterial_SetSpecularPower, val);
public VxColor GetTextureBorderColor() {
BMapException.ThrowIfFailed(BMap.BMMaterial_GetTextureBorderColor(getPointer(), getCKID(), out uint out_val));
return new VxColor(out_val);
}
public void SetTextureBorderColor(VxColor col) {
BMapException.ThrowIfFailed(BMap.BMMaterial_SetTextureBorderColor(getPointer(), getCKID(), col.ToDword()));
}
public VXTEXTURE_BLENDMODE GetTextureBlendMode() => getGenericValue<VXTEXTURE_BLENDMODE>(BMap.BMMaterial_GetTextureBlendMode);
public void SetTextureBlendMode(VXTEXTURE_BLENDMODE val) => setGenericValue<VXTEXTURE_BLENDMODE>(BMap.BMMaterial_SetTextureBlendMode, val);
public VXTEXTURE_FILTERMODE GetTextureMinMode() => getGenericValue<VXTEXTURE_FILTERMODE>(BMap.BMMaterial_GetTextureMinMode);
public void SetTextureMinMode(VXTEXTURE_FILTERMODE val) => setGenericValue<VXTEXTURE_FILTERMODE>(BMap.BMMaterial_SetTextureMinMode, val);
public VXTEXTURE_FILTERMODE GetTextureMagMode() => getGenericValue<VXTEXTURE_FILTERMODE>(BMap.BMMaterial_GetTextureMagMode);
public void SetTextureMagMode(VXTEXTURE_FILTERMODE val) => setGenericValue<VXTEXTURE_FILTERMODE>(BMap.BMMaterial_SetTextureMagMode, val);
public VXTEXTURE_ADDRESSMODE GetTextureAddressMode() => getGenericValue<VXTEXTURE_ADDRESSMODE>(BMap.BMMaterial_GetTextureAddressMode);
public void SetTextureAddressMode(VXTEXTURE_ADDRESSMODE val) => setGenericValue<VXTEXTURE_ADDRESSMODE>(BMap.BMMaterial_SetTextureAddressMode, val);
public VXBLEND_MODE GetSourceBlend() => getGenericValue<VXBLEND_MODE>(BMap.BMMaterial_GetSourceBlend);
public void SetSourceBlend(VXBLEND_MODE val) => setGenericValue<VXBLEND_MODE>(BMap.BMMaterial_SetSourceBlend, val);
public VXBLEND_MODE GetDestBlend() => getGenericValue<VXBLEND_MODE>(BMap.BMMaterial_GetDestBlend);
public void SetDestBlend(VXBLEND_MODE val) => setGenericValue<VXBLEND_MODE>(BMap.BMMaterial_SetDestBlend, val);
public VXFILL_MODE GetFillMode() => getGenericValue<VXFILL_MODE>(BMap.BMMaterial_GetFillMode);
public void SetFillMode(VXFILL_MODE val) => setGenericValue<VXFILL_MODE>(BMap.BMMaterial_SetFillMode, val);
public VXSHADE_MODE GetShadeMode() => getGenericValue<VXSHADE_MODE>(BMap.BMMaterial_GetShadeMode);
public void SetShadeMode(VXSHADE_MODE val) => setGenericValue<VXSHADE_MODE>(BMap.BMMaterial_SetShadeMode, val);
public bool GetAlphaTestEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetAlphaTestEnabled);
public void SetAlphaTestEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetAlphaTestEnabled, val);
public bool GetAlphaBlendEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetAlphaBlendEnabled);
public void SetAlphaBlendEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetAlphaBlendEnabled, val);
public bool GetPerspectiveCorrectionEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetPerspectiveCorrectionEnabled);
public void SetPerspectiveCorrectionEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetPerspectiveCorrectionEnabled, val);
public bool GetZWriteEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetZWriteEnabled);
public void SetZWriteEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetZWriteEnabled, val);
public bool GetTwoSidedEnabled() => getGenericValue<bool>(BMap.BMMaterial_GetTwoSidedEnabled);
public void SetTwoSidedEnabled(bool val) => setGenericValue<bool>(BMap.BMMaterial_SetTwoSidedEnabled, val);
public byte GetAlphaRef() => getGenericValue<byte>(BMap.BMMaterial_GetAlphaRef);
public void SetAlphaRef(byte val) => setGenericValue<byte>(BMap.BMMaterial_SetAlphaRef, val);
public VXCMPFUNC GetAlphaFunc() => getGenericValue<VXCMPFUNC>(BMap.BMMaterial_GetAlphaFunc);
public void SetAlphaFunc(VXCMPFUNC val) => setGenericValue<VXCMPFUNC>(BMap.BMMaterial_SetAlphaFunc, val);
public VXCMPFUNC GetZFunc() => getGenericValue<VXCMPFUNC>(BMap.BMMaterial_GetZFunc);
public void SetZFunc(VXCMPFUNC val) => setGenericValue<VXCMPFUNC>(BMap.BMMaterial_SetZFunc, val);
}
public class BMMesh : BMObject {
internal BMMesh(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {}
internal BMMesh(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public VXMESH_LITMODE GetLitMode() => getGenericValue<VXMESH_LITMODE>(BMap.BMMesh_GetLitMode);
public void SetLitMode(VXMESH_LITMODE mode) => setGenericValue<VXMESH_LITMODE>(BMap.BMMesh_SetLitMode, mode);
public uint GetVertexCount() => getGenericValue<uint>(BMap.BMMesh_GetVertexCount);
public void SetVertexCount(uint count) => setGenericValue<uint>(BMap.BMMesh_SetVertexCount, count);
public IEnumerable<VxVector3> GetVertexPositions() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexPositions(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.VxVector3Iterator(out_mem, GetVertexCount());
}
public void SetVertexPositions(IEnumerable<VxVector3> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexPositions(getPointer(), getCKID(), out IntPtr out_mem));
Utils.VxVector3Assigner(out_mem, GetVertexCount(), iem);
}
public IEnumerable<VxVector3> GetVertexNormals() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexNormals(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.VxVector3Iterator(out_mem, GetVertexCount());
}
public void SetVertexNormals(IEnumerable<VxVector3> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexNormals(getPointer(), getCKID(), out IntPtr out_mem));
Utils.VxVector3Assigner(out_mem, GetVertexCount(), iem);
}
public IEnumerable<VxVector2> GetVertexUVs() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexUVs(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.VxVector2Iterator(out_mem, GetVertexCount());
}
public void SetVertexUVs(IEnumerable<VxVector2> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetVertexUVs(getPointer(), getCKID(), out IntPtr out_mem));
Utils.VxVector2Assigner(out_mem, GetVertexCount(), iem);
}
public uint GetFaceCount() => getGenericValue<uint>(BMap.BMMesh_GetFaceCount);
public void SetFaceCount(uint count) => setGenericValue<uint>(BMap.BMMesh_SetFaceCount, count);
public IEnumerable<CKShortFaceIndices> GetFaceIndices() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceIndices(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.CKShortFaceIndicesIterator(out_mem, GetFaceCount());
}
public void SetFaceIndices(IEnumerable<CKShortFaceIndices> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceIndices(getPointer(), getCKID(), out IntPtr out_mem));
Utils.CKShortFaceIndicesAssigner(out_mem, GetFaceCount(), iem);
}
public IEnumerable<short> GetFaceMaterialSlotIndexs() {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceMaterialSlotIndexs(getPointer(), getCKID(), out IntPtr out_mem));
return Utils.ShortIterator(out_mem, GetFaceCount());
}
public void SetFaceMaterialSlotIndexs(IEnumerable<short> iem) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetFaceMaterialSlotIndexs(getPointer(), getCKID(), out IntPtr out_mem));
Utils.ShortAssigner(out_mem, GetFaceCount(), iem);
}
public uint GetMaterialSlotCount() => getGenericValue<uint>(BMap.BMMesh_GetMaterialSlotCount);
public void SetMaterialSlotCount(uint count) => setGenericValue<uint>(BMap.BMMesh_SetMaterialSlotCount, count);
public IEnumerable<BMMaterial> GetMaterialSlots() {
uint count = GetMaterialSlotCount();
for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMMesh_GetMaterialSlot(getPointer(), getCKID(), i, out uint out_mtlid));
if (out_mtlid == Utils.INVALID_CKID) yield return null;
else yield return new BMMaterial(getPointer(), out_mtlid);
}
}
public void SetMaterialSlots(IEnumerable<BMMaterial> iem) {
uint count = GetMaterialSlotCount();
var itor = iem.GetEnumerator();
for (uint i = 0; i < count; ++i) {
if (!itor.MoveNext()) throw new BMapException("The length of given material array is too short when assigning material slots.");
uint mtlid = itor.Current is null ? Utils.INVALID_CKID : itor.Current.getCKID();
BMapException.ThrowIfFailed(BMap.BMMesh_SetMaterialSlot(getPointer(), getCKID(), i, mtlid));
}
}
}
public class BM3dObject : BMObject {
internal BM3dObject(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {}
internal BM3dObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public VxMatrix GetWorldMatrix() => getGenericValue<VxMatrix>(BMap.BM3dObject_GetWorldMatrix);
public void SetWorldMatrix(VxMatrix mat) => setGenericValue<VxMatrix>(BMap.BM3dObject_SetWorldMatrix, mat);
public BMMesh GetCurrentMesh() {
BMapException.ThrowIfFailed(BMap.BM3dObject_GetCurrentMesh(getPointer(), getCKID(), out uint out_meshid));
if (out_meshid == Utils.INVALID_CKID) return null;
else return new BMMesh(getPointer(), out_meshid);
}
public void SetCurrentMesh(BMMesh mesh) {
uint meshid = (mesh is null) ? Utils.INVALID_CKID : mesh.getCKID();
BMapException.ThrowIfFailed(BMap.BM3dObject_SetCurrentMesh(getPointer(), getCKID(), meshid));
}
public bool GetVisibility() => getGenericValue<bool>(BMap.BM3dObject_GetVisibility);
public void SetVisibility(bool visb) => setGenericValue<bool>(BMap.BM3dObject_SetVisibility, visb);
}
public class BMGroup : BMObject {
internal BMGroup(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {}
internal BMGroup(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
public void AddObject(BM3dObject member) {
BMapException.ThrowIfFailed(BMap.BMGroup_AddObject(getPointer(), getCKID(), member.getCKID()));
}
public uint GetObjectCount() => getGenericValue<uint>(BMap.BMGroup_GetObjectCount);
public IEnumerable<BM3dObject> GetObjects() {
var size = GetObjectCount();
for (uint i = 0; i < size; ++i) {
BMapException.ThrowIfFailed(BMap.BMGroup_GetObject(getPointer(), getCKID(), i, out uint out_objid));
yield return new BM3dObject(getPointer(), out_objid);
}
}
}
public sealed class BMFileReader : AbstractPointer {
private static IntPtr AllocateHandle(string file_name, string temp_folder, string texture_folder, string[] encodings) {
private static IntPtr allocateHandle(string file_name, string temp_folder, string texture_folder, string[] encodings) {
BMapException.ThrowIfFailed(BMap.BMFile_Load(
file_name, temp_folder, texture_folder,
Utils.BMapSharpCallback,
file_name, temp_folder, texture_folder,
Utils.BMapSharpCallback,
(uint)encodings.Length, encodings,
out IntPtr out_file
));
return out_file;
}
protected override bool ReleaseHandle() {
return BMap.BMFile_Free(this.handle);
return BMap.BMFile_Free(this.getPointer());
}
public BMFileReader(string file_name, string temp_folder, string texture_folder, string[] encodings)
: base(AllocateHandle(file_name, temp_folder, texture_folder, encodings)) {}
: base(allocateHandle(file_name, temp_folder, texture_folder, encodings)) { }
public uint GetTextureCount() {
BMapException.ThrowIfFailed(BMap.BMFile_GetTextureCount(this.getPointer(), out uint out_count));
private delegate bool FctProtoGetCount(IntPtr bmf, out uint cnt);
private delegate bool FctProtoGetObject(IntPtr bmf, uint idx, out uint id);
private delegate T FctProtoCreateInstance<T>(IntPtr bmf, uint id);
private uint getCKObjectCount(FctProtoGetCount fct_cnt) {
BMapException.ThrowIfFailed(fct_cnt(this.getPointer(), out uint out_count));
return out_count;
}
public IEnumerable<BMTexture> GetTextures() {
uint count = GetTextureCount();
private IEnumerable<T> getCKObjects<T>(FctProtoGetCount fct_cnt, FctProtoGetObject fct_obj, FctProtoCreateInstance<T> fct_crt) {
uint count = getCKObjectCount(fct_cnt);
for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMFile_GetTexture(this.getPointer(), i, out uint out_id));
yield return new BMTexture(this.getPointer(), out_id);
BMapException.ThrowIfFailed(fct_obj(this.getPointer(), i, out uint out_id));
yield return fct_crt(this.getPointer(), out_id);
}
}
public uint GetMaterialCount() {
BMapException.ThrowIfFailed(BMap.BMFile_GetMaterialCount(this.getPointer(), out uint out_count));
return out_count;
public uint GetTextureCount() =>
getCKObjectCount(BMap.BMFile_GetTextureCount);
public IEnumerable<BMTexture> GetTextures() =>
getCKObjects<BMTexture>(BMap.BMFile_GetTextureCount, BMap.BMFile_GetTexture, (bmf, id) => new BMTexture(bmf, id));
public uint GetMaterialCount() =>
getCKObjectCount(BMap.BMFile_GetMaterialCount);
public IEnumerable<BMMaterial> GetMaterials() =>
getCKObjects<BMMaterial>(BMap.BMFile_GetMaterialCount, BMap.BMFile_GetMaterial, (bmf, id) => new BMMaterial(bmf, id));
public uint GetMeshCount() =>
getCKObjectCount(BMap.BMFile_GetMeshCount);
public IEnumerable<BMMesh> GetMeshes() =>
getCKObjects<BMMesh>(BMap.BMFile_GetMeshCount, BMap.BMFile_GetMesh, (bmf, id) => new BMMesh(bmf, id));
public uint Get3dObjectCount() =>
getCKObjectCount(BMap.BMFile_Get3dObjectCount);
public IEnumerable<BM3dObject> Get3dObjects() =>
getCKObjects<BM3dObject>(BMap.BMFile_Get3dObjectCount, BMap.BMFile_Get3dObject, (bmf, id) => new BM3dObject(bmf, id));
public uint GetGroupCount() =>
getCKObjectCount(BMap.BMFile_GetGroupCount);
public IEnumerable<BMGroup> GetGroups() =>
getCKObjects<BMGroup>(BMap.BMFile_GetGroupCount, BMap.BMFile_GetGroup, (bmf, id) => new BMGroup(bmf, id));
}
public sealed class BMFileWriter : AbstractPointer {
private static IntPtr allocateHandle(string temp_folder, string texture_folder, string[] encodings) {
BMapException.ThrowIfFailed(BMap.BMFile_Create(
temp_folder, texture_folder,
Utils.BMapSharpCallback,
(uint)encodings.Length, encodings,
out IntPtr out_file
));
return out_file;
}
public IEnumerable<BMMaterial> GetMaterials() {
uint count = GetMaterialCount();
for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMFile_GetMaterial(this.getPointer(), i, out uint out_id));
yield return new BMMaterial(this.getPointer(), out_id);
}
protected override bool ReleaseHandle() {
return BMap.BMFile_Free(this.getPointer());
}
public BMFileWriter(string temp_folder, string texture_folder, string[] 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
));
}
public uint GetMeshCount() {
BMapException.ThrowIfFailed(BMap.BMFile_GetMeshCount(this.getPointer(), out uint out_count));
return out_count;
}
public IEnumerable<BMMesh> GetMeshes() {
uint count = GetMeshCount();
for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMFile_GetMesh(this.getPointer(), i, out uint out_id));
yield return new BMMesh(this.getPointer(), out_id);
}
private delegate bool FctProtoCreateObject(IntPtr bmf, out uint id);
private delegate T FctProtoCreateInstance<T>(IntPtr bmf, uint id);
private T createCKObject<T>(FctProtoCreateObject fct_crt, FctProtoCreateInstance<T> fct_inst) {
BMapException.ThrowIfFailed(fct_crt(this.getPointer(), out uint out_id));
return fct_inst(this.getPointer(), out_id);
}
public uint Get3dObjectCount() {
BMapException.ThrowIfFailed(BMap.BMFile_Get3dObjectCount(this.getPointer(), out uint out_count));
return out_count;
public BMTexture CreateTexture() => createCKObject<BMTexture>(BMap.BMFile_CreateTexture, (bmf, id) => new BMTexture(bmf, id));
public BMMaterial CreateMaterial() => createCKObject<BMMaterial>(BMap.BMFile_CreateMaterial, (bmf, id) => new BMMaterial(bmf, id));
public BMMesh CreateMesh() => createCKObject<BMMesh>(BMap.BMFile_CreateMesh, (bmf, id) => new BMMesh(bmf, id));
public BM3dObject Create3dObject() => createCKObject<BM3dObject>(BMap.BMFile_Create3dObject, (bmf, id) => new BM3dObject(bmf, id));
public BMGroup CreateGroup() => createCKObject<BMGroup>(BMap.BMFile_CreateGroup, (bmf, id) => new BMGroup(bmf, id));
}
public sealed class BMMeshTrans : AbstractPointer {
private static IntPtr allocateHandle() {
BMapException.ThrowIfFailed(BMap.BMMeshTrans_New(out IntPtr out_trans));
return out_trans;
}
public IEnumerable<BM3dObject> Get3dObjects() {
uint count = Get3dObjectCount();
for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMFile_Get3dObject(this.getPointer(), i, out uint out_id));
yield return new BM3dObject(this.getPointer(), out_id);
}
protected override bool ReleaseHandle() {
return BMap.BMMeshTrans_Delete(this.getPointer());
}
public BMMeshTrans() : base(allocateHandle()) { }
public void Parse(BMMesh objmesh) {
BMapException.ThrowIfFailed(BMap.BMMeshTrans_Parse(
getPointer(),
objmesh.getPointer(),
objmesh.getCKID()
));
}
public uint GetGroupCount() {
BMapException.ThrowIfFailed(BMap.BMFile_GetGroupCount(this.getPointer(), out uint out_count));
return out_count;
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 IEnumerable<BMGroup> GetGroups() {
uint count = GetGroupCount();
for (uint i = 0; i < count; ++i) {
BMapException.ThrowIfFailed(BMap.BMFile_GetGroup(this.getPointer(), i, out uint out_id));
yield return new BMGroup(this.getPointer(), out_id);
}
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 VxVector2(float _x = 0.0f, float _y = 0.0f) {
X = _x;
Y = _y;
X = _x; Y = _y;
}
public VxVector2(Vector2 vec) {
FromManaged(vec);
}
public void FromManaged(Vector2 vec) {
X = vec.X;
Y = vec.Y;
X = vec.X; Y = vec.Y;
}
public Vector2 ToManaged() {
return new Vector2(X, Y);
@ -33,14 +35,14 @@ namespace BMapSharp.VirtoolsTypes {
public float X, Y, Z;
public VxVector3(float _x = 0.0f, float _y = 0.0f, float _z = 0.0f) {
X = _x;
Y = _y;
Z = _z;
X = _x; Y = _y; Z = _z;
}
public VxVector3(Vector3 vec) {
FromManaged(vec);
}
public void FromManaged(Vector3 vec) {
X = vec.X;
Y = vec.Y;
Z = vec.Z;
X = vec.X; Y = vec.Y; Z = vec.Z;
}
public Vector3 ToManaged() {
return new Vector3(X, Y, Z);
@ -50,29 +52,31 @@ namespace BMapSharp.VirtoolsTypes {
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct VxColor {
[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) {
A = _a;
R = _r;
G = _g;
B = _b;
A = _a; R = _r; G = _g; B = _b;
Regulate();
}
public VxColor(Vector4 col) {
FromManagedRGBA(col);
}
public VxColor(Vector3 col) {
FromManagedRGB(col);
}
public VxColor(uint val) {
FromDword(val);
}
public void FromManagedRGBA(Vector4 col) {
R = col.X;
G = col.Y;
B = col.Z;
A = col.W;
R = col.X; G = col.Y; B = col.Z; A = col.W;
Regulate();
}
public Vector4 ToManagedRGBA() {
return new Vector4(R, G, B, A);
}
public void FromManagedRGB(Vector3 col) {
R = col.X;
G = col.Y;
B = col.Z;
R = col.X; G = col.Y; B = col.Z; A = 1.0f;
Regulate();
}
public Vector3 ToManagedRGB() {
@ -101,6 +105,7 @@ namespace BMapSharp.VirtoolsTypes {
val |= (uint)(B * 255.0f);
return val;
}
public static float ClampFactor(float factor) {
return System.Math.Clamp(factor, 0.0f, 1.0f);
}
@ -166,6 +171,18 @@ namespace BMapSharp.VirtoolsTypes {
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct CKShortFaceIndices {
[MarshalAs(UnmanagedType.U2)]
public ushort I1, I2, I3;
public CKShortFaceIndices(ushort i1 = 0, ushort i2 = 0, ushort i3 = 0) {
I1 = i1;
I2 = i2;
I3 = i3;
}
}
public enum CK_TEXTURE_SAVEOPTIONS : uint {
CKTEXTURE_RAWDATA = 0, /**< Save raw data inside file. The bitmap is saved in a raw 32 bit per pixel format. */
CKTEXTURE_EXTERNAL = 1, /**< Store only the file name for the texture. The bitmap file must be present in the bitmap paths when loading the composition. */

View File

@ -1,8 +1,12 @@
using BMapSharp.BMapWrapper;
using System;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
namespace BMapSharpTestbench {
internal class Program {
static void Main(string[] args) {
// Check environment
Console.OutputEncoding = Encoding.UTF8;
@ -23,36 +27,120 @@ namespace BMapSharpTestbench {
string[] encodings = ["cp1252", "gb2312"];
using (var reader = new BMapSharp.BMapWrapper.BMFileReader(file_name, temp_folder, texture_folder, encodings)) {
Console.WriteLine("===== Groups =====");
foreach (var gp in reader.GetGroups()) {
Console.WriteLine(gp.GetName());
}
Console.WriteLine("===== 3dObjects =====");
foreach (var obj in reader.Get3dObjects()) {
Console.WriteLine(obj.GetName());
}
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());
}
TestCommon(reader);
TestIEquatable(reader);
}
Console.WriteLine("===== Done =====");
Console.WriteLine("Press any key to quit...");
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
#region Basic Class & Constant Defines
@ -13,12 +13,85 @@ def _python_callback(strl: bytes):
Simply add a prefix when output.
Need a convertion before passing to BMFile.
"""
# the passing value is bytes, not bmap.bm_CKSTRING.
# i think Python do a auto convertion here.
# YYC Remarks:
# 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:
print(f'[PyBMap] {strl.decode(g_BMapEncoding)}')
_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():
__mRawPointer: int
@ -46,6 +119,11 @@ class _AbstractPointer():
def __hash__(self) -> int:
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):
__mCKID: int
@ -70,78 +148,76 @@ class _AbstractCKObject(_AbstractPointer):
def __hash__(self) -> int:
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:
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p)
idx: int = 0
for _ in range(count):
uservector: virtools_types.VxVector3 = next(itor)
pfloat[idx] = uservector.x
pfloat[idx + 1] = uservector.y
pfloat[idx + 2] = uservector.z
idx += 3
def _get_str_value(self, getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_CKSTRING_p], bmap.bm_bool]) -> str | None:
data: bmap.bm_CKSTRING = bmap.bm_CKSTRING()
getter_(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
if data.value is None: return None
else: return data.value.decode(g_BMapEncoding)
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:
data: bmap.bm_CKSTRING
if data_ is None: data = bmap.bm_CKSTRING(0)
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]:
ret: virtools_types.VxVector3 = virtools_types.VxVector3()
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]
ret.z = pfloat[idx + 2]
idx += 3
yield ret
def _vxvector2_assigner(pvector: bmap.bm_VxVector2_p, count: int, itor: typing.Iterator[virtools_types.VxVector2]) -> None:
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p)
idx: int = 0
for _ in range(count):
uservector: virtools_types.VxVector2 = next(itor)
pfloat[idx] = uservector.x
pfloat[idx + 1] = uservector.y
idx += 2
def _set_vxcolor_value(self,
setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_VxColor], bmap.bm_bool],
col_: virtools_types.VxColor) -> None:
# set to raw color
col: bmap.bm_VxColor = bmap.bm_VxColor()
(col.r, col.g, col.b, col.a) = (col_.r, col_.g, col_.b, col_.a)
# assign
setter_(self._get_pointer(), self._get_ckid(), col)
def _get_vxcolor_value(self,
getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_VxColor_p], bmap.bm_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, ret.g, ret.b, ret.a) = (col.r, col.g, col.b, col.a)
return ret
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]:
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
TCKObject = typing.TypeVar('TCKObject', bound = _AbstractCKObject)
#endregion
#region Valid Check, Init and Dispose
#region Validation Check, Init and Dispose
def is_bmap_available() -> bool:
return bmap.is_bmap_available()
@ -159,7 +235,7 @@ if is_bmap_available():
#region Real Type Defines
"""!
@remark
@remarks
BMFileReader, BMFileWriter, and BMMeshTrans can be create by given constructor.
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.
@ -173,337 +249,204 @@ We just provide them as a visitor.
class BMObject(_AbstractCKObject):
def get_name(self) -> str | None:
name: bmap.bm_CKSTRING = bmap.bm_CKSTRING()
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)
return self._get_str_value(bmap.BMObject_GetName)
def set_name(self, name_: str | None) -> None:
name: bmap.bm_CKSTRING
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)
self._set_str_value(bmap.BMObject_SetName, name_)
class BMTexture(BMObject):
def get_file_name(self) -> str | None:
filename: bmap.bm_CKSTRING = bmap.bm_CKSTRING()
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)
return self._get_str_value(bmap.BMTexture_GetFileName)
def load_image(self, filepath: str) -> None:
filename: bmap.bm_CKSTRING = bmap.bm_CKSTRING(filepath.encode(g_BMapEncoding))
bmap.BMTexture_LoadImage(self._get_pointer(), self._get_ckid(), filename)
def save_image(self, filepath: str) -> None:
filename: bmap.bm_CKSTRING = bmap.bm_CKSTRING(filepath.encode(g_BMapEncoding))
bmap.BMTexture_SaveImage(self._get_pointer(), self._get_ckid(), filename)
def get_save_options(self) -> virtools_types.CK_TEXTURE_SAVEOPTIONS:
opt: bmap.bm_enum = bmap.bm_enum()
bmap.BMTexture_GetSaveOptions(self._get_pointer(), self._get_ckid(), ctypes.byref(opt))
return virtools_types.CK_TEXTURE_SAVEOPTIONS(opt.value)
return self._get_enum_value(virtools_types.CK_TEXTURE_SAVEOPTIONS, bmap.BMTexture_GetSaveOptions)
def set_save_options(self, opt_: virtools_types.CK_TEXTURE_SAVEOPTIONS) -> None:
opt: bmap.bm_enum = bmap.bm_enum(opt_.value)
bmap.BMTexture_SetSaveOptions(self._get_pointer(), self._get_ckid(), opt)
self._set_enum_value(bmap.BMTexture_SetSaveOptions, opt_)
def get_video_format(self) -> virtools_types.VX_PIXELFORMAT:
fmt: bmap.bm_enum = bmap.bm_enum()
bmap.BMTexture_GetVideoFormat(self._get_pointer(), self._get_ckid(), ctypes.byref(fmt))
return virtools_types.VX_PIXELFORMAT(fmt.value)
return self._get_enum_value(virtools_types.VX_PIXELFORMAT, bmap.BMTexture_GetVideoFormat)
def set_video_format(self, fmt_: virtools_types.VX_PIXELFORMAT) -> None:
fmt: bmap.bm_enum = bmap.bm_enum(fmt_.value)
bmap.BMTexture_SetVideoFormat(self._get_pointer(), self._get_ckid(), fmt)
self._set_enum_value(bmap.BMTexture_SetVideoFormat, fmt_)
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:
return self._get_vxcolor(bmap.BMMaterial_GetDiffuse)
return self._get_vxcolor_value(bmap.BMMaterial_GetDiffuse)
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:
return self._get_vxcolor(bmap.BMMaterial_GetAmbient)
return self._get_vxcolor_value(bmap.BMMaterial_GetAmbient)
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:
return self._get_vxcolor(bmap.BMMaterial_GetSpecular)
return self._get_vxcolor_value(bmap.BMMaterial_GetSpecular)
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:
return self._get_vxcolor(bmap.BMMaterial_GetEmissive)
return self._get_vxcolor_value(bmap.BMMaterial_GetEmissive)
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:
power: bmap.bm_CKFLOAT = bmap.bm_CKFLOAT()
bmap.BMMaterial_GetSpecularPower(self._get_pointer(), self._get_ckid(), ctypes.byref(power))
return power.value
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMMaterial_GetSpecularPower)
def set_specular_power(self, power_: float) -> None:
power: bmap.bm_CKFLOAT = bmap.bm_CKFLOAT(power_)
bmap.BMMaterial_SetSpecularPower(self._get_pointer(), self._get_ckid(), power)
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMMaterial_SetSpecularPower, power_)
def get_texture(self) -> BMTexture | None:
objid: bmap.bm_CKID = bmap.bm_CKID()
bmap.BMMaterial_GetTexture(self._get_pointer(), self._get_ckid(), ctypes.byref(objid))
if objid.value == g_InvalidCKID:
return None
else:
return BMTexture(self._get_pointer(), objid)
if objid.value == g_InvalidCKID: return None
else: return BMTexture(self._get_pointer(), objid)
def set_texture(self, tex_: BMTexture | None) -> None:
objid: bmap.bm_CKID = bmap.bm_CKID(g_InvalidCKID)
if tex_ is not None:
objid = tex_._get_ckid()
if tex_ is not None: objid = tex_._get_ckid()
bmap.BMMaterial_SetTexture(self._get_pointer(), self._get_ckid(), objid)
def get_texture_border_color(self) -> virtools_types.VxColor:
col: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
bmap.BMMaterial_GetTextureBorderColor(self._get_pointer(), self._get_ckid(), ctypes.byref(col))
dword_color: int = self._get_integral_value(bmap.bm_CKDWORD, bmap.BMMaterial_GetTextureBorderColor)
ret: virtools_types.VxColor = virtools_types.VxColor()
ret.from_dword(col.value)
ret.from_dword(dword_color)
return ret
def set_texture_border_color(self, col_: virtools_types.VxColor) -> None:
col: bmap.bm_CKDWORD = bmap.bm_CKDWORD(col_.to_dword())
bmap.BMMaterial_SetTextureBorderColor(self._get_pointer(), self._get_ckid(), col)
self._set_integral_value(bmap.bm_CKDWORD, bmap.BMMaterial_SetTextureBorderColor, col_.to_dword())
def get_texture_blend_mode(self) -> virtools_types.VXTEXTURE_BLENDMODE:
data: bmap.bm_enum = bmap.bm_enum()
bmap.BMMaterial_GetTextureBlendMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXTEXTURE_BLENDMODE(data.value)
return self._get_enum_value(virtools_types.VXTEXTURE_BLENDMODE, bmap.BMMaterial_GetTextureBlendMode)
def set_texture_blend_mode(self, data_: virtools_types.VXTEXTURE_BLENDMODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value)
bmap.BMMaterial_SetTextureBlendMode(self._get_pointer(), self._get_ckid(), data)
self._set_enum_value(bmap.BMMaterial_SetTextureBlendMode, data_)
def get_texture_min_mode(self) -> virtools_types.VXTEXTURE_FILTERMODE:
data: bmap.bm_enum = bmap.bm_enum()
bmap.BMMaterial_GetTextureMinMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXTEXTURE_FILTERMODE(data.value)
return self._get_enum_value(virtools_types.VXTEXTURE_FILTERMODE, bmap.BMMaterial_GetTextureMinMode)
def set_texture_min_mode(self, data_: virtools_types.VXTEXTURE_FILTERMODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value)
bmap.BMMaterial_SetTextureMinMode(self._get_pointer(), self._get_ckid(), data)
self._set_enum_value(bmap.BMMaterial_SetTextureMinMode, data_)
def get_texture_mag_mode(self) -> virtools_types.VXTEXTURE_FILTERMODE:
data: bmap.bm_enum = bmap.bm_enum()
bmap.BMMaterial_GetTextureMagMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXTEXTURE_FILTERMODE(data.value)
return self._get_enum_value(virtools_types.VXTEXTURE_FILTERMODE, bmap.BMMaterial_GetTextureMagMode)
def set_texture_mag_mode(self, data_: virtools_types.VXTEXTURE_FILTERMODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value)
bmap.BMMaterial_SetTextureMagMode(self._get_pointer(), self._get_ckid(), data)
self._set_enum_value(bmap.BMMaterial_SetTextureMagMode, data_)
def get_texture_address_mode(self) -> virtools_types.VXTEXTURE_ADDRESSMODE:
data: bmap.bm_enum = bmap.bm_enum()
bmap.BMMaterial_GetTextureAddressMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXTEXTURE_ADDRESSMODE(data.value)
return self._get_enum_value(virtools_types.VXTEXTURE_ADDRESSMODE, bmap.BMMaterial_GetTextureAddressMode)
def set_texture_address_mode(self, data_: virtools_types.VXTEXTURE_ADDRESSMODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value)
bmap.BMMaterial_SetTextureAddressMode(self._get_pointer(), self._get_ckid(), data)
self._set_enum_value(bmap.BMMaterial_SetTextureAddressMode, data_)
def get_source_blend(self) -> virtools_types.VXBLEND_MODE:
data: bmap.bm_enum = bmap.bm_enum()
bmap.BMMaterial_GetSourceBlend(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXBLEND_MODE(data.value)
return self._get_enum_value(virtools_types.VXBLEND_MODE, bmap.BMMaterial_GetSourceBlend)
def set_source_blend(self, data_: virtools_types.VXBLEND_MODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value)
bmap.BMMaterial_SetSourceBlend(self._get_pointer(), self._get_ckid(), data)
self._set_enum_value(bmap.BMMaterial_SetSourceBlend, data_)
def get_dest_blend(self) -> virtools_types.VXBLEND_MODE:
data: bmap.bm_enum = bmap.bm_enum()
bmap.BMMaterial_GetDestBlend(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXBLEND_MODE(data.value)
return self._get_enum_value(virtools_types.VXBLEND_MODE, bmap.BMMaterial_GetDestBlend)
def set_dest_blend(self, data_: virtools_types.VXBLEND_MODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value)
bmap.BMMaterial_SetDestBlend(self._get_pointer(), self._get_ckid(), data)
self._set_enum_value(bmap.BMMaterial_SetDestBlend, data_)
def get_fill_mode(self) -> virtools_types.VXFILL_MODE:
data: bmap.bm_enum = bmap.bm_enum()
bmap.BMMaterial_GetFillMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXFILL_MODE(data.value)
return self._get_enum_value(virtools_types.VXFILL_MODE, bmap.BMMaterial_GetFillMode)
def set_fill_mode(self, data_: virtools_types.VXFILL_MODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value)
bmap.BMMaterial_SetFillMode(self._get_pointer(), self._get_ckid(), data)
self._set_enum_value(bmap.BMMaterial_SetFillMode, data_)
def get_shade_mode(self) -> virtools_types.VXSHADE_MODE:
data: bmap.bm_enum = bmap.bm_enum()
bmap.BMMaterial_GetShadeMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXSHADE_MODE(data.value)
return self._get_enum_value(virtools_types.VXSHADE_MODE, bmap.BMMaterial_GetShadeMode)
def set_shade_mode(self, data_: virtools_types.VXSHADE_MODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value)
bmap.BMMaterial_SetShadeMode(self._get_pointer(), self._get_ckid(), data)
self._set_enum_value(bmap.BMMaterial_SetShadeMode, data_)
def get_alpha_test_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool()
bmap.BMMaterial_GetAlphaTestEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
return self._get_bool_value(bmap.BMMaterial_GetAlphaTestEnabled)
def set_alpha_test_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_)
bmap.BMMaterial_SetAlphaTestEnabled(self._get_pointer(), self._get_ckid(), data)
self._set_bool_value(bmap.BMMaterial_SetAlphaTestEnabled, data_)
def get_alpha_blend_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool()
bmap.BMMaterial_GetAlphaBlendEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
return self._get_bool_value(bmap.BMMaterial_GetAlphaBlendEnabled)
def set_alpha_blend_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_)
bmap.BMMaterial_SetAlphaBlendEnabled(self._get_pointer(), self._get_ckid(), data)
self._set_bool_value(bmap.BMMaterial_SetAlphaBlendEnabled, data_)
def get_perspective_correction_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool()
bmap.BMMaterial_GetPerspectiveCorrectionEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
return self._get_bool_value(bmap.BMMaterial_GetPerspectiveCorrectionEnabled)
def set_perspective_correction_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_)
bmap.BMMaterial_SetPerspectiveCorrectionEnabled(self._get_pointer(), self._get_ckid(), data)
self._set_bool_value(bmap.BMMaterial_SetPerspectiveCorrectionEnabled, data_)
def get_z_write_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool()
bmap.BMMaterial_GetZWriteEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
return self._get_bool_value(bmap.BMMaterial_GetZWriteEnabled)
def set_z_write_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_)
bmap.BMMaterial_SetZWriteEnabled(self._get_pointer(), self._get_ckid(), data)
self._set_bool_value(bmap.BMMaterial_SetZWriteEnabled, data_)
def get_two_sided_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool()
bmap.BMMaterial_GetTwoSidedEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
return self._get_bool_value(bmap.BMMaterial_GetTwoSidedEnabled)
def set_two_sided_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_)
bmap.BMMaterial_SetTwoSidedEnabled(self._get_pointer(), self._get_ckid(), data)
self._set_bool_value(bmap.BMMaterial_SetTwoSidedEnabled, data_)
def get_alpha_ref(self) -> int:
data: bmap.bm_CKBYTE = bmap.bm_CKBYTE()
bmap.BMMaterial_GetAlphaRef(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
return self._get_integral_value(bmap.bm_CKBYTE, bmap.BMMaterial_GetAlphaRef)
def set_alpha_ref(self, data_: int):
data: bmap.bm_CKBYTE = bmap.bm_CKBYTE(data_)
bmap.BMMaterial_SetAlphaRef(self._get_pointer(), self._get_ckid(), data)
self._set_integral_value(bmap.bm_CKBYTE, bmap.BMMaterial_SetAlphaRef, data_)
def get_alpha_func(self) -> virtools_types.VXCMPFUNC:
data: bmap.bm_enum = bmap.bm_enum()
bmap.BMMaterial_GetAlphaFunc(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXCMPFUNC(data.value)
return self._get_enum_value(virtools_types.VXCMPFUNC, bmap.BMMaterial_GetAlphaFunc)
def set_alpha_func(self, data_: virtools_types.VXCMPFUNC) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value)
bmap.BMMaterial_SetAlphaFunc(self._get_pointer(), self._get_ckid(), data)
self._set_enum_value(bmap.BMMaterial_SetAlphaFunc, data_)
def get_z_func(self) -> virtools_types.VXCMPFUNC:
data: bmap.bm_enum = bmap.bm_enum()
bmap.BMMaterial_GetZFunc(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXCMPFUNC(data.value)
return self._get_enum_value(virtools_types.VXCMPFUNC, bmap.BMMaterial_GetZFunc)
def set_z_func(self, data_: virtools_types.VXCMPFUNC) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value)
bmap.BMMaterial_SetZFunc(self._get_pointer(), self._get_ckid(), data)
self._set_enum_value(bmap.BMMaterial_SetZFunc, data_)
class BMMesh(BMObject):
def get_lit_mode(self) -> virtools_types.VXMESH_LITMODE:
mode: bmap.bm_enum = bmap.bm_enum()
bmap.BMMesh_GetLitMode(self._get_pointer(), self._get_ckid(), ctypes.byref(mode))
return virtools_types.VXMESH_LITMODE(mode.value)
return self._get_enum_value(virtools_types.VXMESH_LITMODE, bmap.BMMesh_GetLitMode)
def set_lit_mode(self, mode_: virtools_types.VXMESH_LITMODE) -> None:
mode: bmap.bm_enum = bmap.bm_enum(mode_.value)
bmap.BMMesh_SetLitMode(self._get_pointer(), self._get_ckid(), mode)
self._set_enum_value(bmap.BMMesh_SetLitMode, mode_)
def get_vertex_count(self) -> int:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
bmap.BMMesh_GetVertexCount(self._get_pointer(), self._get_ckid(), ctypes.byref(count))
return count.value
return self._get_integral_value(bmap.bm_CKDWORD, bmap.BMMesh_GetVertexCount)
def set_vertex_count(self, count_: int) -> None:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count_)
bmap.BMMesh_SetVertexCount(self._get_pointer(), self._get_ckid(), count)
self._set_integral_value(bmap.bm_CKDWORD, bmap.BMMesh_SetVertexCount, count_)
def get_vertex_positions(self) -> typing.Iterator[virtools_types.VxVector3]:
# get raw pointer and return
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMesh_GetVertexPositions(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector))
return _vxvector3_iterator(raw_vector, self.get_vertex_count())
raw_vector = self._get_pointer_value(bmap.bm_VxVector3_p, bmap.BMMesh_GetVertexPositions)
return _Utils.vxvector3_iterator(raw_vector, self.get_vertex_count())
def set_vertex_positions(self, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
# get raw float pointer and assign
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMesh_GetVertexPositions(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector))
_vxvector3_assigner(raw_vector, self.get_vertex_count(), itor)
raw_vector = self._get_pointer_value(bmap.bm_VxVector3_p, bmap.BMMesh_GetVertexPositions)
_Utils.vxvector3_assigner(raw_vector, self.get_vertex_count(), itor)
def get_vertex_normals(self) -> typing.Iterator[virtools_types.VxVector3]:
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMesh_GetVertexNormals(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector))
return _vxvector3_iterator(raw_vector, self.get_vertex_count())
raw_vector = self._get_pointer_value(bmap.bm_VxVector3_p, bmap.BMMesh_GetVertexNormals)
return _Utils.vxvector3_iterator(raw_vector, self.get_vertex_count())
def set_vertex_normals(self, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMesh_GetVertexNormals(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector))
_vxvector3_assigner(raw_vector, self.get_vertex_count(), itor)
raw_vector = self._get_pointer_value(bmap.bm_VxVector3_p, bmap.BMMesh_GetVertexNormals)
_Utils.vxvector3_assigner(raw_vector, self.get_vertex_count(), itor)
def get_vertex_uvs(self) -> typing.Iterator[virtools_types.VxVector2]:
raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p()
bmap.BMMesh_GetVertexUVs(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector))
return _vxvector2_iterator(raw_vector, self.get_vertex_count())
raw_vector = self._get_pointer_value(bmap.bm_VxVector2_p, bmap.BMMesh_GetVertexUVs)
return _Utils.vxvector2_iterator(raw_vector, self.get_vertex_count())
def set_vertex_uvs(self, itor: typing.Iterator[virtools_types.VxVector2]) -> None:
raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p()
bmap.BMMesh_GetVertexUVs(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector))
_vxvector2_assigner(raw_vector, self.get_vertex_count(), itor)
raw_vector = self._get_pointer_value(bmap.bm_VxVector2_p, bmap.BMMesh_GetVertexUVs)
_Utils.vxvector2_assigner(raw_vector, self.get_vertex_count(), itor)
def get_face_count(self) -> int:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
bmap.BMMesh_GetFaceCount(self._get_pointer(), self._get_ckid(), ctypes.byref(count))
return count.value
return self._get_integral_value(bmap.bm_CKDWORD, bmap.BMMesh_GetFaceCount)
def set_face_count(self, count_: int) -> None:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count_)
bmap.BMMesh_SetFaceCount(self._get_pointer(), self._get_ckid(), count)
self._set_integral_value(bmap.bm_CKDWORD, bmap.BMMesh_SetFaceCount, count_)
def get_face_indices(self) -> typing.Iterator[virtools_types.CKFaceIndices]:
raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p()
bmap.BMMesh_GetFaceIndices(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_idx))
return _ckfaceindices_iterator(raw_idx, self.get_face_count())
raw_idx = self._get_pointer_value(bmap.bm_CKWORD_p, bmap.BMMesh_GetFaceIndices)
return _Utils.ckfaceindices_iterator(raw_idx, self.get_face_count())
def set_face_indices(self, itor: typing.Iterator[virtools_types.CKFaceIndices]) -> None:
raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p()
bmap.BMMesh_GetFaceIndices(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_idx))
_ckfaceindices_assigner(raw_idx, self.get_face_count(), itor)
raw_idx = self._get_pointer_value(bmap.bm_CKWORD_p, bmap.BMMesh_GetFaceIndices)
_Utils.ckfaceindices_assigner(raw_idx, self.get_face_count(), itor)
def get_face_material_slot_indexs(self) -> typing.Iterator[int]:
raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p()
bmap.BMMesh_GetFaceMaterialSlotIndexs(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_idx))
raw_idx = self._get_pointer_value(bmap.bm_CKWORD_p, bmap.BMMesh_GetFaceMaterialSlotIndexs)
for i in range(self.get_face_count()):
yield raw_idx[i]
def set_face_material_slot_indexs(self, itor: typing.Iterator[int]) -> None:
raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p()
bmap.BMMesh_GetFaceMaterialSlotIndexs(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_idx))
for i in range(self.get_face_count()):
raw_idx[i] = next(itor)
raw_idx = self._get_pointer_value(bmap.bm_CKWORD_p, bmap.BMMesh_GetFaceMaterialSlotIndexs)
try:
for i in range(self.get_face_count()):
raw_idx[i] = next(itor)
except StopIteration:
_Utils.raise_out_of_length_exception()
def get_material_slot_count(self) -> int:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
bmap.BMMesh_GetMaterialSlotCount(self._get_pointer(), self._get_ckid(), ctypes.byref(count))
return count.value
return self._get_integral_value(bmap.bm_CKDWORD, bmap.BMMesh_GetMaterialSlotCount)
def set_material_slot_count(self, count_: int) -> None:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count_)
bmap.BMMesh_SetMaterialSlotCount(self._get_pointer(), self._get_ckid(), count)
self._set_integral_value(bmap.bm_CKDWORD, bmap.BMMesh_SetMaterialSlotCount, count_)
def get_material_slots(self) -> typing.Iterator[BMMaterial | None]:
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:
idx: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
mtlid: bmap.bm_CKID = bmap.bm_CKID()
for i in range(self.get_material_slot_count()):
idx.value = i
# analyze mtl item
mtlobj: BMMaterial | None = next(itor)
if mtlobj is None:
mtlid.value = g_InvalidCKID
else:
mtlid = mtlobj._get_ckid()
# set
bmap.BMMesh_SetMaterialSlot(self._get_pointer(), self._get_ckid(), idx, mtlid)
try:
for i in range(self.get_material_slot_count()):
idx.value = i
# analyze mtl item
mtlobj: BMMaterial | None = next(itor)
if mtlobj is None:
mtlid.value = g_InvalidCKID
else:
mtlid = mtlobj._get_ckid()
# set
bmap.BMMesh_SetMaterialSlot(self._get_pointer(), self._get_ckid(), idx, mtlid)
except StopIteration:
_Utils.raise_out_of_length_exception()
class BM3dObject(BMObject):
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)
def get_visibility(self) -> bool:
visb: bmap.bm_bool = bmap.bm_bool()
bmap.BM3dObject_GetVisibility(self._get_pointer(), self._get_ckid(), ctypes.byref(visb))
return visb.value
return self._get_bool_value(bmap.BM3dObject_GetVisibility)
def set_visibility(self, visb_: bool) -> None:
visb: bmap.bm_bool = bmap.bm_bool(visb_)
bmap.BM3dObject_SetVisibility(self._get_pointer(), self._get_ckid(), visb)
self._set_bool_value(bmap.BM3dObject_SetVisibility, visb_)
class BMGroup(BMObject):
def add_object(self, member: BM3dObject) -> None:
bmap.BMGroup_AddObject(self._get_pointer(), self._get_ckid(), member._get_ckid())
def get_object_count(self) -> int:
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
bmap.BMGroup_GetObjectCount(self._get_pointer(), self._get_ckid(), ctypes.byref(csize))
return csize.value
return self._get_integral_value(bmap.bm_CKDWORD, bmap.BMGroup_GetObjectCount)
def get_objects(self) -> typing.Iterator[BM3dObject]:
# get list size
csize: int = self.get_object_count()
# iterate list
cidx: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
retid: bmap.bm_CKID = bmap.bm_CKID()
@ -621,16 +561,16 @@ class BMFileReader(_AbstractPointer):
self._set_pointer(g_InvalidPtr)
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
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
count_getter(self._get_pointer(), ctypes.byref(csize))
return csize.value
def __get_ckobjects(self,
class_type: type[TCKObj],
count_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD_p], bool],
obj_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD, bmap.bm_CKID_p], bool]) -> typing.Iterator[TCKObj]:
class_type: type[TCKObject],
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], bmap.bm_bool]) -> typing.Iterator[TCKObject]:
# get size first
csize: int = self.__get_ckobject_count(count_getter)
@ -646,47 +586,23 @@ class BMFileReader(_AbstractPointer):
def get_texture_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetTextureCount)
def get_textures(self) -> typing.Iterator[BMTexture]:
return self.__get_ckobjects(
BMTexture,
bmap.BMFile_GetTextureCount,
bmap.BMFile_GetTexture
)
return self.__get_ckobjects(BMTexture, bmap.BMFile_GetTextureCount, bmap.BMFile_GetTexture)
def get_material_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetMaterialCount)
def get_materials(self) -> typing.Iterator[BMMaterial]:
return self.__get_ckobjects(
BMMaterial,
bmap.BMFile_GetMaterialCount,
bmap.BMFile_GetMaterial
)
return self.__get_ckobjects(BMMaterial, bmap.BMFile_GetMaterialCount, bmap.BMFile_GetMaterial)
def get_mesh_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetMeshCount)
def get_meshs(self) -> typing.Iterator[BMMesh]:
return self.__get_ckobjects(
BMMesh,
bmap.BMFile_GetMeshCount,
bmap.BMFile_GetMesh
)
return self.__get_ckobjects(BMMesh, bmap.BMFile_GetMeshCount, bmap.BMFile_GetMesh)
def get_3dobject_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_Get3dObjectCount)
def get_3dobjects(self) -> typing.Iterator[BM3dObject]:
return self.__get_ckobjects(
BM3dObject,
bmap.BMFile_Get3dObjectCount,
bmap.BMFile_Get3dObject
)
return self.__get_ckobjects(BM3dObject, bmap.BMFile_Get3dObjectCount, bmap.BMFile_Get3dObject)
def get_group_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetGroupCount)
def get_groups(self) -> typing.Iterator[BMGroup]:
return self.__get_ckobjects(
BMGroup,
bmap.BMFile_GetGroupCount,
bmap.BMFile_GetGroup
)
return self.__get_ckobjects(BMGroup, bmap.BMFile_GetGroupCount, bmap.BMFile_GetGroup)
class BMFileWriter(_AbstractPointer):
def __init__(self, temp_folder_: str, texture_folder_: str, encodings_: tuple[str]):
@ -728,8 +644,8 @@ class BMFileWriter(_AbstractPointer):
self._set_pointer(g_InvalidPtr)
def __create_ckobject(self,
class_type: type[TCKObj],
creator: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID_p], bool]) -> TCKObj:
class_type: type[TCKObject],
creator: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID_p], bmap.bm_bool]) -> TCKObject:
# prepare id container
retid: bmap.bm_CKID = bmap.bm_CKID()
# create new one
@ -738,34 +654,15 @@ class BMFileWriter(_AbstractPointer):
return class_type(self._get_pointer(), retid)
def create_texture(self) -> BMTexture:
return self.__create_ckobject(
BMTexture,
bmap.BMFile_CreateTexture
)
return self.__create_ckobject(BMTexture, bmap.BMFile_CreateTexture)
def create_material(self) -> BMMaterial:
return self.__create_ckobject(
BMMaterial,
bmap.BMFile_CreateMaterial
)
return self.__create_ckobject(BMMaterial, bmap.BMFile_CreateMaterial)
def create_mesh(self) -> BMMesh:
return self.__create_ckobject(
BMMesh,
bmap.BMFile_CreateMesh
)
return self.__create_ckobject(BMMesh, bmap.BMFile_CreateMesh)
def create_3dobject(self) -> BM3dObject:
return self.__create_ckobject(
BM3dObject,
bmap.BMFile_Create3dObject
)
return self.__create_ckobject(BM3dObject, bmap.BMFile_Create3dObject)
def create_group(self) -> BMGroup:
return self.__create_ckobject(
BMGroup,
bmap.BMFile_CreateGroup
)
return self.__create_ckobject(BMGroup, bmap.BMFile_CreateGroup)
class BMMeshTrans(_AbstractPointer):
def __init__(self):
@ -784,8 +681,8 @@ class BMMeshTrans(_AbstractPointer):
bmap.BMMeshTrans_Delete(self._get_pointer())
self._set_pointer(g_InvalidPtr)
def parse(self, bmfile: BMFileWriter, objmesh: BMMesh) -> None:
bmap.BMMeshTrans_Parse(self._get_pointer(), bmfile._get_pointer(), objmesh._get_ckid())
def parse(self, objmesh: BMMesh) -> None:
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:
# prepare count first
@ -795,7 +692,7 @@ class BMMeshTrans(_AbstractPointer):
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMeshTrans_PrepareVertex(self._get_pointer(), ctypes.byref(raw_vector))
# 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:
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()
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:
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()
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:
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()
bmap.BMMeshTrans_PrepareMtlSlot(self._get_pointer(), ctypes.byref(raw_ckid))
idx: int = 0
for _ in range(count):
usermtl: BMMaterial | None = next(itor)
if usermtl is None:
raw_ckid[idx] = g_InvalidCKID
else:
raw_ckid[idx] = usermtl._get_ckid().value
idx += 1
try:
idx: int = 0
for _ in range(count):
usermtl: BMMaterial | None = next(itor)
if usermtl is None:
raw_ckid[idx] = g_InvalidCKID
else:
raw_ckid[idx] = usermtl._get_ckid().value
idx += 1
except StopIteration:
_Utils.raise_out_of_length_exception()
def prepare_face(self,
count: int,
@ -853,13 +752,16 @@ class BMMeshTrans(_AbstractPointer):
# iterate and assign
# assigne triple indices
_ckfaceindices_assigner(raw_vec_idx, count, vec_idx)
_ckfaceindices_assigner(raw_nml_idx, count, nml_idx)
_ckfaceindices_assigner(raw_uv_idx, count, uv_idx)
_Utils.ckfaceindices_assigner(raw_vec_idx, count, vec_idx)
_Utils.ckfaceindices_assigner(raw_nml_idx, count, nml_idx)
_Utils.ckfaceindices_assigner(raw_uv_idx, count, uv_idx)
# assign mtl index
idx: int = 0
for _ in range(count):
raw_mtl_idx[idx] = next(mtl_idx)
idx += 1
try:
idx: int = 0
for _ in range(count):
raw_mtl_idx[idx] = next(mtl_idx)
idx += 1
except StopIteration:
_Utils.raise_out_of_length_exception()
#endregion

View File

@ -9,27 +9,124 @@ def main() -> None:
texture_folder: str = 'F:\\Ballance\\Ballance\\Textures'
encodings: tuple[str, ...] = ('cp1252', )
with bmap.BMFileReader(file_name, temp_folder, texture_folder, encodings) as reader:
print('===== Groups =====')
for gp in reader.get_groups():
print(gp.get_name())
test_common(reader)
test_equatable(reader)
print('===== 3dObjects =====')
for obj in reader.get_3dobjects():
print(obj.get_name())
def test_common(reader: bmap.BMFileReader):
# print('===== Groups =====')
# 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 =====')
for mesh in reader.get_meshs():
print(mesh.get_name())
print(f'\tDiffuse: {mtl.get_diffuse().to_const_rgba()}')
print(f'\tAmbient: {mtl.get_ambient().to_const_rgba()}')
print(f'\tSpecular: {mtl.get_specular().to_const_rgba()}')
print(f'\tEmissive: {mtl.get_emissive().to_const_rgba()}')
print('===== Materials =====')
for mtl in reader.get_materials():
print(mtl.get_name())
print(f'\tSpecular Power: {mtl.get_specular_power()}')
print('===== Textures =====')
for tex in reader.get_textures():
print(tex.get_name())
print(f'\tTexture Border Color: {mtl.get_texture_border_color().to_const_rgba()}')
print(f'\tTexture Blend Mode: {mtl.get_texture_blend_mode()}')
print(f'\tTexture Min Mode: {mtl.get_texture_min_mode()}')
print(f'\tTexture Mag Mode: {mtl.get_texture_mag_mode()}')
print(f'\tSource Blend: {mtl.get_source_blend()}')
print(f'\tDest Blend: {mtl.get_dest_blend()}')
print(f'\tFill Mode: {mtl.get_fill_mode()}')
print(f'\tShade Mode: {mtl.get_shade_mode()}')
print(f'\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 =====')
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__':
main()

View File

@ -6,6 +6,10 @@ endif()
# Find YYCC library
# 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)

83
COMPILE.md Normal file
View File

@ -0,0 +1,83 @@
# Compile Manual
## Requirements
This project require:
* CMake 3.23 at least.
* The common compiler supporting C++ 20 (GCC / Clang / MSVC).
* Littile-endian architecture system.
* zlib.
* iconv (non-Windows system required).
* [stb](https://github.com/nothings/stb): For image read and write.
* [YYCCommonplace](https://github.com/yyc12345/YYCCommonplace): My personal invented library concentrating some common functions for mine.
Since libcmo21 0.2.0, we only provide it in CMake build system. So Windows user should install CMake first or use Visual Studio directly (Visual Studio provides CMake build system supports).
## Preparations
### YYCCommonplace
You should clone YYCCommonplace and switch to the latest release tag (or specified commit hash provided with libcmo21 release infos if you are building for specific libcmo21 version). When configuring YYCCommonplace, you should notice following infos:
* Please make sure that you have specified C++ 20 explicitly by passing `-DCMAKE_CXX_STANDARD=20` in command line. This is crucial because libcmo21 use C++ 20, and YYCCommonplace's ABI is incompatible between C++ 17 version and C++ 20 version.
* If you need `BMap` in final libcmo21 built artifacts, and you are in non-Windows system now, please specify position independent code flag by passing `-DCMAKE_POSITION_INDEPENDENT_CODE=True` in command line. GCC and Clang will reject linking if you don't flag it.
After configuring, you can normally build YYCCommonplace like a common CMake project.
Please note if your final program or dynamic library is provided for end user, please choose `RelWithDebInfo` build type (`Release` is not suggested because it will strip all debug infos and it is not good for bug reporter, which is embedded in program, to report crash). If final program is served for programmer debugging, please choose `Debug` build type.
### stb
You should clone stb repository first, then switch to a specific commit hash `2e2bef463a5b53ddf8bb788e25da6b8506314c08`. In ideally scenario, people like to choose the latest commit. However, I not frequently update this dependency.
### zlib
If you are in Windows, you should download zlib source code and build it with given Visual Studio solution files. The final file we needed is `zlibwapi.dll` with `ZlibDllRelease` build type.
If you are running on non-Windows system. You usually do not need to do anything. Because zlib development environment may be configured by your package manager correctly.
## Compile
### Directory Hierarchy
First, create subdirectory `Bin/build` and `Bin/install` at the root directory of libcmo21.
### Configuration
Then enter subdirectory `Bin/build` and use following command to configure CMake:
- Windows (MSVC): `cmake -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_DOC=OFF -DSTB_IMAGE_PATH=<path-to-stb> -DYYCC_PATH=<path-to-yycc-install> -DZLIB_HEADER_PATH=<path-to-zlib-hdr> -DZLIB_BINARY_PATH=<path-to-zlib-bin> ../..`
- non-Windows: `cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_DOC=OFF -DSTB_IMAGE_PATH=<path-to-stb> -DYYCC_PATH=<path-to-yycc-install> ../..`
The arguments in command should be replaced by:
* `<path-to-stb>`: The root directory of your cloned stb repository.
* `<path-to-yycc-install>`: The directory to installed CMake package you chosen when building YYCCommonplace.
* `<path-to-zlib-hdr>` (Windows only): The root directory of downloaded zlib source code.
* `<path-to-zlib-bin>` (Windows only): The directory where you can find built `zlibwapi.dll`.
The switches in command can be switched as you wish:
* `NEMO_BUILD_UNVIRT`: Build `Unvirt`, a command line application debugging Virtools files.
* `NEMO_BUILD_BMAP`: Build `BMap`, a dynamic library specific used for loading Ballance map file. If you are coming from my another project [BallanceBlenderPlugin](https://github.com/yyc12345/BallanceBlenderHelper), this is what you need.
* `NEMO_BUILD_DOC`: Build the document of libcmo21.
### Build
Execute following command to build libcmo21.
* Windows: `cmake --build . --config RelWithDebInfo`
* non-Windows: `cmake --build .`
### Build Type
Like YYCCommonplace, we suggest `RelWithDebInfo` for end user. If you want to build for programmer debugging, please replace all `RelWithDebInfo` to `Debug`. The build type between YYCCommonplace and libcmo21 should keep same to reduce any possibility about ABI incompatible issue.
## Install
Currently the CMake install script still has some bugs and can not work as expected. So as the alternative, just go into build directory and find your final program please. It's pretty simple.
## Note
You may face issue when compiling this program on Linux or macOS because I develop this project on Windows frequently. The compatibility with Linux will only be checked just before releasing. And I don't have any Apple device to check the compatibility with macOS. So, for Linux issue, please report it directly and I will try to fix. For macOS bug, PR is welcomed.

View File

@ -118,6 +118,7 @@ public class CSharpWriter {
ret.mMarshalAs = "UnmanagedType.SysInt";
ret.mCsType = "IntPtr";
}
break;
case "CK_ID":
if (vt_pointer_level == 0) {
ret.mMarshalAs = "UnmanagedType.U4";
@ -195,11 +196,14 @@ public class CSharpWriter {
case "VXSHADE_MODE":
case "VXCMPFUNC":
case "VXMESH_LITMODE":
// all enum share the same underlying type.
// all enum type use the same strategy
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.mCsType = "uint";
ret.mCsType = vt_base_type;
} else {
// for pointer type, use IntPtr instead.
ret.mMarshalAs = "UnmanagedType.SysInt";
ret.mCsType = "IntPtr";
}

View File

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

View File

@ -521,7 +521,7 @@ namespace LibCmo::CK2 {
m_Slots.resize(count);
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;
// NOTE: idk what the fuck this is. just interpter the IDA decompiled code.
if (EnumsHelper::Has(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP)) {
EnumsHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_FORCERESTORE);
if (YYCC::EnumHelper::Has(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP)) {
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.
// User should set slot count manually.
if (is_cube) {
EnumsHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP);
YYCC::EnumHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP);
} else {
EnumsHelper::Rm(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP);
YYCC::EnumHelper::Remove(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_CUBEMAP);
}
}
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 {
@ -688,14 +688,14 @@ namespace LibCmo::CK2 {
void CKBitmapData::SetTransparent(bool Transparency) {
if (Transparency) {
EnumsHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_TRANSPARENT);
YYCC::EnumHelper::Add(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_TRANSPARENT);
} else {
EnumsHelper::Rm(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_TRANSPARENT);
YYCC::EnumHelper::Remove(m_BitmapFlags, CK_BITMAPDATA_FLAGS::CKBITMAPDATA_TRANSPARENT);
}
}
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) {

View File

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

View File

@ -216,8 +216,8 @@ namespace LibCmo::CK2 {
}
// compress header if needed
if (EnumsHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) ||
EnumsHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
if (YYCC::EnumHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) ||
YYCC::EnumHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
CKDWORD comp_buf_size = 0;
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
if (EnumsHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) ||
EnumsHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
if (YYCC::EnumHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) ||
YYCC::EnumHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
CKDWORD comp_buf_size = 0;
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);
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
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]);
bufpos += 1u;
std::memcpy(this->m_ObjectList.data(), dwbuf + bufpos, sizeof(CKDWORD) * 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]);
bufpos += 1u;
std::memcpy(this->m_ChunkList.data(), dwbuf + bufpos, sizeof(CKDWORD) * 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]);
bufpos += 1u;
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()) {
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()) {
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()) {
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) {
EnumsHelper::Add(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_FILE);
YYCC::EnumHelper::Add(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_FILE);
}
// if buffer provided, write it

View File

@ -86,7 +86,7 @@ namespace LibCmo::CK2::MgrImpls {
// set to be deleted
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);
// collect class id

View File

@ -9,12 +9,12 @@ namespace LibCmo::CK2::ObjImpls {
CKRenderObject(ctx, ckid, name),
m_PotentialMeshes(), m_CurrentMesh(nullptr),
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_VISIBLE,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_RENDERCHANNELS,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_INVERSEWORLDMATVALID
})),
)),
m_3dEntityFlags(static_cast<CK_3DENTITY_FLAGS>(0)) {}
CK3dEntity::~CK3dEntity() {}
@ -53,15 +53,15 @@ namespace LibCmo::CK2::ObjImpls {
// regulate self flag again
// MARK: originally we should check parent here.
// 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.
// 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
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 {
EnumsHelper::Rm(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_ZORDERVALID);
YYCC::EnumHelper::Remove(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_ZORDERVALID);
}
// write 2 flags
@ -94,7 +94,7 @@ namespace LibCmo::CK2::ObjImpls {
if (!suc) return false;
// 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
@ -132,11 +132,11 @@ namespace LibCmo::CK2::ObjImpls {
chunk->ReadStruct(m_3dEntityFlags);
chunk->ReadStruct(m_MoveableFlags);
// 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_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_STENCILONLY,
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_USERBOX,
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_UPTODATE
}));
);
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 (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;
}
@ -171,47 +171,47 @@ namespace LibCmo::CK2::ObjImpls {
VxMath::VxVector3 crossProduct = VxMath::NSVxVector::CrossProduct(col0, col1);
CKFLOAT dotProduct = VxMath::NSVxVector::DotProduct(crossProduct, col2);
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 {
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
// process direct visible
if (EnumsHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE)) {
EnumsHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE);
if (YYCC::EnumHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE)) {
YYCC::EnumHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE);
} 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
if (EnumsHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE)) {
EnumsHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE);
if (YYCC::EnumHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE)) {
YYCC::EnumHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE);
} 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
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.
// so we just read it and skip it.
CK_ID placeid;
chunk->ReadObjectID(placeid);
// 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
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
// we ignore this field.
CK_ID parentid;
chunk->ReadObjectID(parentid);
// 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)
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);
}
@ -227,16 +227,16 @@ namespace LibCmo::CK2::ObjImpls {
void CK3dEntity::Show(CK_OBJECT_SHOWOPTION 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_HIERARCHICALHIDE,
}));
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE
);
switch (show) {
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;
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;
case CK_OBJECT_SHOWOPTION::CKHIDE:
break;

View File

@ -21,12 +21,12 @@ namespace LibCmo::CK2::ObjImpls {
m_LineCount(0),
m_LineIndices(),
// init flags
m_Flags(EnumsHelper::Merge({
m_Flags(YYCC::EnumHelper::Merge(
VxMath::VXMESH_FLAGS::VXMESH_VISIBLE,
VxMath::VXMESH_FLAGS::VXMESH_RENDERCHANNELS
})) {
)) {
// 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() {}
@ -145,7 +145,7 @@ namespace LibCmo::CK2::ObjImpls {
rawbuf += CKSizeof(CKDWORD);
// write vertex position
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::NoPos)) {
if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::NoPos)) {
CKDWORD consumed = CKSizeof(VxMath::VxVector3) * vtxCount;
std::memcpy(rawbuf, m_VertexPosition.data(), consumed);
rawbuf += consumed;
@ -154,7 +154,7 @@ namespace LibCmo::CK2::ObjImpls {
// write color and specular color
{
CKDWORD consumed = 0;
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::SingleColor)) {
if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::SingleColor)) {
consumed = CKSizeof(CKDWORD) * vtxCount;
} else {
consumed = CKSizeof(CKDWORD);
@ -165,7 +165,7 @@ namespace LibCmo::CK2::ObjImpls {
}
{
CKDWORD consumed = 0;
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::SingleSpecularColor)) {
if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::SingleSpecularColor)) {
consumed = CKSizeof(CKDWORD) * vtxCount;
} else {
consumed = CKSizeof(CKDWORD);
@ -176,7 +176,7 @@ namespace LibCmo::CK2::ObjImpls {
}
// write normal
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::NoNormal)) {
if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::NoNormal)) {
CKDWORD consumed = CKSizeof(VxMath::VxVector3) * vtxCount;
std::memcpy(rawbuf, m_VertexNormal.data(), consumed);
rawbuf += consumed;
@ -185,7 +185,7 @@ namespace LibCmo::CK2::ObjImpls {
// write uv
{
CKDWORD consumed = 0;
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::SingleUV)) {
if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::SingleUV)) {
consumed = CKSizeof(VxMath::VxVector2) * vtxCount;
} else {
consumed = CKSizeof(VxMath::VxVector2);
@ -229,13 +229,13 @@ namespace LibCmo::CK2::ObjImpls {
// read flag
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_MESH::CK_STATESAVE_MESHFLAGS)) {
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.
EnumsHelper::Rm(m_Flags, EnumsHelper::Merge({
YYCC::EnumHelper::Remove(m_Flags,
VxMath::VXMESH_FLAGS::VXMESH_BOUNDINGUPTODATE,
VxMath::VXMESH_FLAGS::VXMESH_OPTIMIZED
}));
);
}
// read material slots
@ -285,14 +285,14 @@ namespace LibCmo::CK2::ObjImpls {
const CKBYTE* rawbuf = static_cast<const CKBYTE*>(buf.get());
// copy position if it have
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::NoPos)) {
if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::NoPos)) {
CKDWORD consumed = CKSizeof(VxMath::VxVector3) * vertexCount;
std::memcpy(m_VertexPosition.data(), rawbuf, consumed);
rawbuf += consumed;
}
// copy color or apply single color
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::SingleColor)) {
if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::SingleColor)) {
CKDWORD consumed = CKSizeof(CKDWORD) * vertexCount;
std::memcpy(m_VertexColor.data(), rawbuf, consumed);
rawbuf += consumed;
@ -309,7 +309,7 @@ namespace LibCmo::CK2::ObjImpls {
}
// 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;
std::memcpy(m_VertexSpecularColor.data(), rawbuf, consumed);
rawbuf += consumed;
@ -326,14 +326,14 @@ namespace LibCmo::CK2::ObjImpls {
}
// copy normals if it has
if (!EnumsHelper::Has(saveflags, VertexSaveFlags::NoNormal)) {
if (!YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::NoNormal)) {
CKDWORD consumed = CKSizeof(VxMath::VxVector3) * vertexCount;
std::memcpy(m_VertexNormal.data(), rawbuf, consumed);
rawbuf += consumed;
}
// 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;
std::memcpy(m_VertexUV.data(), rawbuf, consumed);
rawbuf += consumed;
@ -407,7 +407,7 @@ namespace LibCmo::CK2::ObjImpls {
}
// build normals
if (EnumsHelper::Has(saveflags, VertexSaveFlags::NoNormal)) {
if (YYCC::EnumHelper::Has(saveflags, VertexSaveFlags::NoNormal)) {
BuildNormals();
} else {
BuildFaceNormals();
@ -425,9 +425,9 @@ namespace LibCmo::CK2::ObjImpls {
CKObject::Show(show);
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 {
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;
// sync visibility to CKObject layer.
if (EnumsHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_VISIBLE)) {
EnumsHelper::Add(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
if (YYCC::EnumHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_VISIBLE)) {
YYCC::EnumHelper::Add(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
} 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 {
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;
} else {
return VxMath::VXMESH_LITMODE::VX_LITMESH;
@ -467,10 +467,10 @@ namespace LibCmo::CK2::ObjImpls {
void CKMesh::SetLitMode(VxMath::VXMESH_LITMODE mode) {
switch (mode) {
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;
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;
}
}
@ -478,51 +478,51 @@ namespace LibCmo::CK2::ObjImpls {
VxMath::VXTEXTURE_WRAPMODE CKMesh::GetWrapMode() const {
VxMath::VXTEXTURE_WRAPMODE ret = VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_NONE;
if (EnumsHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPU)) {
EnumsHelper::Add(ret, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_U);
if (YYCC::EnumHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPU)) {
YYCC::EnumHelper::Add(ret, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_U);
}
if (EnumsHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPV)) {
EnumsHelper::Add(ret, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_V);
if (YYCC::EnumHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPV)) {
YYCC::EnumHelper::Add(ret, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_V);
}
return ret;
}
void CKMesh::SetWrapMode(VxMath::VXTEXTURE_WRAPMODE mode) {
if (EnumsHelper::Has(mode, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_U)) {
EnumsHelper::Add(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPU);
if (YYCC::EnumHelper::Has(mode, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_U)) {
YYCC::EnumHelper::Add(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPU);
} 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)) {
EnumsHelper::Add(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPV);
if (YYCC::EnumHelper::Has(mode, VxMath::VXTEXTURE_WRAPMODE::VXTEXTUREWRAP_V)) {
YYCC::EnumHelper::Add(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPV);
} else {
EnumsHelper::Rm(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPV);
YYCC::EnumHelper::Remove(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_WRAPV);
}
}
CKMesh::VertexSaveFlags CKMesh::GenerateSaveFlags() {
// set to initial status
VertexSaveFlags saveflags = EnumsHelper::Merge({
VertexSaveFlags saveflags = YYCC::EnumHelper::Merge(
VertexSaveFlags::SingleColor,
VertexSaveFlags::SingleSpecularColor,
VertexSaveFlags::NoNormal,
VertexSaveFlags::SingleUV
});
);
// check no pos
// if position is generated, skip saving position
if (EnumsHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_PROCEDURALPOS)) {
EnumsHelper::Add(saveflags, VertexSaveFlags::NoPos);
if (YYCC::EnumHelper::Has(m_Flags, VxMath::VXMESH_FLAGS::VXMESH_PROCEDURALPOS)) {
YYCC::EnumHelper::Add(saveflags, VertexSaveFlags::NoPos);
}
// check 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) {
if (uv != m_VertexUV.front()) {
EnumsHelper::Rm(saveflags, VertexSaveFlags::SingleUV);
YYCC::EnumHelper::Remove(saveflags, VertexSaveFlags::SingleUV);
break;
}
}
@ -532,19 +532,19 @@ namespace LibCmo::CK2::ObjImpls {
// if all color are not the same value, remove single color
for (const auto& col : m_VertexColor) {
if (col != m_VertexColor.front()) {
EnumsHelper::Rm(saveflags, VertexSaveFlags::SingleColor);
YYCC::EnumHelper::Remove(saveflags, VertexSaveFlags::SingleColor);
break;
}
}
for (const auto& col : m_VertexSpecularColor) {
if (col != m_VertexSpecularColor.front()) {
EnumsHelper::Rm(saveflags, VertexSaveFlags::SingleSpecularColor);
YYCC::EnumHelper::Remove(saveflags, VertexSaveFlags::SingleSpecularColor);
break;
}
}
// 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
// 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.
@ -581,7 +581,7 @@ namespace LibCmo::CK2::ObjImpls {
accnml /= static_cast<CKFLOAT>(m_VertexCount);
if (accnml.Length() > 0.001f) {
// 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;
}
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 {
return m_Context;
@ -51,10 +51,10 @@ namespace LibCmo::CK2::ObjImpls {
void CKObject::PreSave(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
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
chunk->WriteIdentifier(CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIDDEN);
}
@ -65,18 +65,20 @@ namespace LibCmo::CK2::ObjImpls {
bool CKObject::Load(CKStateChunk* chunk, CKFileVisitor* file) {
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIDDEN)) {
EnumsHelper::Rm(this->m_ObjectFlags,
EnumsHelper::Merge({ CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE }));
YYCC::EnumHelper::Remove(this->m_ObjectFlags,
CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE,
CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE
);
} else {
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIERAHIDDEN)) {
// != 0
EnumsHelper::Rm(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
EnumsHelper::Add(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE);
YYCC::EnumHelper::Remove(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
YYCC::EnumHelper::Add(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE);
} else {
// == 0
EnumsHelper::Add(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
EnumsHelper::Rm(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE);
YYCC::EnumHelper::Add(this->m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE);
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) {
// 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_VISIBLE
}));
);
switch (show) {
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;
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;
case CK_OBJECT_SHOWOPTION::CKHIDE:
return;
@ -107,7 +109,7 @@ namespace LibCmo::CK2::ObjImpls {
}
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
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE
YYCC::YYCCommonplace
ZLIB::ZLIB
stb::stb-image
)
target_link_libraries(LibCmo
PRIVATE
PUBLIC
YYCC::YYCCommonplace
PRIVATE
ZLIB::ZLIB
stb::stb-image
)
if (NOT WIN32)
target_include_directories(LibCmo PRIVATE Iconv::Iconv)
target_link_libraries(LibCmo PRIVATE Iconv::Iconv)
endif ()
# Setup C++ standard

View File

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

View File

@ -10,4 +10,4 @@
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stb_image_write.h>
#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!"
#endif
// Include YYCC helper library
// Include YYCC helper library and check its version
#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
#include <string>
#include <type_traits>
#include <initializer_list>
/**
* @brief The core namespace of LibCmo project.
@ -69,91 +70,4 @@ namespace LibCmo {
#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 <cmath>
#include <stb_image_resize.h>
#include <deprecated/stb_image_resize.h>
namespace LibCmo::VxMath {

View File

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

View File

@ -1,7 +1,7 @@
# libcmo21
The Library for CMO (also accept NMO, VMO and NMS) File Read/Write. Also the Minimalist Virtools Environment.
Write with one Library and Load Virtools File Everywhere.
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/Save Virtools File Everywhere.
## Status
@ -10,12 +10,15 @@ This project welcome everyone's contribution, except the employee of Dassault, w
## 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.
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 aim of this project is creating a universal library which can RW CMO files or any other Virtools files without any Virtools dependencies.
**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
@ -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 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 C# binding for the loader to enable that I can load Ballance Map in Godot on Linux / Android 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.
There is still a long way to go. But I will try my best.
## 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.
* 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).
* BMap: A dynamic library which is specific for Ballance Map loading by using LibCmo.
## 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.
There are 3 lists which indicate our accept guideline.
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.
### Wanted Features
@ -64,14 +65,4 @@ These features explicitly will not be merged.
## Compile
This project require:
* The compiler supporting C++ 20
* Littile-endian architecture system.
* zlib
* [stb](https://github.com/nothings/stb) (For image read / write)
* iconv (non-Windows system required)
It can be compiled on Windows via sln file. You should set up `LibRef.props` when using sln file to build this project on Windows.
You also can use CMake file to compile this project on Linux or anything else platform. However CMake may not be updated in time because I develop this project on Windows frequently.
You may need use this command to configure CMake: `cmake .. -DSTB_IMAGE_PATH="/path/to/stb-image" -DCMAKE_BUILD_TYPE=Release`
See [Compile Manual](./COMPILE.md)

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
if (LibCmo::EnumsHelper::Has(val, item.first)) {
if (YYCC::EnumHelper::Has(val, item.first)) {
// add splittor if it not the first entry
if (strl.size() != 0u && splitor != nullptr) {
strl += splitor;

View File

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