Import in Unity for Android/IOS

Issue #36 closed
romixoid created an issue

There is a way to use AssimpNet on Unity to build Android and IOS application? Thanks

Comments (2)

  1. Nicholas Woodfield repo owner

    Not out of the box, I believe the linux implementation should work for android. But iOS doesn't allow for dynamic DLL loading, so the library cannot be used on that platform.

  2. NoTuxNoBux

    I know this is old, but I wanted to mention, on top of the most recent master, I got Android on Unity 2021 to correctly try the libdl-based loader on Android by adding this patch on top:

    diff --git a/AssimpNet/Unmanaged/Platform.cs b/AssimpNet/Unmanaged/Platform.cs
    index 2fac9ff..5326cd0 100644
    --- a/AssimpNet/Unmanaged/Platform.cs
    +++ b/AssimpNet/Unmanaged/Platform.cs
    @@ -45,6 +45,11 @@ namespace Assimp.Unmanaged
             /// <summary>
             /// Mac platform.
             /// </summary>
    -        Mac
    +        Mac,
    +
    +        /// <summary>
    +        /// Unix platform.
    +        /// </summary>
    +        Unix
         }
     }
    diff --git a/AssimpNet/Unmanaged/UnmanagedLibrary.cs b/AssimpNet/Unmanaged/UnmanagedLibrary.cs
    index b2cd0c8..ad9b063 100644
    --- a/AssimpNet/Unmanaged/UnmanagedLibrary.cs
    +++ b/AssimpNet/Unmanaged/UnmanagedLibrary.cs
    @@ -1,4 +1,4 @@
    -/*
    +/*
     * Copyright (c) 2012-2020 AssimpNet - Nicholas Woodfield
     * 
     * Permission is hereby granted, free of charge, to any person obtaining a copy
    @@ -148,6 +148,11 @@ namespace Assimp.Unmanaged
                 if(RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                     return Platform.Mac;
    
    +            //Note that Android target in Unity 2021 with IL2CPP (Meta Quest 2, HTC Vive Focus 3, ...) is also picked up
    +            //as "Unix x.yy.zz.w", where the the second part contains the kernel version.
    +            if(RuntimeInformation.OSDescription.Contains("Unix"))
    +                return Platform.Unix;
    +
                 throw new InvalidOperationException(
                     $"Cannot determine OS-specific implementation " +
                         $"(OS description '{RuntimeInformation.OSDescription}', " +
    @@ -295,6 +300,8 @@ namespace Assimp.Unmanaged
                         return CreateRuntimeImplementationForWindowsPlatform(defaultLibName, unmanagedFunctionDelegateTypes);
                     case Platform.Linux:
                         return CreateRuntimeImplementationForLinuxPlatform(defaultLibName, unmanagedFunctionDelegateTypes);
    +                case Platform.Unix:
    +                    return CreateRuntimeImplementationForUnixPlatform(defaultLibName, unmanagedFunctionDelegateTypes);
                     case Platform.Mac:
                         return CreateRuntimeImplementationForMacPlatform(defaultLibName, unmanagedFunctionDelegateTypes);
                 }
    @@ -307,6 +314,7 @@ namespace Assimp.Unmanaged
                 [DllImport("kernel32.dll", CharSet = CharSet.Ansi, BestFitMapping = false, SetLastError = true, EntryPoint = "LoadLibrary")]
                 static extern IntPtr WinNativeLoadLibrary(String fileName);
    
    +
                 try
                 {
                     WinNativeLoadLibrary("non-existent-dll-that-is-never-used.dll");
    @@ -382,5 +390,28 @@ namespace Assimp.Unmanaged
                     "present on your (Linux) system and correctly expose this symbol."
                 );
             }
    +
    +        private UnmanagedLibraryImplementation CreateRuntimeImplementationForUnixPlatform(String defaultLibName, Type[] unmanagedFunctionDelegateTypes)
    +        {
    +            //Since Android is sometimes detected as UNIX as well (see GetPlatform), which is Linux-like, try libdl.
    +            [DllImport("libdl.so", EntryPoint = "dlerror")]
    +            static extern IntPtr libdl_dlerror();
    +
    +            try
    +            {
    +                libdl_dlerror();
    +
    +                return new UnmanagedLinuxLibdlLibraryImplementation(defaultLibName, unmanagedFunctionDelegateTypes);
    +            }
    +            catch (DllNotFoundException)
    +            {
    +                // Continue with fallback.
    +            }
    +
    +            throw new PlatformNotSupportedException(
    +                "UNIX system detected, but libdl.so does not contain symbol 'dlopen' necessary to load Assimp " +
    +                "DLL. Check that this so files is present on your (UNIX) system and correctly exposes this symbol."
    +            );
    +        }
         }
     }
    

    I haven’t actually succeeded in loading an ARM64 build of Assimp itself yet, but this detects the platform correctly and it doesn’t fail on using libdl, so the approach should work with an appropriate SO file.

    The gist is that Android ARM64 (tested with an HTC Vive Focus 3) is detected by Unity 2021 with ARM64 IL2CPP as “Unix” in for some reason. Note that Unity 2021 is different from 2020 in that something seems to have changed around the RuntimeInformation APIs and platform detection: the HoloLens 2 was previously also detected as Windows, but 2021 is suddenly causing the “Determining OS-specific implementation failed” error, which I need to investigate further (it’s likely that it now got its own OS description).

    I currently can’t submit a PR because something seems to be wrong with Git LFS and the Linux libassimp.so generating 404's (even Bitbucket’s workaround and cleanly forking seems to fail).

    EDIT: We got it to work on a Meta Quest 2. The dlopen implementation works. The missing link was that you need to place the file in e.g. libs/arm64-v8a in the APK, and then just try to load libassimp.so, as it will search in that folder automatically (part of the DLL search path); trying to load by absolute path from the storage folder or mounted APK folder did not work, probably due to security constraints (it’s the same story on UWP).

  3. Log in to comment