Skip to content

Commit

Permalink
Merged in improve-version-support (pull request #5)
Browse files Browse the repository at this point in the history
Improve platform compatibility (recent Linux, UWP, Unity, newer Assimp)

* Allow overriding LogStream's native callbacks with custom methods

When used in Unity, IL2CPP throws a runtime error that it cannot marshal
the open and close delegates to native code. It is possible to marshal
static methods [1], which would be possible t…
* Support BC breaking changes in data structures for upcoming Assimp 5.1

* Support BC breaking changes in data structures for upcoming Assimp 5.1

* Merge branch 'feature/mrwatts-arm64-uwp-with-assimp-5.1' into improve-version-support

* Refactor platform support and support newer glibc on Linux

* Update data structures to match Assimp v5.2.3

* Use kernel32.dll consistently on Win32 back end

__Internal might also work, but Unity's IL2CPP will then look for these
symbols at build time, meaning that it will break non-Win32 builds using
IL2CPP (such as for Android). The same problem seems to exist …
* Avoid __Internal for UWP to fix Unity IL2CPP on other targets

Unity's IL2CPP immediately tries to link all functions marked as
DllImport("__Internal") at build time, even on platforms that don't
support it. This was breaking the Android IL2CPP build. If y…
* Add UWP DLL loading to Unity example

* Use libc.so.6 on Linux to avoid IL2CPP breaking on other platforms

See also 4ab089081f1e33eab6cee4ab61bde28d1ba1d074 for more context.
__Internal should be avoided as it's not well documented outside Unity,
and also causes IL2CPP to always search for thes…

Approved-by: Nicholas Woodfield
  • Loading branch information
NoTuxNoBux authored and Starnick committed May 7, 2022
1 parent 77c8eb7 commit edd6f2f
Show file tree
Hide file tree
Showing 17 changed files with 1,193 additions and 502 deletions.
2 changes: 2 additions & 0 deletions AssimpNet/Bone.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ void IMarshalable<Bone, AiBone>.ToNative(IntPtr thisPtr, out AiBone nativeValue)
nativeValue.Name = new AiString(m_name);
nativeValue.OffsetMatrix = m_offsetMatrix;
nativeValue.NumWeights = (uint) m_weights.Count;
nativeValue.Armature = IntPtr.Zero;
nativeValue.Node = IntPtr.Zero;
nativeValue.Weights = IntPtr.Zero;

if(nativeValue.NumWeights > 0)
Expand Down
119 changes: 83 additions & 36 deletions AssimpNet/IOStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,6 @@ namespace Assimp
/// </summary>
public abstract class IOStream : IDisposable
{
private AiFileWriteProc m_writeProc;
private AiFileReadProc m_readProc;
private AiFileTellProc m_tellProc;
private AiFileTellProc m_fileSizeProc;
private AiFileSeek m_seekProc;
private AiFileFlushProc m_flushProc;
private IntPtr m_filePtr;
private bool m_isDiposed;
private String m_pathToFile;
Expand Down Expand Up @@ -99,26 +93,54 @@ internal IntPtr AiFile
/// </summary>
/// <param name="pathToFile">Path to file given by Assimp</param>
/// <param name="fileMode">Desired file access mode</param>
public IOStream(String pathToFile, FileIOMode fileMode)
/// <param name="initialize"></param>
public IOStream(String pathToFile, FileIOMode fileMode, bool initialize = true)
{
m_pathToFile = pathToFile;
m_fileMode = fileMode;

m_writeProc = OnAiFileWriteProc;
m_readProc = OnAiFileReadProc;
m_tellProc = OnAiFileTellProc;
m_fileSizeProc = OnAiFileSizeProc;
m_seekProc = OnAiFileSeekProc;
m_flushProc = OnAiFileFlushProc;
if (initialize)
{
Initialize(
OnAiFileWriteProc,
OnAiFileReadProc,
OnAiFileTellProc,
OnAiFileSizeProc,
OnAiFileSeekProc,
OnAiFileFlushProc,
IntPtr.Zero
);
}
}

/// <summary>
/// Initializes the system by setting up native pointers for Assimp to the specified functions.
/// </summary>
/// <param name="aiFileWriteProc"></param>
/// <param name="aiFileReadProc"></param>
/// <param name="aiFileTellProc"></param>
/// <param name="aiFileSizeProc"></param>
/// <param name="aiFileSeek"></param>
/// <param name="aiFileFlushProc"></param>
/// <param name="userData"></param>
protected void Initialize(
AiFileWriteProc aiFileWriteProc,
AiFileReadProc aiFileReadProc,
AiFileTellProc aiFileTellProc,
AiFileTellProc aiFileSizeProc,
AiFileSeek aiFileSeek,
AiFileFlushProc aiFileFlushProc,
IntPtr userData
)
{
AiFile file;
file.WriteProc = Marshal.GetFunctionPointerForDelegate(m_writeProc);
file.ReadProc = Marshal.GetFunctionPointerForDelegate(m_readProc);
file.TellProc = Marshal.GetFunctionPointerForDelegate(m_tellProc);
file.FileSizeProc = Marshal.GetFunctionPointerForDelegate(m_fileSizeProc);
file.SeekProc = Marshal.GetFunctionPointerForDelegate(m_seekProc);
file.FlushProc = Marshal.GetFunctionPointerForDelegate(m_flushProc);
file.UserData = IntPtr.Zero;
file.WriteProc = Marshal.GetFunctionPointerForDelegate(aiFileWriteProc);
file.ReadProc = Marshal.GetFunctionPointerForDelegate(aiFileReadProc);
file.TellProc = Marshal.GetFunctionPointerForDelegate(aiFileTellProc);
file.FileSizeProc = Marshal.GetFunctionPointerForDelegate(aiFileSizeProc);
file.SeekProc = Marshal.GetFunctionPointerForDelegate(aiFileSeek);
file.FlushProc = Marshal.GetFunctionPointerForDelegate(aiFileFlushProc);
file.UserData = userData;

m_filePtr = MemoryHelper.AllocateMemory(MemoryHelper.SizeOf<AiFile>());
Marshal.StructureToPtr(file, m_filePtr, false);
Expand Down Expand Up @@ -155,16 +177,6 @@ protected virtual void Dispose(bool disposing)
m_filePtr = IntPtr.Zero;
}

if(disposing)
{
m_writeProc = null;
m_readProc = null;
m_tellProc = null;
m_fileSizeProc = null;
m_seekProc = null;
m_flushProc = null;
}

m_isDiposed = true;
}
}
Expand Down Expand Up @@ -219,7 +231,15 @@ public virtual void Close()
Dispose();
}

