From 6ca492b204c205f0b6b09ebc4414637d14c5ccce Mon Sep 17 00:00:00 2001
From: Salvage <29021710+Saalvage@users.noreply.github.com>
Date: Tue, 10 Dec 2024 03:55:38 +0100
Subject: [PATCH] WIP work
---
AssimpNet/AssimpContext.cs | 41 ++++----
AssimpNet/AssimpNet.csproj | 2 +-
AssimpNet/Bone.cs | 2 +-
AssimpNet/ExportDataBlob.cs | 10 +-
AssimpNet/MemoryHelper.cs | 116 ++-------------------
AssimpNet/Scene.cs | 4 +-
AssimpNet/Unmanaged/UnmanagedStructures.cs | 14 +--
7 files changed, 49 insertions(+), 140 deletions(-)
diff --git a/AssimpNet/AssimpContext.cs b/AssimpNet/AssimpContext.cs
index d8ba7ed..8979bde 100755
--- a/AssimpNet/AssimpContext.cs
+++ b/AssimpNet/AssimpContext.cs
@@ -176,21 +176,27 @@ public Scene ImportFileFromStream(Stream stream, string formatHint = null)
/// The imported scene
/// Thrown if the stream is not valid (null or write-only).
/// Thrown if the context has already been disposed of.
- public Scene ImportFileFromStream(Stream stream, PostProcessSteps postProcessFlags, string formatHint = null)
+ public unsafe Scene ImportFileFromStream(Stream stream, PostProcessSteps postProcessFlags, string formatHint = null)
{
CheckDisposed();
if(stream == null || stream.CanRead != true)
throw new AssimpException(nameof(stream), "Can't read from the stream it's null or write-only");
- IntPtr ptr = IntPtr.Zero;
+ AiScene* ptr = null;
PrepareImport();
+ var bytes = MemoryHelper.ReadStreamFully(stream, 0);
+
try
{
- ptr = AssimpLibrary.Instance.ImportFileFromStream(stream, PostProcessSteps.None, formatHint, m_propStore);
+ fixed (byte* buffer = bytes)
+ {
+ ptr = AssimpLibrary.aiImportFileFromMemoryWithProperties(buffer, (uint)bytes.Length, PostProcessSteps.None,
+ formatHint, m_propStore);
+ }
- if(ptr == IntPtr.Zero)
+ if (ptr == null)
throw new AssimpException("Error importing file: " + AssimpLibrary.Instance.GetErrorString());
TransformScene(ptr);
@@ -203,9 +209,9 @@ public Scene ImportFileFromStream(Stream stream, PostProcessSteps postProcessFla
{
CleanupImport();
- if(ptr != IntPtr.Zero)
+ if(ptr != null)
{
- AssimpLibrary.Instance.ReleaseImport(ptr);
+ AssimpLibrary.aiReleaseImport(ptr);
}
}
}
@@ -264,11 +270,11 @@ public unsafe Scene ImportFile(string file, PostProcessSteps postProcessFlags)
if(ptr == null)
throw new AssimpException("Error importing file: " + AssimpLibrary.Instance.GetErrorString());
- TransformScene(new(ptr));
+ TransformScene(ptr);
- ptr = (AiScene*)ApplyPostProcessing(new(ptr), postProcessFlags);
+ ptr = (AiScene*)ApplyPostProcessing(ptr, postProcessFlags);
- return Scene.FromUnmanagedScene(new(ptr));
+ return Scene.FromUnmanagedScene(ptr);
}
finally
{
@@ -276,7 +282,7 @@ public unsafe Scene ImportFile(string file, PostProcessSteps postProcessFlags)
if(ptr != null)
{
- AssimpLibrary.Instance.ReleaseImport(new(ptr));
+ AssimpLibrary.aiReleaseImport(ptr);
}
}
}
@@ -1013,7 +1019,7 @@ private void BuildMatrix()
}
//Transforms the root node of the scene and writes it back to the native structure
- private bool TransformScene(IntPtr scene)
+ private unsafe bool TransformScene(AiScene* scene)
{
BuildMatrix();
@@ -1021,11 +1027,10 @@ private bool TransformScene(IntPtr scene)
{
if(!m_scaleRot.IsIdentity)
{
- AiScene aiScene = MemoryHelper.MarshalStructure(scene);
- if(aiScene.RootNode == IntPtr.Zero)
+ if(scene->RootNode == IntPtr.Zero)
return false;
- IntPtr matrixPtr = aiScene.RootNode + MemoryHelper.SizeOf(); //Skip over Node Name
+ IntPtr matrixPtr = scene->RootNode + MemoryHelper.SizeOf(); //Skip over Node Name
Matrix4x4 matrix = MemoryHelper.Read(matrixPtr); //Get the root transform
matrix = matrix * m_scaleRot; //Transform
@@ -1044,14 +1049,14 @@ private bool TransformScene(IntPtr scene)
return false;
}
- private IntPtr ApplyPostProcessing(IntPtr scene, PostProcessSteps postProcessFlags)
+ private unsafe AiScene* ApplyPostProcessing(AiScene* scene, PostProcessSteps postProcessFlags)
{
- if(postProcessFlags == PostProcessSteps.None || scene == IntPtr.Zero)
+ if(postProcessFlags == PostProcessSteps.None || scene == null)
return scene;
- scene = AssimpLibrary.Instance.ApplyPostProcessing(scene, postProcessFlags);
+ scene = AssimpLibrary.aiApplyPostProcessing(scene, postProcessFlags);
- if(scene == IntPtr.Zero)
+ if(scene == null)
{
string error = AssimpLibrary.Instance.GetErrorString();
throw new AssimpException(error.Length == 0
diff --git a/AssimpNet/AssimpNet.csproj b/AssimpNet/AssimpNet.csproj
index e82def5..3cac855 100755
--- a/AssimpNet/AssimpNet.csproj
+++ b/AssimpNet/AssimpNet.csproj
@@ -10,7 +10,7 @@
true
Nicholas Woodfield, Salvage
- 5.4.3.0
+ 5.4.3.1
License.txt
Copyright © 2012-2020 Nicholas Woodfield, © 2024 Salvage
logo.png
diff --git a/AssimpNet/Bone.cs b/AssimpNet/Bone.cs
index 84d4d7b..ebe7ce3 100755
--- a/AssimpNet/Bone.cs
+++ b/AssimpNet/Bone.cs
@@ -154,7 +154,7 @@ public static void FreeNative(IntPtr nativeValue, bool freeNative)
int numWeights = MemoryHelper.Read(nativeValue + MemoryHelper.SizeOf());
IntPtr weightsPtr = nativeValue + MemoryHelper.SizeOf() + sizeof(uint);
- if(aiBone.NumWeights > 0 && aiBone.Weights != IntPtr.Zero)
+ if(aiBone.NumWeights > 0 && aiBone.Weights != null)
MemoryHelper.FreeMemory(aiBone.Weights);
if(freeNative)
diff --git a/AssimpNet/ExportDataBlob.cs b/AssimpNet/ExportDataBlob.cs
index 60f9c9b..03befb7 100755
--- a/AssimpNet/ExportDataBlob.cs
+++ b/AssimpNet/ExportDataBlob.cs
@@ -77,18 +77,18 @@ public sealed class ExportDataBlob
/// Creates a new ExportDataBlob.
///
/// Unmanaged structure.
- internal ExportDataBlob(ref AiExportDataBlob dataBlob)
+ internal unsafe ExportDataBlob(ref AiExportDataBlob dataBlob)
{
m_name = dataBlob.Name.GetString();
- if(dataBlob.Size.ToUInt32() > 0 && dataBlob.Data != IntPtr.Zero)
- m_data = MemoryHelper.FromNativeArray(dataBlob.Data, (int) dataBlob.Size.ToUInt32());
+ if(dataBlob.Size.ToUInt32() > 0 && dataBlob.Data != null)
+ m_data = MemoryHelper.FromNativeArray(dataBlob.Data, (int)dataBlob.Size.ToUInt32());
m_next = null;
- if(dataBlob.NextBlob != IntPtr.Zero)
+ if(dataBlob.NextBlob != null)
{
- AiExportDataBlob nextBlob = MemoryHelper.MarshalStructure(dataBlob.NextBlob);
+ AiExportDataBlob nextBlob = *dataBlob.NextBlob;
m_next = new ExportDataBlob(ref nextBlob);
}
}
diff --git a/AssimpNet/MemoryHelper.cs b/AssimpNet/MemoryHelper.cs
index 2acc67c..94de1a8 100755
--- a/AssimpNet/MemoryHelper.cs
+++ b/AssimpNet/MemoryHelper.cs
@@ -63,7 +63,7 @@ public static IntPtr ToNativeArray(IReadOnlyCollection
return IntPtr.Zero;
bool isNativeBlittable = IsNativeBlittable(managedColl);
- int sizeofNative = (isNativeBlittable) ? SizeOf() : MarshalSizeOf();
+ int sizeofNative = SizeOf();
//If the pointer is a void** we need to step by the pointer size, otherwise it's just a void* and step by the type size.
int stride = (arrayOfPointers) ? IntPtr.Size : sizeofNative;
@@ -218,9 +218,9 @@ public static IntPtr ToNativeArray(List managedArray) where T : struct
/// Pointer to unmanaged memory
/// Number of elements to read
/// Managed array
- public static T[] FromNativeArray(IntPtr nativeArray, int length) where T : struct
+ public static unsafe T[] FromNativeArray(void* nativeArray, int length) where T : struct
{
- if(nativeArray == IntPtr.Zero || length == 0)
+ if(nativeArray == null || length == 0)
return Array.Empty();
T[] managedArray = new T[length];
@@ -305,118 +305,22 @@ public static IntPtr ToNativePointer(Managed managedValue)
/// Unmanaged type
/// Pointer to unmanaged memory
/// The marshaled managed value
- public static Managed FromNativePointer(IntPtr ptr)
+ public static unsafe Managed FromNativePointer(Native* ptr)
where Managed : class, IMarshalable, new()
where Native : struct
{
- if(ptr == IntPtr.Zero)
+ if(ptr == null)
return null;
Managed managedValue = Activator.CreateInstance();
- //Marshal pointer to structure
- Native nativeValue;
-
- if(managedValue.IsNativeBlittable)
- {
- Read(ptr, out nativeValue);
- }
- else
- {
- MarshalStructure(ptr, out nativeValue);
- }
-
//Populate managed value
- managedValue.FromNative(nativeValue);
+ managedValue.FromNative(*ptr);
return managedValue;
}
- ///
- /// Convienence method for marshaling a pointer to a structure. Only use if the type is not blittable, otherwise
- /// use the read methods for blittable types.
- ///
- /// Struct type
- /// Pointer to marshal
- /// The marshaled structure
- public static void MarshalStructure(IntPtr ptr, out T value) where T : struct
- {
- if(ptr == IntPtr.Zero)
- value = default(T);
-
- Type type = typeof(T);
-
- INativeCustomMarshaler marshaler;
- if (HasNativeCustomMarshaler(type, out marshaler))
- {
- value = (T)marshaler.MarshalNativeToManaged(ptr);
- return;
- }
-
- value = Marshal.PtrToStructure(ptr);
- }
-
- ///
- /// Convienence method for marshaling a pointer to a structure. Only use if the type is not blittable, otherwise
- /// use the read methods for blittable types.
- ///
- /// Struct type
- /// Pointer to marshal
- /// The marshaled structure
- public static T MarshalStructure(IntPtr ptr) where T : struct
- {
- if(ptr == IntPtr.Zero)
- return default(T);
-
- Type type = typeof(T);
-
- INativeCustomMarshaler marshaler;
- if (HasNativeCustomMarshaler(type, out marshaler))
- return (T) marshaler.MarshalNativeToManaged(ptr);
-
- return Marshal.PtrToStructure(ptr);
- }
-
- ///
- /// Convienence method for marshaling a structure to a pointer. Only use if the type is not blittable, otherwise
- /// use the write methods for blittable types.
- ///
- /// Struct type
- /// Struct to marshal
- /// Pointer to unmanaged chunk of memory which must be allocated prior to this call
- public static void MarshalPointer(in T value, IntPtr ptr) where T : struct
- {
- if (ptr == IntPtr.Zero)
- return;
-
- INativeCustomMarshaler marshaler;
- if (HasNativeCustomMarshaler(typeof(T), out marshaler))
- {
- marshaler.MarshalManagedToNative((object)value, ptr);
- return;
- }
-
- Marshal.StructureToPtr(value, ptr, true);
- }
-
- ///
- /// Computes the size of the struct type using Marshal SizeOf. Only use if the type is not blittable, thus requiring marshaling by the runtime,
- /// (e.g. has MarshalAs attributes), otherwise use the SizeOf methods for blittable types.
- ///
- /// Struct type
- /// Size of the struct in bytes.
- public static unsafe int MarshalSizeOf() where T : struct
- {
- Type type = typeof(T);
-
- INativeCustomMarshaler marshaler;
- if (HasNativeCustomMarshaler(type, out marshaler))
- return marshaler.NativeDataSize;
-
- return Marshal.SizeOf();
- }
-
#endregion
#region Memory Interop (Shared code from other Projects)
@@ -559,9 +463,9 @@ public static unsafe void CopyMemory(IntPtr pDest, IntPtr pSrc, int sizeInBytesT
/// Array to store the copied data
/// Zero-based element index to start writing data to in the element array.
/// Number of elements to copy
- public static unsafe void Read(IntPtr pSrc, T[] data, int startIndexInArray, int count) where T : struct
+ public static unsafe void Read(void* pSrc, T[] data, int startIndexInArray, int count) where T : struct
{
- ReadOnlySpan src = new ReadOnlySpan(pSrc.ToPointer(), count);
+ ReadOnlySpan src = new ReadOnlySpan(pSrc, count);
Span dst = new Span(data, startIndexInArray, count);
src.CopyTo(dst);
}
@@ -583,9 +487,9 @@ public static unsafe T Read(IntPtr pSrc) where T : struct
/// Struct type
/// Pointer to memory location
/// The read value.
- public static unsafe void Read(IntPtr pSrc, out T value) where T : struct
+ public static unsafe void Read(T* pSrc, out T value) where T : struct
{
- value = Unsafe.ReadUnaligned(pSrc.ToPointer());
+ value = Unsafe.ReadUnaligned(pSrc);
}
///
diff --git a/AssimpNet/Scene.cs b/AssimpNet/Scene.cs
index defc96c..db8c299 100755
--- a/AssimpNet/Scene.cs
+++ b/AssimpNet/Scene.cs
@@ -273,9 +273,9 @@ public static IntPtr ToUnmanagedScene(Scene scene)
///
/// The unmanaged scene data
/// The managed scene, or null if the pointer is NULL
- public static Scene FromUnmanagedScene(IntPtr scenePtr)
+ public static unsafe Scene FromUnmanagedScene(AiScene* scenePtr)
{
- if(scenePtr == IntPtr.Zero)
+ if(scenePtr == null)
return null;
return MemoryHelper.FromNativePointer(scenePtr);
diff --git a/AssimpNet/Unmanaged/UnmanagedStructures.cs b/AssimpNet/Unmanaged/UnmanagedStructures.cs
index c7c981c..d021b0e 100755
--- a/AssimpNet/Unmanaged/UnmanagedStructures.cs
+++ b/AssimpNet/Unmanaged/UnmanagedStructures.cs
@@ -408,7 +408,7 @@ public static string GetFormatHint(in AiTexture aiTex)
/// Represents an aiFace struct.
///
[StructLayout(LayoutKind.Sequential)]
- public struct AiFace
+ public unsafe struct AiFace
{
///
/// Number of indices in the face.
@@ -418,14 +418,14 @@ public struct AiFace
///
/// unsigned int*, array of indices.
///
- public IntPtr Indices;
+ public uint* Indices;
}
///
/// Represents an aiBone struct.
///
[StructLayout(LayoutKind.Sequential)]
- public struct AiBone
+ public unsafe struct AiBone
{
///
/// Name of the bone.
@@ -450,7 +450,7 @@ public struct AiBone
///
/// VertexWeight*, array of vertex weights.
///
- public IntPtr Weights;
+ public VertexWeight* Weights;
///
/// Matrix that transforms the vertex from mesh to bone space in bind pose
@@ -1137,7 +1137,7 @@ public struct AiExportFormatDesc
/// blobs represent auxillary files produced by the exporter (e.g. material files) and are named accordingly.
///
[StructLayout(LayoutKind.Sequential)]
- public struct AiExportDataBlob
+ public unsafe struct AiExportDataBlob
{
///
/// size_t, size of the data in bytes.
@@ -1147,7 +1147,7 @@ public struct AiExportDataBlob
///
/// void*, the data.
///
- public IntPtr Data;
+ public void* Data;
///
/// AiString, name of the blob.
@@ -1157,7 +1157,7 @@ public struct AiExportDataBlob
///
/// aiExportDataBlob*, pointer to the next blob in the chain.
///
- public IntPtr NextBlob;
+ public AiExportDataBlob* NextBlob;
}
///