feat: update BMap bindings

- add testbench file in BMap bindings.
- reorganise BMap bindings code.
- write some BMapSharp binding code.
This commit is contained in:
yyc12345 2024-10-02 13:33:32 +08:00
parent 5e5eed03f5
commit 2ce5203ac7
15 changed files with 871 additions and 123 deletions

View File

@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BMapSharp", "BMapSharp\BMapSharp.csproj", "{604F426A-EC91-4E17-BE58-74565B24946C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BMapSharpTestbench", "BMapSharpTestbench\BMapSharpTestbench.csproj", "{3490D77F-119B-48EF-AA0B-E715EBE80DAA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{604F426A-EC91-4E17-BE58-74565B24946C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{604F426A-EC91-4E17-BE58-74565B24946C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{604F426A-EC91-4E17-BE58-74565B24946C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{604F426A-EC91-4E17-BE58-74565B24946C}.Release|Any CPU.Build.0 = Release|Any CPU
{3490D77F-119B-48EF-AA0B-E715EBE80DAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3490D77F-119B-48EF-AA0B-E715EBE80DAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3490D77F-119B-48EF-AA0B-E715EBE80DAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3490D77F-119B-48EF-AA0B-E715EBE80DAA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -7,6 +7,15 @@ namespace BMapSharp {
public static class BMap {
/// <summary>BMapSharp module specific exception.</summary>
public class BMapException : Exception {
public BMapException() {}
public BMapException(string message)
: base(message) {}
public BMapException(string message, Exception inner)
: base(message, inner) {}
}
/// <summary>The callback function of BMap.</summary>
/// <param name="msg">The message content need to be printed.</param>
public delegate void OutputCallback([In, MarshalAs(UnmanagedType.LPUTF8Str)] string msg);
@ -20,12 +29,9 @@ namespace BMapSharp {
// NOTE: I do not create a member to store the object we are marshaling.
// Because my binding do not have In, Out parameter. All parameters are In OR Out.
// So there is no reason to keep that member.
private static BMStringArrayMarshaler g_Instance;
public static ICustomMarshaler GetInstance(string pstrCookie) {
if (g_Instance is null) g_Instance = new BMStringArrayMarshaler();
return g_Instance;
}
private static readonly BMStringArrayMarshaler g_Instance = new BMStringArrayMarshaler();
public static ICustomMarshaler GetInstance(string pstrCookie) => g_Instance;
// For respecting the standard of BMap,
// the native memory we created is a simple array and each item is a pointer to a NULL-terminated UTF8 string.
@ -114,7 +120,7 @@ namespace BMapSharp {
// Decode string with UTF8
ret[i] = Encoding.UTF8.GetString(encString);
}
// Return result
return ret;
}
@ -151,6 +157,7 @@ namespace BMapSharp {
}
public int GetNativeDataSize() {
// Return -1 to indicate the managed type this marshaler handles is not a value type.
return -1;
}

View File

@ -0,0 +1,112 @@
using System;
using System.Runtime.InteropServices;
using BMapSharp.VirtoolsTypes;
namespace BMapSharp.BMapWrapper {
public sealed class BMapGuard : IDisposable {
internal BMapGuard() {
BMap.BMInit();
}
public void Dispose() {
throw new NotImplementedException();
}
public bool IsBMapAvailable() {
}
}
public static class Utilities {
public static readonly BMapGuard Guard = new BMapGuard();
internal static readonly IntPtr INVALID_PTR = IntPtr.Zero;
internal static readonly uint INVALID_CKID = 0u;
internal static void BMapSharpCallback(string msg) {
Console.WriteLine(msg);
}
}
public abstract class AbstractPointer : IComparable<AbstractPointer>, IEquatable<AbstractPointer> {
private IntPtr mRawPointer;
protected AbstractPointer(IntPtr raw_pointer) {
mRawPointer = raw_pointer;
}
protected virtual bool IsValid() => mRawPointer != Utilities.INVALID_PTR;
protected IntPtr GetPointer() => mRawPointer;
protected void SetPointer(IntPtr raw_pointer) => mRawPointer = raw_pointer;
#region IComparable
public int CompareTo(AbstractPointer other) {
return mRawPointer.CompareTo(other.mRawPointer);
}
#endregion
#region IEquatable
public static bool operator ==(AbstractPointer left, AbstractPointer right) => left.mRawPointer == right.mRawPointer;
public static bool operator !=(AbstractPointer left, AbstractPointer right) => left.mRawPointer != right.mRawPointer;
public bool Equals(AbstractPointer other) => this == other;
public override bool Equals(object obj) {
return (!(obj is null)) && (obj is AbstractPointer) && this.Equals((AbstractPointer)obj);
}
#endregion
#region Misc
public override int GetHashCode() => mRawPointer.GetHashCode();
public override string ToString() => mRawPointer.ToString();
#endregion
}
public abstract class AbstractCKObject : AbstractPointer, IComparable<AbstractCKObject>, IEquatable<AbstractCKObject> {
private uint mCKID;
protected AbstractCKObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer) {
mCKID = ckid;
}
protected override bool IsValid() => base.IsValid() && mCKID != Utilities.INVALID_CKID;
protected uint GetCKID() => mCKID;
#region IComparable
public int CompareTo(AbstractCKObject other) {
var ret = base.CompareTo((AbstractPointer)other);
if (ret != 0) return ret;
return mCKID.CompareTo(other.mCKID);
}
#endregion
#region IEquatable
public static bool operator ==(AbstractCKObject left, AbstractCKObject right) =>
((AbstractPointer)left == (AbstractPointer)right) && left.mCKID == right.mCKID;
public static bool operator !=(AbstractCKObject left, AbstractCKObject right) =>
((AbstractPointer)left != (AbstractPointer)right) || left.mCKID != right.mCKID;
public bool Equals(AbstractCKObject other) => this == other;
public override bool Equals(object obj) {
return (!(obj is null)) && (obj is AbstractCKObject) && this.Equals((AbstractCKObject)obj);
}
#endregion
#region Misc
public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), mCKID);
public override string ToString() => $"{base.ToString()} {mCKID.ToString()}";
#endregion
}
}

View File

@ -0,0 +1,287 @@
using System;
using System.Runtime.InteropServices;
using System.Numerics;
namespace BMapSharp.VirtoolsTypes {
// NOTE: Structures defined in there is only served for marshaling.
// You should not use them in hash set or anything else,
// because they do not have proper hash function and compare function.
// You should use the managed type generated by them instead.
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct VxVector2 {
[MarshalAs(UnmanagedType.R4)]
public float X, Y;
public VxVector2(float _x = 0.0f, float _y = 0.0f) {
X = _x;
Y = _y;
}
public void FromManaged(Vector2 vec) {
X = vec.X;
Y = vec.Y;
}
public Vector2 ToManaged() {
return new Vector2(X, Y);
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct VxVector3 {
[MarshalAs(UnmanagedType.R4)]
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;
}
public void FromManaged(Vector3 vec) {
X = vec.X;
Y = vec.Y;
Z = vec.Z;
}
public Vector3 ToManaged() {
return new Vector3(X, Y, Z);
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct VxColor {
[MarshalAs(UnmanagedType.R4)]
public float A, R, G, B;
public VxColor(float _r, float _g, float _b, float _a) {
A = _a;
R = _r;
G = _g;
B = _b;
Regulate();
}
public void FromManagedRGBA(Vector4 col) {
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;
Regulate();
}
public Vector3 ToManagedRGB() {
return new Vector3(R, G, B);
}
public void FromDword(uint val) {
B = (val & 0xFFu) / 255.0f;
val >>= 8;
G = (val & 0xFFu) / 255.0f;
val >>= 8;
R = (val & 0xFFu) / 255.0f;
val >>= 8;
A = (val & 0xFFu) / 255.0f;
}
public uint ToDword() {
// regulate self first
Regulate();
// build result
uint val = 0u;
val |= (uint)(A * 255.0f);
val <<= 8;
val |= (uint)(R * 255.0f);
val <<= 8;
val |= (uint)(G * 255.0f);
val <<= 8;
val |= (uint)(B * 255.0f);
return val;
}
public static float ClampFactor(float factor) {
return System.Math.Clamp(factor, 0.0f, 1.0f);
}
public void Regulate() {
A = ClampFactor(A);
R = ClampFactor(R);
G = ClampFactor(G);
B = ClampFactor(B);
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct VxMatrix {
[MarshalAs(UnmanagedType.R4)]
public float M11, M12, M13, M14;
[MarshalAs(UnmanagedType.R4)]
public float M21, M22, M23, M24;
[MarshalAs(UnmanagedType.R4)]
public float M31, M32, M33, M34;
[MarshalAs(UnmanagedType.R4)]
public float M41, M42, M43, M44;
public VxMatrix(float m11 = 1.0f, float m12 = 0.0f, float m13 = 0.0f, float m14 = 0.0f,
float m21 = 0.0f, float m22 = 1.0f, float m23 = 0.0f, float m24 = 0.0f,
float m31 = 0.0f, float m32 = 0.0f, float m33 = 1.0f, float m34 = 0.0f,
float m41 = 0.0f, float m42 = 0.0f, float m43 = 0.0f, float m44 = 1.0f) {
M11 = m11; M12 = m12; M13 = m13; M14 = m14;
M21 = m21; M22 = m22; M23 = m23; M24 = m24;
M31 = m31; M32 = m32; M33 = m33; M34 = m34;
M41 = m41; M42 = m42; M43 = m43; M44 = m44;
}
public void Reset() {
M11 = 1.0f; M12 = 0.0f; M13 = 0.0f; M14 = 0.0f;
M21 = 0.0f; M22 = 1.0f; M23 = 0.0f; M24 = 0.0f;
M31 = 0.0f; M32 = 0.0f; M33 = 1.0f; M34 = 0.0f;
M41 = 0.0f; M42 = 0.0f; M43 = 0.0f; M44 = 1.0f;
}
public void FromManaged(Matrix4x4 mat) {
M11 = mat.M11; M12 = mat.M12; M13 = mat.M13; M14 = mat.M14;
M21 = mat.M21; M22 = mat.M22; M23 = mat.M23; M24 = mat.M24;
M31 = mat.M31; M32 = mat.M32; M33 = mat.M33; M34 = mat.M34;
M41 = mat.M41; M42 = mat.M42; M43 = mat.M43; M44 = mat.M44;
}
public Matrix4x4 ToManaged() {
return new Matrix4x4(
M11, M12, M13, M14,
M21, M22, M23, M24,
M31, M32, M33, M34,
M41, M42, M43, M44
);
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct CKFaceIndices {
[MarshalAs(UnmanagedType.U4)]
public uint I1, I2, I3;
public CKFaceIndices(uint i1 = 0u, uint i2 = 0u, uint i3 = 0u) {
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. */
CKTEXTURE_IMAGEFORMAT = 2, /**< Save using format specified. The bitmap data will be converted to the specified format by the correspondant bitmap plugin and saved inside file. */
CKTEXTURE_USEGLOBAL = 3, /**< Use Global settings, that is the settings given with CKContext::SetGlobalImagesSaveOptions. (Not valid when using CKContext::SetImagesSaveOptions). */
CKTEXTURE_INCLUDEORIGINALFILE = 4, /**< Insert original image file inside CMO file. The bitmap file that was used originally for the texture or sprite will be append to the composition file and extracted when the file is loaded. */
}
public enum VX_PIXELFORMAT : uint {
UNKNOWN_PF = 0, /**< Unknown pixel format */
_32_ARGB8888 = 1, /**< 32-bit ARGB pixel format with alpha */
_32_RGB888 = 2, /**< 32-bit RGB pixel format without alpha */
_24_RGB888 = 3, /**< 24-bit RGB pixel format */
_16_RGB565 = 4, /**< 16-bit RGB pixel format */
_16_RGB555 = 5, /**< 16-bit RGB pixel format (5 bits per color) */
_16_ARGB1555 = 6, /**< 16-bit ARGB pixel format (5 bits per color + 1 bit for alpha) */
_16_ARGB4444 = 7, /**< 16-bit ARGB pixel format (4 bits per color) */
_8_RGB332 = 8, /**< 8-bit RGB pixel format */
_8_ARGB2222 = 9, /**< 8-bit ARGB pixel format */
_32_ABGR8888 = 10, /**< 32-bit ABGR pixel format */
_32_RGBA8888 = 11, /**< 32-bit RGBA pixel format */
_32_BGRA8888 = 12, /**< 32-bit BGRA pixel format */
_32_BGR888 = 13, /**< 32-bit BGR pixel format */
_24_BGR888 = 14, /**< 24-bit BGR pixel format */
_16_BGR565 = 15, /**< 16-bit BGR pixel format */
_16_BGR555 = 16, /**< 16-bit BGR pixel format (5 bits per color) */
_16_ABGR1555 = 17, /**< 16-bit ABGR pixel format (5 bits per color + 1 bit for alpha) */
_16_ABGR4444 = 18, /**< 16-bit ABGR pixel format (4 bits per color) */
_DXT1 = 19, /**< S3/DirectX Texture Compression 1 */
_DXT2 = 20, /**< S3/DirectX Texture Compression 2 */
_DXT3 = 21, /**< S3/DirectX Texture Compression 3 */
_DXT4 = 22, /**< S3/DirectX Texture Compression 4 */
_DXT5 = 23, /**< S3/DirectX Texture Compression 5 */
_16_V8U8 = 24, /**< 16-bit Bump Map format format (8 bits per color) */
_32_V16U16 = 25, /**< 32-bit Bump Map format format (16 bits per color) */
_16_L6V5U5 = 26, /**< 16-bit Bump Map format format with luminance */
_32_X8L8V8U8 = 27, /**< 32-bit Bump Map format format with luminance */
_8_ABGR8888_CLUT = 28, /**< 8 bits indexed CLUT (ABGR) */
_8_ARGB8888_CLUT = 29, /**< 8 bits indexed CLUT (ARGB) */
_4_ABGR8888_CLUT = 30, /**< 4 bits indexed CLUT (ABGR) */
_4_ARGB8888_CLUT = 31, /**< 4 bits indexed CLUT (ARGB) */
}
public enum VXTEXTURE_BLENDMODE : uint {
VXTEXTUREBLEND_DECAL = 1, /**< Texture replace any material information */
VXTEXTUREBLEND_MODULATE = 2, /**< Texture and material are combine. Alpha information of the texture replace material alpha component. */
VXTEXTUREBLEND_DECALALPHA = 3, /**< Alpha information in the texture specify how material and texture are combined. Alpha information of the texture replace material alpha component. */
VXTEXTUREBLEND_MODULATEALPHA = 4, /**< Alpha information in the texture specify how material and texture are combined */
VXTEXTUREBLEND_DECALMASK = 5,
VXTEXTUREBLEND_MODULATEMASK = 6,
VXTEXTUREBLEND_COPY = 7, /**< Equivalent to DECAL */
VXTEXTUREBLEND_ADD = 8,
VXTEXTUREBLEND_DOTPRODUCT3 = 9, /**< Perform a Dot Product 3 between texture (normal map) and a referential vector given in VXRENDERSTATE_TEXTUREFACTOR. */
VXTEXTUREBLEND_MAX = 10,
}
public enum VXTEXTURE_FILTERMODE : uint {
VXTEXTUREFILTER_NEAREST = 1, /**< No Filter */
VXTEXTUREFILTER_LINEAR = 2, /**< Bilinear Interpolation */
VXTEXTUREFILTER_MIPNEAREST = 3, /**< Mip mapping */
VXTEXTUREFILTER_MIPLINEAR = 4, /**< Mip Mapping with Bilinear interpolation */
VXTEXTUREFILTER_LINEARMIPNEAREST = 5, /**< Mip Mapping with Bilinear interpolation between mipmap levels. */
VXTEXTUREFILTER_LINEARMIPLINEAR = 6, /**< Trilinear Filtering */
VXTEXTUREFILTER_ANISOTROPIC = 7, /**< Anisotropic filtering */
}
public enum VXTEXTURE_ADDRESSMODE : uint {
VXTEXTURE_ADDRESSWRAP = 1, /**< Default mesh wrap mode is used (see CKMesh::SetWrapMode) */
VXTEXTURE_ADDRESSMIRROR = 2, /**< Texture coordinates outside the range [0..1] are flipped evenly. */
VXTEXTURE_ADDRESSCLAMP = 3, /**< Texture coordinates greater than 1.0 are set to 1.0, and values less than 0.0 are set to 0.0. */
VXTEXTURE_ADDRESSBORDER = 4, /**< When texture coordinates are greater than 1.0 or less than 0.0 texture is set to a color defined in CKMaterial::SetTextureBorderColor. */
VXTEXTURE_ADDRESSMIRRORONCE = 5, /**< */
}
public enum VXBLEND_MODE : uint {
VXBLEND_ZERO = 1, /**< Blend factor is (0, 0, 0, 0). */
VXBLEND_ONE = 2, /**< Blend factor is (1, 1, 1, 1). */
VXBLEND_SRCCOLOR = 3, /**< Blend factor is (Rs, Gs, Bs, As). */
VXBLEND_INVSRCCOLOR = 4, /**< Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As). */
VXBLEND_SRCALPHA = 5, /**< Blend factor is (As, As, As, As). */
VXBLEND_INVSRCALPHA = 6, /**< Blend factor is (1-As, 1-As, 1-As, 1-As). */
VXBLEND_DESTALPHA = 7, /**< Blend factor is (Ad, Ad, Ad, Ad). */
VXBLEND_INVDESTALPHA = 8, /**< Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad). */
VXBLEND_DESTCOLOR = 9, /**< Blend factor is (Rd, Gd, Bd, Ad). */
VXBLEND_INVDESTCOLOR = 10, /**< Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad). */
VXBLEND_SRCALPHASAT = 11, /**< Blend factor is (f, f, f, 1); f = min(As, 1-Ad). */
// VXBLEND_BOTHSRCALPHA = 12, /**< Source blend factor is (As, As, As, As) and destination blend factor is (1-As, 1-As, 1-As, 1-As) */
// VXBLEND_BOTHINVSRCALPHA = 13, /**< Source blend factor is (1-As, 1-As, 1-As, 1-As) and destination blend factor is (As, As, As, As) */
}
public enum VXFILL_MODE : uint {
VXFILL_POINT = 1, /**< Vertices rendering */
VXFILL_WIREFRAME = 2, /**< Edges rendering */
VXFILL_SOLID = 3, /**< Face rendering */
}
public enum VXSHADE_MODE : uint {
VXSHADE_FLAT = 1, /**< Flat Shading */
VXSHADE_GOURAUD = 2, /**< Gouraud Shading */
VXSHADE_PHONG = 3, /**< Phong Shading (Not yet supported by most implementation) */
}
public enum VXCMPFUNC : uint {
VXCMP_NEVER = 1, /**< Always fail the test. */
VXCMP_LESS = 2, /**< Accept if value if less than current value. */
VXCMP_EQUAL = 3, /**< Accept if value if equal than current value. */
VXCMP_LESSEQUAL = 4, /**< Accept if value if less or equal than current value. */
VXCMP_GREATER = 5, /**< Accept if value if greater than current value. */
VXCMP_NOTEQUAL = 6, /**< Accept if value if different than current value. */
VXCMP_GREATEREQUAL = 7, /**< Accept if value if greater or equal current value. */
VXCMP_ALWAYS = 8, /**< Always accept the test. */
}
public enum VXMESH_LITMODE : uint {
VX_PRELITMESH = 0, /**< Lighting use color information store with vertices */
VX_LITMESH = 1, /**< Lighting is done by renderer using normals and face material information. */
}
}

View File

@ -0,0 +1,364 @@
root = true
# All files
[*]
indent_style = space
# Xml files
[*.xml]
indent_size = 2
# C# files
[*.cs]
#### Core EditorConfig Options ####
# Indentation and spacing
indent_size = 4
tab_width = 4
# New line preferences
end_of_line = crlf
insert_final_newline = false
#### .NET Coding Conventions ####
[*.{cs,vb}]
# Organize usings
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
file_header_template = unset
# this. and Me. preferences
dotnet_style_qualification_for_event = false:silent
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_property = false:silent
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
# Expression-level preferences
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_object_initializer = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
# Field preferences
dotnet_style_readonly_field = true:warning
# Parameter preferences
dotnet_code_quality_unused_parameters = all:suggestion
# Suppression preferences
dotnet_remove_unnecessary_suppression_exclusions = none
#### C# Coding Conventions ####
[*.cs]
# var preferences
csharp_style_var_elsewhere = false:silent
csharp_style_var_for_built_in_types = false:silent
csharp_style_var_when_type_is_apparent = false:silent
# Expression-bodied members
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_lambdas = true:suggestion
csharp_style_expression_bodied_local_functions = false:silent
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
# Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_prefer_not_pattern = true:suggestion
csharp_style_prefer_pattern_matching = true:silent
csharp_style_prefer_switch_expression = true:suggestion
# Null-checking preferences
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_prefer_static_local_function = true:warning
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
# Code-block preferences
csharp_prefer_braces = true:silent
csharp_prefer_simple_using_statement = true:suggestion
# Expression-level preferences
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_prefer_index_operator = true:suggestion
csharp_style_prefer_range_operator = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:silent
#### C# Formatting Rules ####
# New line preferences
csharp_new_line_before_catch = false
csharp_new_line_before_else = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
#### Naming styles ####
[*.{cs,vb}]
# Naming rules
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.symbols = types_and_namespaces
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.interfaces_should_be_ipascalcase.severity = suggestion
dotnet_naming_rule.interfaces_should_be_ipascalcase.symbols = interfaces
dotnet_naming_rule.interfaces_should_be_ipascalcase.style = ipascalcase
dotnet_naming_rule.type_parameters_should_be_tpascalcase.severity = suggestion
dotnet_naming_rule.type_parameters_should_be_tpascalcase.symbols = type_parameters
dotnet_naming_rule.type_parameters_should_be_tpascalcase.style = tpascalcase
dotnet_naming_rule.methods_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.methods_should_be_pascalcase.symbols = methods
dotnet_naming_rule.methods_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.properties_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.properties_should_be_pascalcase.symbols = properties
dotnet_naming_rule.properties_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.events_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.events_should_be_pascalcase.symbols = events
dotnet_naming_rule.events_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.local_variables_should_be_camelcase.severity = suggestion
dotnet_naming_rule.local_variables_should_be_camelcase.symbols = local_variables
dotnet_naming_rule.local_variables_should_be_camelcase.style = camelcase
dotnet_naming_rule.local_constants_should_be_camelcase.severity = suggestion
dotnet_naming_rule.local_constants_should_be_camelcase.symbols = local_constants
dotnet_naming_rule.local_constants_should_be_camelcase.style = camelcase
dotnet_naming_rule.parameters_should_be_camelcase.severity = suggestion
dotnet_naming_rule.parameters_should_be_camelcase.symbols = parameters
dotnet_naming_rule.parameters_should_be_camelcase.style = camelcase
dotnet_naming_rule.public_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.public_fields_should_be_pascalcase.symbols = public_fields
dotnet_naming_rule.public_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.private_fields_should_be__camelcase.severity = suggestion
dotnet_naming_rule.private_fields_should_be__camelcase.symbols = private_fields
dotnet_naming_rule.private_fields_should_be__camelcase.style = _camelcase
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.severity = suggestion
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.symbols = private_static_fields
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = s_camelcase
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.symbols = public_constant_fields
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.symbols = private_constant_fields
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.symbols = public_static_readonly_fields
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.symbols = private_static_readonly_fields
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.enums_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.enums_should_be_pascalcase.symbols = enums
dotnet_naming_rule.enums_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.local_functions_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.local_functions_should_be_pascalcase.symbols = local_functions
dotnet_naming_rule.local_functions_should_be_pascalcase.style = pascalcase
dotnet_naming_rule.non_field_members_should_be_pascalcase.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascalcase.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase
# Symbol specifications
dotnet_naming_symbols.interfaces.applicable_kinds = interface
dotnet_naming_symbols.interfaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interfaces.required_modifiers =
dotnet_naming_symbols.enums.applicable_kinds = enum
dotnet_naming_symbols.enums.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.enums.required_modifiers =
dotnet_naming_symbols.events.applicable_kinds = event
dotnet_naming_symbols.events.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.events.required_modifiers =
dotnet_naming_symbols.methods.applicable_kinds = method
dotnet_naming_symbols.methods.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.methods.required_modifiers =
dotnet_naming_symbols.properties.applicable_kinds = property
dotnet_naming_symbols.properties.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.properties.required_modifiers =
dotnet_naming_symbols.public_fields.applicable_kinds = field
dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal
dotnet_naming_symbols.public_fields.required_modifiers =
dotnet_naming_symbols.private_fields.applicable_kinds = field
dotnet_naming_symbols.private_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
dotnet_naming_symbols.private_fields.required_modifiers =
dotnet_naming_symbols.private_static_fields.applicable_kinds = field
dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
dotnet_naming_symbols.private_static_fields.required_modifiers = static
dotnet_naming_symbols.types_and_namespaces.applicable_kinds = namespace, class, struct, interface, enum
dotnet_naming_symbols.types_and_namespaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types_and_namespaces.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
dotnet_naming_symbols.type_parameters.applicable_kinds = namespace
dotnet_naming_symbols.type_parameters.applicable_accessibilities = *
dotnet_naming_symbols.type_parameters.required_modifiers =
dotnet_naming_symbols.private_constant_fields.applicable_kinds = field
dotnet_naming_symbols.private_constant_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
dotnet_naming_symbols.private_constant_fields.required_modifiers = const
dotnet_naming_symbols.local_variables.applicable_kinds = local
dotnet_naming_symbols.local_variables.applicable_accessibilities = local
dotnet_naming_symbols.local_variables.required_modifiers =
dotnet_naming_symbols.local_constants.applicable_kinds = local
dotnet_naming_symbols.local_constants.applicable_accessibilities = local
dotnet_naming_symbols.local_constants.required_modifiers = const
dotnet_naming_symbols.parameters.applicable_kinds = parameter
dotnet_naming_symbols.parameters.applicable_accessibilities = *
dotnet_naming_symbols.parameters.required_modifiers =
dotnet_naming_symbols.public_constant_fields.applicable_kinds = field
dotnet_naming_symbols.public_constant_fields.applicable_accessibilities = public, internal
dotnet_naming_symbols.public_constant_fields.required_modifiers = const
dotnet_naming_symbols.public_static_readonly_fields.applicable_kinds = field
dotnet_naming_symbols.public_static_readonly_fields.applicable_accessibilities = public, internal
dotnet_naming_symbols.public_static_readonly_fields.required_modifiers = readonly, static
dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readonly, static
dotnet_naming_symbols.local_functions.applicable_kinds = local_function
dotnet_naming_symbols.local_functions.applicable_accessibilities = *
dotnet_naming_symbols.local_functions.required_modifiers =
# Naming styles
dotnet_naming_style.pascalcase.required_prefix =
dotnet_naming_style.pascalcase.required_suffix =
dotnet_naming_style.pascalcase.word_separator =
dotnet_naming_style.pascalcase.capitalization = pascal_case
dotnet_naming_style.ipascalcase.required_prefix = I
dotnet_naming_style.ipascalcase.required_suffix =
dotnet_naming_style.ipascalcase.word_separator =
dotnet_naming_style.ipascalcase.capitalization = pascal_case
dotnet_naming_style.tpascalcase.required_prefix = T
dotnet_naming_style.tpascalcase.required_suffix =
dotnet_naming_style.tpascalcase.word_separator =
dotnet_naming_style.tpascalcase.capitalization = pascal_case
dotnet_naming_style._camelcase.required_prefix = _
dotnet_naming_style._camelcase.required_suffix =
dotnet_naming_style._camelcase.word_separator =
dotnet_naming_style._camelcase.capitalization = camel_case
dotnet_naming_style.camelcase.required_prefix =
dotnet_naming_style.camelcase.required_suffix =
dotnet_naming_style.camelcase.word_separator =
dotnet_naming_style.camelcase.capitalization = camel_case
dotnet_naming_style.s_camelcase.required_prefix = s_
dotnet_naming_style.s_camelcase.required_suffix =
dotnet_naming_style.s_camelcase.word_separator =
dotnet_naming_style.s_camelcase.capitalization = camel_case

View File

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,12 @@
using System;
namespace BMapSharpTestbench // Note: actual namespace depends on the project name.
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

View File

@ -1,7 +0,0 @@
using System;
namespace BMapSharp.BMapWrapper {
}

View File

@ -0,0 +1,7 @@
# BMapSharp
The core of BMapSharp project is placed within `BMapSharp` subdirectory. This directory also contain a testbench project of `BMapSharp`, called `BMapSharpTestbench`. You can build it and do basic test for `BMapSharp`.
The native BMap library should be placed together with managed `BMapSharp` dynamic library. I use gitignore file to filter all native binary so you need put them manually. The native BMap library must be named as `BMap.dll` (in Windows), `BMap.so` (in Linux or BSD), or `BMap.dylib` (in macOS). If you still can not load BMap or your system is not listed above, you should name it as `BMap.bin`.
The most content of `VirtoolsTypes.cs` is generated by EnumsMigration, and the most content of `BMap.cs` is generated by BMapBindings. You should watch these file changes if corresponding C++ code or structures are changed.

View File

@ -1,104 +0,0 @@
using System;
using System.Runtime.InteropServices;
using System.Numerics;
namespace BMapSharp.VirtoolsTypes {
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct VxVector2 {
[MarshalAs(UnmanagedType.R4)]
public float X;
[MarshalAs(UnmanagedType.R4)]
public float Y;
public VxVector2(float _x = 0.0f, float _y = 0.0f) {
this.X = _x;
this.Y = _y;
}
public VxVector2(Vector2 vec) {
this.FromManaged(vec);
}
public void FromManaged(Vector2 vec) {
this.X = vec.X;
this.Y = vec.Y;
}
public Vector2 ToManaged() {
return new Vector2(this.X, this.Y);
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct VxVector3 {
[MarshalAs(UnmanagedType.R4)]
public float X;
[MarshalAs(UnmanagedType.R4)]
public float Y;
[MarshalAs(UnmanagedType.R4)]
public float Z;
public VxVector3(float _x = 0.0f, float _y = 0.0f, float _z = 0.0f) {
this.X = _x;
this.Y = _y;
this.Z = _z;
}
public VxVector3(Vector3 vec) {
this.FromManaged(vec);
}
public void FromManaged(Vector3 vec) {
this.X = vec.X;
this.Y = vec.Y;
this.Z = vec.Z;
}
public Vector3 ToManaged() {
return new Vector3(this.X, this.Y, this.Z);
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct VxColor {
[MarshalAs(UnmanagedType.R4)]
public float A;
[MarshalAs(UnmanagedType.R4)]
public float R;
[MarshalAs(UnmanagedType.R4)]
public float G;
[MarshalAs(UnmanagedType.R4)]
public float B;
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct VxVector4 {
[MarshalAs(UnmanagedType.R4)]
public float X;
[MarshalAs(UnmanagedType.R4)]
public float Y;
[MarshalAs(UnmanagedType.R4)]
public float Z;
[MarshalAs(UnmanagedType.R4)]
public float W;
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct VxMatrix {
public VxVector4 x;
public VxVector4 y;
public VxVector4 z;
public VxVector4 w;
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct CKFaceIndices {
[MarshalAs(UnmanagedType.U4)]
public uint I1;
[MarshalAs(UnmanagedType.U4)]
public uint I2;
[MarshalAs(UnmanagedType.U4)]
public uint I3;
public CKFaceIndices(uint i1 = 0u, uint i2 = 0u, uint i3 = 0u) {
this.I1 = i1;
this.I2 = i2;
this.I3 = i3;
}
}
}

View File

@ -9,9 +9,6 @@
*.dylib
*.bin
# Ignore testbench file.
testbench.py
# -------------------- Python --------------------
# Byte-compiled / optimized / DLL files
__pycache__/

View File

@ -1,7 +1,7 @@
# PyBMap
The real scripts are placed in sub PyBMap folder. This folder is served for testbench scripts placing. Place any testbench files (e.g. `testbench.py`) in there what you want and don't sumbit them (`testbench.py` is explicitly excluded by gitignore file).
The real scripts are placed in sub PyBMap folder. This folder is served for testbench scripts placing. You can run `testbench.py` to do a basic test for PyBMap but you may need some essential files to run this testbench which were written in `testbench.py`.
The native BMap library should be placed in sub PyBMap folder, and I have used gitignore file to filter them. The native BMap library must be named as `BMap.dll` (in Windows), `BMap.so` (in Linux or BSD), or `BMap.dylib` (in macOS). If you still can not load BMap or your system is not listed above, you should name it as `BMap.bin`.
Please note the most content of `virtools_types.py` are generated by EnumsMigration sub-project, so if some structs are updated, do not forget checking this file. Additionally the whole `bmap.py` is generated by BMapBindings, if something need to be changed, please modify the template of BMapBindings and do not midify the result directly.
Please note the most content of `virtools_types.py` are generated by EnumsMigration sub-project. Additionally the most content of `bmap.py` is generated by BMapBindings. So if some structs are updated, do not forget checking these files.

View File

@ -0,0 +1,35 @@
import os
import PyBMap.bmap_wrapper as bmap
def main() -> None:
input(f'Python PID is {os.getpid()}. Waiting for debugger, press any key to continue...')
file_name: str = 'Level_02.NMO'
temp_folder: str = 'Temp'
texture_folder: str = 'F:\\Ballance\\Ballance\\Textures'
encodings: tuple[str, ...] = ('cp1252', )
with bmap.BMFileReader(file_name, temp_folder, texture_folder, encodings) as reader:
print('===== Groups =====')
for gp in reader.get_groups():
print(gp.get_name())
print('===== Objects =====')
for obj in reader.get_3dobjects():
print(obj.get_name())
print('===== Meshes =====')
for mesh in reader.get_meshs():
print(mesh.get_name())
print('===== Materials =====')
for mtl in reader.get_materials():
print(mtl.get_name())
print('===== Textures =====')
for tex in reader.get_textures():
print(tex.get_name())
print('===== END =====')
if __name__ == '__main__':
main()