private UIntPtr OnAiFileWriteProc(IntPtr file, IntPtr dataToWrite, UIntPtr sizeOfElemInBytes, UIntPtr numElements)
/// <summary>
/// Callback for Assimp that handles writes.
/// </summary>
/// <param name="file"></param>
/// <param name="dataToWrite"></param>
/// <param name="sizeOfElemInBytes"></param>
/// <param name="numElements"></param>
/// <returns></returns>
protected UIntPtr OnAiFileWriteProc(IntPtr file, IntPtr dataToWrite, UIntPtr sizeOfElemInBytes, UIntPtr numElements)
{
if(m_filePtr != file)
return UIntPtr.Zero;
Expand All @@ -245,7 +265,15 @@ private UIntPtr OnAiFileWriteProc(IntPtr file, IntPtr dataToWrite, UIntPtr sizeO
return new UIntPtr((ulong) actualCount / (ulong) longSize);
}

private UIntPtr OnAiFileReadProc(IntPtr file, IntPtr dataRead, UIntPtr sizeOfElemInBytes, UIntPtr numElements)
/// <summary>
/// Callback for Assimp that handles reads.
/// </summary>
/// <param name="file"></param>
/// <param name="dataRead"></param>
/// <param name="sizeOfElemInBytes"></param>
/// <param name="numElements"></param>
/// <returns></returns>
protected UIntPtr OnAiFileReadProc(IntPtr file, IntPtr dataRead, UIntPtr sizeOfElemInBytes, UIntPtr numElements)
{
if(m_filePtr != file)
return UIntPtr.Zero;
Expand All @@ -270,7 +298,12 @@ private UIntPtr OnAiFileReadProc(IntPtr file, IntPtr dataRead, UIntPtr sizeOfEle
return new UIntPtr((ulong) actualCount / (ulong) longSize);
}

private UIntPtr OnAiFileTellProc(IntPtr file)
/// <summary>
/// Callback for Assimp that handles tell requests.
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
protected UIntPtr OnAiFileTellProc(IntPtr file)
{
if(m_filePtr != file)
return UIntPtr.Zero;
Expand All @@ -286,7 +319,12 @@ private UIntPtr OnAiFileTellProc(IntPtr file)
return new UIntPtr((ulong) pos);
}

private UIntPtr OnAiFileSizeProc(IntPtr file)
/// <summary>
/// Callback for Assimp that handles size requests.
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
protected UIntPtr OnAiFileSizeProc(IntPtr file)
{
if(m_filePtr != file)
return UIntPtr.Zero;
Expand All @@ -302,7 +340,14 @@ private UIntPtr OnAiFileSizeProc(IntPtr file)
return new UIntPtr((ulong) fileSize);
}

private ReturnCode OnAiFileSeekProc(IntPtr file, UIntPtr offset, Origin seekOrigin)
/// <summary>
/// Callback for Assimp that handles seeks.
/// </summary>
/// <param name="file"></param>
/// <param name="offset"></param>
/// <param name="seekOrigin"></param>
/// <returns></returns>
protected ReturnCode OnAiFileSeekProc(IntPtr file, UIntPtr offset, Origin seekOrigin)
{
if(m_filePtr != file)
return ReturnCode.Failure;
Expand All @@ -318,7 +363,9 @@ private ReturnCode OnAiFileSeekProc(IntPtr file, UIntPtr offset, Origin seekOrig
return code;
}

private void OnAiFileFlushProc(IntPtr file)
/// <summary>Callback for Assimp that handles flushes.</summary>
/// <param name="file"></param>
protected void OnAiFileFlushProc(IntPtr file)
{
if(m_filePtr != file)
return;
Expand Down
51 changes: 37 additions & 14 deletions AssimpNet/IOSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ namespace Assimp
/// </summary>
public abstract class IOSystem : IDisposable
{
private AiFileOpenProc m_openProc;
private AiFileCloseProc m_closeProc;
private IntPtr m_fileIOPtr;
private bool m_isDisposed;
private Dictionary<IntPtr, IOStream> m_openedFiles;
Expand Down Expand Up @@ -72,20 +70,35 @@ internal IntPtr AiFileIO
/// <summary>
/// Constructs a new IOSystem.
/// </summary>
public IOSystem()
/// <param name="initialize">
/// Whether to immediately initialize the system by setting up native pointers. Set this to
/// false if you want to manually initialize and use custom function pointers for advanced use cases.
/// </param>
public IOSystem(bool initialize = true)
{
m_openProc = OnAiFileOpenProc;
m_closeProc = OnAiFileCloseProc;
if (initialize)
{
Initialize(OnAiFileOpenProc, OnAiFileCloseProc, IntPtr.Zero);
}

m_openedFiles = new Dictionary<IntPtr, IOStream>();
}

/// <summary>
/// Initializes the system by setting up native pointers for Assimp to the specified functions.
/// </summary>
/// <param name="fileOpenProc"></param>
/// <param name="fileCloseProc"></param>
/// <param name="userData"></param>
protected void Initialize(AiFileOpenProc fileOpenProc, AiFileCloseProc fileCloseProc, IntPtr userData)
{
AiFileIO fileIO;
fileIO.OpenProc = Marshal.GetFunctionPointerForDelegate(m_openProc);
fileIO.CloseProc = Marshal.GetFunctionPointerForDelegate(m_closeProc);
fileIO.UserData = IntPtr.Zero;
fileIO.OpenProc = Marshal.GetFunctionPointerForDelegate(fileOpenProc);
fileIO.CloseProc = Marshal.GetFunctionPointerForDelegate(fileCloseProc);
fileIO.UserData = userData;

m_fileIOPtr = MemoryHelper.AllocateMemory(MemoryHelper.SizeOf<AiFileIO>());
Marshal.StructureToPtr(fileIO, m_fileIOPtr, false);

m_openedFiles = new Dictionary<IntPtr, IOStream>();
}

/// <summary>
Expand Down Expand Up @@ -160,15 +173,20 @@ protected virtual void Dispose(bool disposing)

if(disposing)
{
m_openProc = null;
m_closeProc = null;
CloseAllFiles();
}
m_isDisposed = true;
}
}

private IntPtr OnAiFileOpenProc(IntPtr fileIO, String pathToFile, String mode)
/// <summary>
/// Callback for Assimp that handles a file being opened.
/// </summary>
/// <param name="fileIO"></param>
/// <param name="pathToFile"></param>
/// <param name="mode"></param>
/// <returns></returns>
protected IntPtr OnAiFileOpenProc(IntPtr fileIO, String pathToFile, String mode)
{
if(m_fileIOPtr != fileIO)
return IntPtr.Zero;
Expand All @@ -193,7 +211,12 @@ private IntPtr OnAiFileOpenProc(IntPtr fileIO, String pathToFile, String mode)
return aiFilePtr;
}

private void OnAiFileCloseProc(IntPtr fileIO, IntPtr file)
/// <summary>
/// Callback for Assimp that handles a file being closed.
/// </summary>
/// <param name="fileIO"></param>
/// <param name="file"></param>
protected void OnAiFileCloseProc(IntPtr fileIO, IntPtr file)
{
if(m_fileIOPtr != fileIO)
return;
Expand Down
Loading

0 comments on commit edd6f2f

Please sign in to comment.