feat: continue improving BMapSharp.
- add BMFileWriter in BMapSharp.
This commit is contained in:
parent
623334f863
commit
4d04b38d52
|
@ -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.
|
// 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.
|
// 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
|
// Check marshaler type
|
||||||
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return nint.Zero;
|
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return IntPtr.Zero;
|
||||||
// Check nullptr object.
|
// Check nullptr object.
|
||||||
if (ManagedObj is null) return nint.Zero;
|
if (ManagedObj is null) return IntPtr.Zero;
|
||||||
// Check argument type.
|
// Check argument type.
|
||||||
string[] castManagedObj = ManagedObj as string[];
|
string[] castManagedObj = ManagedObj as string[];
|
||||||
if (castManagedObj is null)
|
if (castManagedObj is null)
|
||||||
|
@ -70,45 +70,45 @@ namespace BMapSharp {
|
||||||
|
|
||||||
// Allocate string items first
|
// Allocate string items first
|
||||||
int szArrayItemCount = castManagedObj.Length;
|
int szArrayItemCount = castManagedObj.Length;
|
||||||
int szArrayItemSize = Marshal.SizeOf<nint>();
|
int szArrayItemSize = Marshal.SizeOf<IntPtr>();
|
||||||
nint[] apString = new nint[szArrayItemCount];
|
IntPtr[] apString = new IntPtr[szArrayItemCount];
|
||||||
for (int i = 0; i < szArrayItemCount; ++i) {
|
for (int i = 0; i < szArrayItemCount; ++i) {
|
||||||
// Check null string
|
// Check null string
|
||||||
string stringObj = castManagedObj[i];
|
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);
|
else apString[i] = BMStringMarshaler.ToNative(stringObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate array pointer now.
|
// Allocate array pointer now.
|
||||||
nint pArray = Marshal.AllocHGlobal(szArrayItemSize * (szArrayItemCount + 1));
|
IntPtr pArray = Marshal.AllocHGlobal(szArrayItemSize * (szArrayItemCount + 1));
|
||||||
// Copy string pointer data
|
// Copy string pointer data
|
||||||
Marshal.Copy(apString, 0, pArray, szArrayItemCount);
|
Marshal.Copy(apString, 0, pArray, szArrayItemCount);
|
||||||
// Setup NULL ternimal
|
// Setup NULL ternimal
|
||||||
Marshal.WriteIntPtr(pArray + (szArrayItemSize * szArrayItemCount), nint.Zero);
|
Marshal.WriteIntPtr(pArray + (szArrayItemSize * szArrayItemCount), IntPtr.Zero);
|
||||||
|
|
||||||
// Return value
|
// Return value
|
||||||
return pArray;
|
return pArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object MarshalNativeToManaged(nint pNativeData) {
|
public object MarshalNativeToManaged(IntPtr pNativeData) {
|
||||||
// Check marshaler type
|
// Check marshaler type
|
||||||
if (!m_MarshalerType.HasFlag(MarshalerType.Out)) return null;
|
if (!m_MarshalerType.HasFlag(MarshalerType.Out)) return null;
|
||||||
// Check nullptr
|
// Check nullptr
|
||||||
if (pNativeData == nint.Zero) return null;
|
if (pNativeData == IntPtr.Zero) return null;
|
||||||
|
|
||||||
// Get the length of array
|
// Get the length of array
|
||||||
int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData);
|
int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData);
|
||||||
int szArrayItemSize = Marshal.SizeOf<nint>();
|
int szArrayItemSize = Marshal.SizeOf<IntPtr>();
|
||||||
// Prepare array cache and read it.
|
// Prepare array cache and read it.
|
||||||
nint[] apString = new nint[szArrayItemCount];
|
IntPtr[] apString = new IntPtr[szArrayItemCount];
|
||||||
Marshal.Copy(pNativeData, apString, 0, szArrayItemCount);
|
Marshal.Copy(pNativeData, apString, 0, szArrayItemCount);
|
||||||
|
|
||||||
// Iterate the array and process each string one by one.
|
// Iterate the array and process each string one by one.
|
||||||
string[] ret = new string[szArrayItemCount];
|
string[] ret = new string[szArrayItemCount];
|
||||||
for (int i = 0; i < szArrayItemCount; ++i) {
|
for (int i = 0; i < szArrayItemCount; ++i) {
|
||||||
// Get string pointer
|
// Get string pointer
|
||||||
nint pString = apString[i];
|
IntPtr pString = apString[i];
|
||||||
if (pString == nint.Zero) {
|
if (pString == IntPtr.Zero) {
|
||||||
ret[i] = null;
|
ret[i] = null;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -120,25 +120,25 @@ namespace BMapSharp {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CleanUpNativeData(nint pNativeData) {
|
public void CleanUpNativeData(IntPtr pNativeData) {
|
||||||
// Check marshaler type
|
// Check marshaler type
|
||||||
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return;
|
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return;
|
||||||
// Check nullptr
|
// Check nullptr
|
||||||
if (pNativeData == nint.Zero) return;
|
if (pNativeData == IntPtr.Zero) return;
|
||||||
|
|
||||||
// Get the length of array
|
// Get the length of array
|
||||||
int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData);
|
int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData);
|
||||||
int szArrayItemSize = Marshal.SizeOf<nint>();
|
int szArrayItemSize = Marshal.SizeOf<IntPtr>();
|
||||||
// Prepare array cache and read it.
|
// Prepare array cache and read it.
|
||||||
nint[] apString = new nint[szArrayItemCount];
|
IntPtr[] apString = new IntPtr[szArrayItemCount];
|
||||||
Marshal.Copy(pNativeData, apString, 0, szArrayItemCount);
|
Marshal.Copy(pNativeData, apString, 0, szArrayItemCount);
|
||||||
// Free array self
|
// Free array self
|
||||||
Marshal.FreeHGlobal(pNativeData);
|
Marshal.FreeHGlobal(pNativeData);
|
||||||
|
|
||||||
// Iterate the string pointer array and free them one by one.
|
// Iterate the string pointer array and free them one by one.
|
||||||
foreach (nint pString in apString) {
|
foreach (IntPtr pString in apString) {
|
||||||
// Free string pointer
|
// Free string pointer
|
||||||
if (pString == nint.Zero) continue;
|
if (pString == IntPtr.Zero) continue;
|
||||||
Marshal.FreeHGlobal(pString);
|
Marshal.FreeHGlobal(pString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,9 +157,9 @@ namespace BMapSharp {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ptr">The pointer to array for checking.</param>
|
/// <param name="ptr">The pointer to array for checking.</param>
|
||||||
/// <returns>The length of array (NULL terminal exclusive).</returns>
|
/// <returns>The length of array (NULL terminal exclusive).</returns>
|
||||||
internal static int GetArrayLength(nint ptr) {
|
internal static int GetArrayLength(IntPtr ptr) {
|
||||||
int count = 0, unit = Marshal.SizeOf<nint>();
|
int count = 0, unit = Marshal.SizeOf<IntPtr>();
|
||||||
while (Marshal.ReadIntPtr(ptr) != nint.Zero) {
|
while (Marshal.ReadIntPtr(ptr) != IntPtr.Zero) {
|
||||||
ptr += unit;
|
ptr += unit;
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
@ -181,11 +181,11 @@ namespace BMapSharp {
|
||||||
m_MarshalerType = marshaler_type;
|
m_MarshalerType = marshaler_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public nint MarshalManagedToNative(object ManagedObj) {
|
public IntPtr MarshalManagedToNative(object ManagedObj) {
|
||||||
// Check marshaler type
|
// Check marshaler type
|
||||||
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return nint.Zero;
|
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return IntPtr.Zero;
|
||||||
// Check requirements.
|
// Check requirements.
|
||||||
if (ManagedObj is null) return nint.Zero;
|
if (ManagedObj is null) return IntPtr.Zero;
|
||||||
string castManagedObj = ManagedObj as string;
|
string castManagedObj = ManagedObj as string;
|
||||||
if (castManagedObj is null)
|
if (castManagedObj is null)
|
||||||
throw new MarshalDirectiveException("BMStringMarshaler must be used on a string.");
|
throw new MarshalDirectiveException("BMStringMarshaler must be used on a string.");
|
||||||
|
@ -193,20 +193,20 @@ namespace BMapSharp {
|
||||||
return BMStringMarshaler.ToNative(castManagedObj);
|
return BMStringMarshaler.ToNative(castManagedObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public object MarshalNativeToManaged(nint pNativeData) {
|
public object MarshalNativeToManaged(IntPtr pNativeData) {
|
||||||
// Check marshaler type
|
// Check marshaler type
|
||||||
if (!m_MarshalerType.HasFlag(MarshalerType.Out)) return null;
|
if (!m_MarshalerType.HasFlag(MarshalerType.Out)) return null;
|
||||||
// Check nullptr
|
// Check nullptr
|
||||||
if (pNativeData == nint.Zero) return null;
|
if (pNativeData == IntPtr.Zero) return null;
|
||||||
// Call self
|
// Call self
|
||||||
return BMStringMarshaler.ToManaged(pNativeData);
|
return BMStringMarshaler.ToManaged(pNativeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CleanUpNativeData(nint pNativeData) {
|
public void CleanUpNativeData(IntPtr pNativeData) {
|
||||||
// Check marshaler type
|
// Check marshaler type
|
||||||
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return;
|
if (!m_MarshalerType.HasFlag(MarshalerType.In)) return;
|
||||||
// Check nullptr
|
// Check nullptr
|
||||||
if (pNativeData == nint.Zero) return;
|
if (pNativeData == IntPtr.Zero) return;
|
||||||
// Free native pointer
|
// Free native pointer
|
||||||
Marshal.FreeHGlobal(pNativeData);
|
Marshal.FreeHGlobal(pNativeData);
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,7 @@ namespace BMapSharp {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ptr">The pointer for checking.</param>
|
/// <param name="ptr">The pointer for checking.</param>
|
||||||
/// <returns>The length of C style string (NUL exclusive).</returns>
|
/// <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>();
|
int count = 0, unit = Marshal.SizeOf<byte>();
|
||||||
while (Marshal.ReadByte(ptr) != (byte)0) {
|
while (Marshal.ReadByte(ptr) != (byte)0) {
|
||||||
ptr += unit;
|
ptr += unit;
|
||||||
|
@ -240,13 +240,13 @@ namespace BMapSharp {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="obj">String object. Caller must make sure this object is not null.</param>
|
/// <param name="obj">String object. Caller must make sure this object is not null.</param>
|
||||||
/// <returns>The created native data pointer.</returns>
|
/// <returns>The created native data pointer.</returns>
|
||||||
internal static nint ToNative(string obj) {
|
internal static IntPtr ToNative(string obj) {
|
||||||
// Encode string first
|
// Encode string first
|
||||||
byte[] encString = Encoding.UTF8.GetBytes(obj);
|
byte[] encString = Encoding.UTF8.GetBytes(obj);
|
||||||
// Allocate string memory with extra NUL.
|
// Allocate string memory with extra NUL.
|
||||||
int szStringItemCount = encString.Length;
|
int szStringItemCount = encString.Length;
|
||||||
int szStringItemSize = Marshal.SizeOf<byte>();
|
int szStringItemSize = Marshal.SizeOf<byte>();
|
||||||
nint pString = Marshal.AllocHGlobal(szStringItemSize * (szStringItemCount + 1));
|
IntPtr pString = Marshal.AllocHGlobal(szStringItemSize * (szStringItemCount + 1));
|
||||||
// Copy encoded string data
|
// Copy encoded string data
|
||||||
Marshal.Copy(encString, 0, pString, szStringItemCount);
|
Marshal.Copy(encString, 0, pString, szStringItemCount);
|
||||||
// Setup NUL
|
// Setup NUL
|
||||||
|
@ -260,7 +260,7 @@ namespace BMapSharp {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ptr">Native pointer holding string data. Caller must make sure this pointer is not nullptr.</param>
|
/// <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>
|
/// <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.
|
// Get the length of given string.
|
||||||
int szStringItemCount = BMStringMarshaler.GetCStringLength(ptr);
|
int szStringItemCount = BMStringMarshaler.GetCStringLength(ptr);
|
||||||
int szStringItemSize = Marshal.SizeOf<byte>();
|
int szStringItemSize = Marshal.SizeOf<byte>();
|
||||||
|
|
|
@ -94,16 +94,19 @@ namespace BMapSharp.BMapWrapper {
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class AbstractCKObject {
|
public abstract class AbstractCKObject : SafeHandle {
|
||||||
internal AbstractCKObject(IntPtr raw_pointer, uint ckid) {
|
// Same as AbstractPointer, but not own this handle.
|
||||||
m_RawPointer = raw_pointer;
|
internal AbstractCKObject(IntPtr raw_pointer, uint ckid) : base(Utils.INVALID_PTR, false) {
|
||||||
|
this.handle = raw_pointer;
|
||||||
m_CKID = ckid;
|
m_CKID = ckid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IntPtr m_RawPointer;
|
public override bool IsInvalid => this.handle == Utils.INVALID_PTR;
|
||||||
|
protected override bool ReleaseHandle() => throw new NotImplementedException();
|
||||||
|
|
||||||
private readonly uint m_CKID;
|
private readonly uint m_CKID;
|
||||||
protected bool isValid() => m_RawPointer != Utils.INVALID_PTR && m_RawPointer != Utils.INVALID_CKID;
|
protected bool isValid() => this.handle != Utils.INVALID_PTR && m_CKID != Utils.INVALID_CKID;
|
||||||
protected IntPtr getPointer() => m_RawPointer;
|
protected IntPtr getPointer() => this.handle;
|
||||||
protected uint getCKID() => m_CKID;
|
protected uint getCKID() => m_CKID;
|
||||||
|
|
||||||
// private uint m_CKID;
|
// private uint m_CKID;
|
||||||
|
@ -143,14 +146,14 @@ namespace BMapSharp.BMapWrapper {
|
||||||
|
|
||||||
#region Misc
|
#region Misc
|
||||||
|
|
||||||
public override int GetHashCode() => HashCode.Combine(m_RawPointer, m_CKID);
|
public override int GetHashCode() => HashCode.Combine(this.handle, m_CKID);
|
||||||
public override string ToString() => $"{m_RawPointer}, {m_CKID}";
|
public override string ToString() => $"{this.handle}, {m_CKID}";
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BMObject : AbstractCKObject {
|
public class BMObject : AbstractCKObject {
|
||||||
internal BMObject(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
internal BMObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
||||||
|
|
||||||
public string GetName() {
|
public string GetName() {
|
||||||
BMapException.ThrowIfFailed(BMap.BMObject_GetName(
|
BMapException.ThrowIfFailed(BMap.BMObject_GetName(
|
||||||
|
@ -166,27 +169,27 @@ namespace BMapSharp.BMapWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BMTexture : BMObject {
|
public class BMTexture : BMObject {
|
||||||
internal BMTexture(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
internal BMTexture(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BMMaterial : BMObject {
|
public class BMMaterial : BMObject {
|
||||||
internal BMMaterial(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
internal BMMaterial(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BMMesh : BMObject {
|
public class BMMesh : BMObject {
|
||||||
internal BMMesh(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
internal BMMesh(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BM3dObject : BMObject {
|
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 class BMGroup : BMObject {
|
public class BMGroup : BMObject {
|
||||||
internal BMGroup(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
internal BMGroup(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class BMFileReader : AbstractPointer {
|
public sealed class BMFileReader : AbstractPointer {
|
||||||
private static IntPtr AllocateHandle(string file_name, string temp_folder, string texture_folder, string[] encodings) {
|
private static IntPtr allocateHandle(string file_name, string temp_folder, string texture_folder, string[] encodings) {
|
||||||
BMapException.ThrowIfFailed(BMap.BMFile_Load(
|
BMapException.ThrowIfFailed(BMap.BMFile_Load(
|
||||||
file_name, temp_folder, texture_folder,
|
file_name, temp_folder, texture_folder,
|
||||||
Utils.BMapSharpCallback,
|
Utils.BMapSharpCallback,
|
||||||
|
@ -196,21 +199,20 @@ namespace BMapSharp.BMapWrapper {
|
||||||
return out_file;
|
return out_file;
|
||||||
}
|
}
|
||||||
protected override bool ReleaseHandle() {
|
protected override bool ReleaseHandle() {
|
||||||
return BMap.BMFile_Free(this.handle);
|
return BMap.BMFile_Free(this.getPointer());
|
||||||
}
|
}
|
||||||
public BMFileReader(string file_name, string temp_folder, string texture_folder, string[] encodings)
|
public BMFileReader(string file_name, string temp_folder, string texture_folder, string[] encodings)
|
||||||
: base(AllocateHandle(file_name, temp_folder, texture_folder, encodings)) { }
|
: base(allocateHandle(file_name, temp_folder, texture_folder, encodings)) { }
|
||||||
|
|
||||||
|
private delegate bool FctProtoGetCount(IntPtr bmf, out uint cnt);
|
||||||
private delegate bool FctProtoGetCount(nint bmf, out uint cnt);
|
private delegate bool FctProtoGetObject(IntPtr bmf, uint idx, out uint id);
|
||||||
private delegate bool FctProtoGetObject(nint bmf, uint idx, out uint id);
|
private delegate T FctProtoCreateInstance<T>(IntPtr bmf, uint id);
|
||||||
private delegate T FctProtoCreateInstance<T>(nint bmf, uint id);
|
private uint getCKObjectCount(FctProtoGetCount fct_cnt) {
|
||||||
private uint GetCKObjectCount(FctProtoGetCount fct_cnt) {
|
|
||||||
BMapException.ThrowIfFailed(fct_cnt(this.getPointer(), out uint out_count));
|
BMapException.ThrowIfFailed(fct_cnt(this.getPointer(), out uint out_count));
|
||||||
return out_count;
|
return out_count;
|
||||||
}
|
}
|
||||||
private IEnumerable<T> GetCKObjects<T>(FctProtoGetCount fct_cnt, FctProtoGetObject fct_obj, FctProtoCreateInstance<T> fct_crt) {
|
private IEnumerable<T> getCKObjects<T>(FctProtoGetCount fct_cnt, FctProtoGetObject fct_obj, FctProtoCreateInstance<T> fct_crt) {
|
||||||
uint count = GetCKObjectCount(fct_cnt);
|
uint count = getCKObjectCount(fct_cnt);
|
||||||
for (uint i = 0; i < count; ++i) {
|
for (uint i = 0; i < count; ++i) {
|
||||||
BMapException.ThrowIfFailed(fct_obj(this.getPointer(), i, out uint out_id));
|
BMapException.ThrowIfFailed(fct_obj(this.getPointer(), i, out uint out_id));
|
||||||
yield return fct_crt(this.getPointer(), out_id);
|
yield return fct_crt(this.getPointer(), out_id);
|
||||||
|
@ -218,26 +220,56 @@ namespace BMapSharp.BMapWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint GetTextureCount() =>
|
public uint GetTextureCount() =>
|
||||||
GetCKObjectCount(BMap.BMFile_GetTextureCount);
|
getCKObjectCount(BMap.BMFile_GetTextureCount);
|
||||||
public IEnumerable<BMTexture> GetTextures() =>
|
public IEnumerable<BMTexture> GetTextures() =>
|
||||||
GetCKObjects<BMTexture>(BMap.BMFile_GetTextureCount, BMap.BMFile_GetTexture, (bmf, id) => new BMTexture(bmf, id));
|
getCKObjects<BMTexture>(BMap.BMFile_GetTextureCount, BMap.BMFile_GetTexture, (bmf, id) => new BMTexture(bmf, id));
|
||||||
public uint GetMaterialCount() =>
|
public uint GetMaterialCount() =>
|
||||||
GetCKObjectCount(BMap.BMFile_GetMaterialCount);
|
getCKObjectCount(BMap.BMFile_GetMaterialCount);
|
||||||
public IEnumerable<BMMaterial> GetMaterials() =>
|
public IEnumerable<BMMaterial> GetMaterials() =>
|
||||||
GetCKObjects<BMMaterial>(BMap.BMFile_GetMaterialCount, BMap.BMFile_GetMaterial, (bmf, id) => new BMMaterial(bmf, id));
|
getCKObjects<BMMaterial>(BMap.BMFile_GetMaterialCount, BMap.BMFile_GetMaterial, (bmf, id) => new BMMaterial(bmf, id));
|
||||||
public uint GetMeshCount() =>
|
public uint GetMeshCount() =>
|
||||||
GetCKObjectCount(BMap.BMFile_GetMeshCount);
|
getCKObjectCount(BMap.BMFile_GetMeshCount);
|
||||||
public IEnumerable<BMMesh> GetMeshes() =>
|
public IEnumerable<BMMesh> GetMeshes() =>
|
||||||
GetCKObjects<BMMesh>(BMap.BMFile_GetMeshCount, BMap.BMFile_GetMesh, (bmf, id) => new BMMesh(bmf, id));
|
getCKObjects<BMMesh>(BMap.BMFile_GetMeshCount, BMap.BMFile_GetMesh, (bmf, id) => new BMMesh(bmf, id));
|
||||||
public uint Get3dObjectCount() =>
|
public uint Get3dObjectCount() =>
|
||||||
GetCKObjectCount(BMap.BMFile_Get3dObjectCount);
|
getCKObjectCount(BMap.BMFile_Get3dObjectCount);
|
||||||
public IEnumerable<BM3dObject> Get3dObjects() =>
|
public IEnumerable<BM3dObject> Get3dObjects() =>
|
||||||
GetCKObjects<BM3dObject>(BMap.BMFile_Get3dObjectCount, BMap.BMFile_Get3dObject, (bmf, id) => new BM3dObject(bmf, id));
|
getCKObjects<BM3dObject>(BMap.BMFile_Get3dObjectCount, BMap.BMFile_Get3dObject, (bmf, id) => new BM3dObject(bmf, id));
|
||||||
public uint GetGroupCount() =>
|
public uint GetGroupCount() =>
|
||||||
GetCKObjectCount(BMap.BMFile_GetGroupCount);
|
getCKObjectCount(BMap.BMFile_GetGroupCount);
|
||||||
public IEnumerable<BMGroup> GetGroups() =>
|
public IEnumerable<BMGroup> GetGroups() =>
|
||||||
GetCKObjects<BMGroup>(BMap.BMFile_GetGroupCount, BMap.BMFile_GetGroup, (bmf, id) => new BMGroup(bmf, id));
|
getCKObjects<BMGroup>(BMap.BMFile_GetGroupCount, BMap.BMFile_GetGroup, (bmf, id) => new BMGroup(bmf, id));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public 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;
|
||||||
|
}
|
||||||
|
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)) { }
|
||||||
|
|
||||||
|
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 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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user