feat: update BMapSharp code
This commit is contained in:
parent
2ce5203ac7
commit
334580acdc
|
@ -5,16 +5,19 @@ using BMapSharp.VirtoolsTypes;
|
||||||
|
|
||||||
namespace BMapSharp {
|
namespace BMapSharp {
|
||||||
|
|
||||||
public static class BMap {
|
/// <summary>BMapSharp module specific exception.</summary>
|
||||||
|
public class BMapException : Exception {
|
||||||
/// <summary>BMapSharp module specific exception.</summary>
|
public BMapException() {}
|
||||||
public class BMapException : Exception {
|
public BMapException(string message)
|
||||||
public BMapException() {}
|
: base(message) {}
|
||||||
public BMapException(string message)
|
public BMapException(string message, Exception inner)
|
||||||
: base(message) {}
|
: base(message, inner) {}
|
||||||
public BMapException(string message, Exception inner)
|
public static void ThrowIfFailed(bool condition) {
|
||||||
: base(message, inner) {}
|
if (!condition) throw new BMapException("BMap operation failed.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BMap {
|
||||||
|
|
||||||
/// <summary>The callback function of BMap.</summary>
|
/// <summary>The callback function of BMap.</summary>
|
||||||
/// <param name="msg">The message content need to be printed.</param>
|
/// <param name="msg">The message content need to be printed.</param>
|
||||||
|
|
|
@ -1,112 +1,266 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Reflection.Metadata.Ecma335;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using BMapSharp.VirtoolsTypes;
|
using BMapSharp.VirtoolsTypes;
|
||||||
|
|
||||||
namespace BMapSharp.BMapWrapper {
|
namespace BMapSharp.BMapWrapper {
|
||||||
|
|
||||||
public sealed class BMapGuard : IDisposable {
|
/// <summary>
|
||||||
internal BMapGuard() {
|
/// The guard of native BMap environment.
|
||||||
BMap.BMInit();
|
/// This class initialize native BMap environment when constructing and free it when destructing.
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class BMapGuard : SafeHandle {
|
||||||
|
private static readonly IntPtr MAGIC_HANDLE = (IntPtr)61;
|
||||||
|
internal BMapGuard() : base(Utils.INVALID_PTR, true) {
|
||||||
|
BMapException.ThrowIfFailed(BMap.BMInit());
|
||||||
|
this.handle = MAGIC_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
public override bool IsInvalid => this.handle == Utils.INVALID_PTR;
|
||||||
throw new NotImplementedException();
|
protected override bool ReleaseHandle() {
|
||||||
}
|
return BMap.BMDispose();
|
||||||
|
|
||||||
public bool IsBMapAvailable() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Utilities {
|
public static class Utils {
|
||||||
public static readonly BMapGuard Guard = new BMapGuard();
|
/// <summary>The representation of invalid raw pointer.</summary>
|
||||||
|
|
||||||
internal static readonly IntPtr INVALID_PTR = IntPtr.Zero;
|
internal static readonly IntPtr INVALID_PTR = IntPtr.Zero;
|
||||||
|
/// <summary>The representation of invalid CK_ID.</summary>
|
||||||
internal static readonly uint INVALID_CKID = 0u;
|
internal static readonly uint INVALID_CKID = 0u;
|
||||||
|
/// <summary>
|
||||||
|
/// The function used as callback for BMap.
|
||||||
|
/// It just writes the data in console.
|
||||||
|
/// </summary>
|
||||||
internal static void BMapSharpCallback(string msg) {
|
internal static void BMapSharpCallback(string msg) {
|
||||||
Console.WriteLine(msg);
|
Console.WriteLine(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly BMapGuard Singleton = new BMapGuard();
|
||||||
|
public static bool IsBMapAvailable() {
|
||||||
|
return !Singleton.IsInvalid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class AbstractPointer : IComparable<AbstractPointer>, IEquatable<AbstractPointer> {
|
public abstract class AbstractPointer : SafeHandle {
|
||||||
private IntPtr mRawPointer;
|
internal AbstractPointer(IntPtr raw_pointer) : base(Utils.INVALID_PTR, true) {
|
||||||
|
this.handle = raw_pointer;
|
||||||
protected AbstractPointer(IntPtr raw_pointer) {
|
|
||||||
mRawPointer = raw_pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool IsValid() => mRawPointer != Utilities.INVALID_PTR;
|
public override bool IsInvalid => this.handle == Utils.INVALID_PTR;
|
||||||
protected IntPtr GetPointer() => mRawPointer;
|
protected override bool ReleaseHandle() => throw new NotImplementedException();
|
||||||
protected void SetPointer(IntPtr raw_pointer) => mRawPointer = raw_pointer;
|
|
||||||
|
|
||||||
#region IComparable
|
protected bool isValid() => this.handle != Utils.INVALID_PTR;
|
||||||
|
protected IntPtr getPointer() => this.handle;
|
||||||
|
|
||||||
public int CompareTo(AbstractPointer other) {
|
// protected AbstractPointer(IntPtr raw_pointer) : base(raw_pointer, true) {}
|
||||||
return mRawPointer.CompareTo(other.mRawPointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
// protected IntPtr GetPointer() => this.handle;
|
||||||
|
// public override bool IsInvalid { get { return this.handle == Utils.INVALID_PTR; } }
|
||||||
|
|
||||||
#region IEquatable
|
// #region IComparable
|
||||||
|
|
||||||
public static bool operator ==(AbstractPointer left, AbstractPointer right) => left.mRawPointer == right.mRawPointer;
|
// public int CompareTo(AbstractPointer other) {
|
||||||
public static bool operator !=(AbstractPointer left, AbstractPointer right) => left.mRawPointer != right.mRawPointer;
|
// return m_RawPointer.CompareTo(other.m_RawPointer);
|
||||||
|
// }
|
||||||
|
|
||||||
public bool Equals(AbstractPointer other) => this == other;
|
// #endregion
|
||||||
public override bool Equals(object obj) {
|
|
||||||
return (!(obj is null)) && (obj is AbstractPointer) && this.Equals((AbstractPointer)obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
// #region IEquatable
|
||||||
|
|
||||||
|
// public override bool Equals(object obj) => this.Equals(obj as AbstractPointer);
|
||||||
|
// public bool Equals(AbstractPointer other) {
|
||||||
|
// if (other is null) return false;
|
||||||
|
// if (Object.ReferenceEquals(this, other)) return true;
|
||||||
|
// // if (this.GetType() != other.GetType()) return false;
|
||||||
|
// return this.m_RawPointer == other.m_RawPointer;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static bool operator ==(AbstractPointer lhs, AbstractPointer rhs) {
|
||||||
|
// if (lhs is null) {
|
||||||
|
// if (rhs is null) return true;
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// return lhs.Equals(rhs);
|
||||||
|
// }
|
||||||
|
// public static bool operator !=(AbstractPointer lhs, AbstractPointer rhs) => !(lhs == rhs);
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
#region Misc
|
#region Misc
|
||||||
|
|
||||||
public override int GetHashCode() => mRawPointer.GetHashCode();
|
public override int GetHashCode() => this.handle.GetHashCode();
|
||||||
public override string ToString() => mRawPointer.ToString();
|
public override string ToString() => this.handle.ToString();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class AbstractCKObject : AbstractPointer, IComparable<AbstractCKObject>, IEquatable<AbstractCKObject> {
|
public abstract class AbstractCKObject {
|
||||||
private uint mCKID;
|
internal AbstractCKObject(IntPtr raw_pointer, uint ckid) {
|
||||||
|
m_RawPointer = raw_pointer;
|
||||||
protected AbstractCKObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer) {
|
m_CKID = ckid;
|
||||||
mCKID = ckid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool IsValid() => base.IsValid() && mCKID != Utilities.INVALID_CKID;
|
private readonly IntPtr m_RawPointer;
|
||||||
protected uint GetCKID() => mCKID;
|
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;
|
||||||
|
|
||||||
#region IComparable
|
// private uint m_CKID;
|
||||||
|
|
||||||
public int CompareTo(AbstractCKObject other) {
|
// protected AbstractCKObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer) {
|
||||||
var ret = base.CompareTo((AbstractPointer)other);
|
// m_CKID = ckid;
|
||||||
if (ret != 0) return ret;
|
// }
|
||||||
return mCKID.CompareTo(other.mCKID);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
// protected override bool IsValid() => base.IsValid() && m_CKID != Utils.INVALID_CKID;
|
||||||
|
// protected uint GetCKID() => m_CKID;
|
||||||
|
|
||||||
#region IEquatable
|
// #region IComparable
|
||||||
|
|
||||||
public static bool operator ==(AbstractCKObject left, AbstractCKObject right) =>
|
// public int CompareTo(AbstractCKObject other) {
|
||||||
((AbstractPointer)left == (AbstractPointer)right) && left.mCKID == right.mCKID;
|
// var ret = base.CompareTo((AbstractPointer)other);
|
||||||
public static bool operator !=(AbstractCKObject left, AbstractCKObject right) =>
|
// if (ret != 0) return ret;
|
||||||
((AbstractPointer)left != (AbstractPointer)right) || left.mCKID != right.mCKID;
|
// return m_CKID.CompareTo(other.m_CKID);
|
||||||
|
// }
|
||||||
|
|
||||||
public bool Equals(AbstractCKObject other) => this == other;
|
// #endregion
|
||||||
public override bool Equals(object obj) {
|
|
||||||
return (!(obj is null)) && (obj is AbstractCKObject) && this.Equals((AbstractCKObject)obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
// #region IEquatable
|
||||||
|
|
||||||
|
// public override bool Equals(object obj) => this.Equals(obj as AbstractCKObject);
|
||||||
|
// public bool Equals(AbstractCKObject other) {
|
||||||
|
// if (other is null) return false;
|
||||||
|
// if (Object.ReferenceEquals(this, other)) return true;
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static bool operator ==(AbstractCKObject left, AbstractCKObject right) =>
|
||||||
|
// ((AbstractPointer)left == (AbstractPointer)right) && left.m_CKID == right.m_CKID;
|
||||||
|
// public static bool operator !=(AbstractCKObject left, AbstractCKObject right) =>
|
||||||
|
// ((AbstractPointer)left != (AbstractPointer)right) || left.m_CKID != right.m_CKID;
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
#region Misc
|
#region Misc
|
||||||
|
|
||||||
public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), mCKID);
|
public override int GetHashCode() => HashCode.Combine(m_RawPointer, m_CKID);
|
||||||
public override string ToString() => $"{base.ToString()} {mCKID.ToString()}";
|
public override string ToString() => $"{m_RawPointer}, {m_CKID}";
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BMObject : AbstractCKObject {
|
||||||
|
internal BMObject(nint 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 class BMTexture : BMObject {
|
||||||
|
internal BMTexture(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BMMaterial : BMObject {
|
||||||
|
internal BMMaterial(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BMMesh : BMObject {
|
||||||
|
internal BMMesh(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BM3dObject : BMObject {
|
||||||
|
internal BM3dObject(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BMGroup : BMObject {
|
||||||
|
internal BMGroup(nint raw_pointer, uint ckid) : base(raw_pointer, ckid) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class BMFileReader : AbstractPointer {
|
||||||
|
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,
|
||||||
|
(uint)encodings.Length, encodings,
|
||||||
|
out IntPtr out_file
|
||||||
|
));
|
||||||
|
return out_file;
|
||||||
|
}
|
||||||
|
protected override bool ReleaseHandle() {
|
||||||
|
return BMap.BMFile_Free(this.handle);
|
||||||
|
}
|
||||||
|
public BMFileReader(string file_name, string temp_folder, string texture_folder, string[] encodings)
|
||||||
|
: base(AllocateHandle(file_name, temp_folder, texture_folder, encodings)) {}
|
||||||
|
|
||||||
|
public uint GetTextureCount() {
|
||||||
|
BMapException.ThrowIfFailed(BMap.BMFile_GetTextureCount(this.getPointer(), out uint out_count));
|
||||||
|
return out_count;
|
||||||
|
}
|
||||||
|
public IEnumerable<BMTexture> GetTextures() {
|
||||||
|
uint count = GetTextureCount();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint GetMaterialCount() {
|
||||||
|
BMapException.ThrowIfFailed(BMap.BMFile_GetMaterialCount(this.getPointer(), out uint out_count));
|
||||||
|
return out_count;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint GetMeshCount() {
|
||||||
|
BMapException.ThrowIfFailed(BMap.BMFile_GetMeshCount(this.getPointer(), out uint out_count));
|
||||||
|
return out_count;
|
||||||
|
}
|
||||||
|
public IEnumerable<BMMesh> GetMeshs() {
|
||||||
|
uint count = GetMeshCount();
|
||||||
|
for (uint i = 0; i < count; ++i) {
|
||||||
|
BMapException.ThrowIfFailed(BMap.BMFile_GetMesh(this.getPointer(), i, out uint out_id));
|
||||||
|
yield return new BMMesh(this.getPointer(), out_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Get3dObjectCount() {
|
||||||
|
BMapException.ThrowIfFailed(BMap.BMFile_Get3dObjectCount(this.getPointer(), out uint out_count));
|
||||||
|
return out_count;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint GetGroupCount() {
|
||||||
|
BMapException.ThrowIfFailed(BMap.BMFile_GetGroupCount(this.getPointer(), out uint out_count));
|
||||||
|
return out_count;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user