Search Unity

[RELEASED] Piglet: glTF Importer

Discussion in 'Assets and Asset Store' started by awesomesaucelabs, Jul 9, 2020.

  1. DerrickBarra

    DerrickBarra

    Joined:
    Nov 19, 2013
    Posts:
    210
    @awesomesaucelabs I created a test repo for the bug, you can find it at this link.

    Use the scripting define symbol USE_MODIFIED_PIGLET to see check the loading with the modified TextureUtil.cs that is loading the KTX2 textures correctly. Remove the symbol to restore the original logic.

    EDIT: Just saw your latest message, it's possible then that there's a logic error somewhere in our use of Piglet. I'll keep looking into this test repo to locate the bug.

    Importing the model directly in the editor does work, so the error is either in the script that is loading the model from the web, or it's in the Piglet runtime importer logic.

    EDIT 2: So the bug is due to the initial Request being a UnityWebRequestTexture instead of a UnityWebRequest, so the data attribute will always be null, and the KTX texture will never be loaded and instead you'll get the missing texture asset applied to the material (the red '?' texture). That's why the bug fixed version is necessary for runtime imports.

    Code (CSharp):
    1. #if USE_MODIFIED_PIGLET
    2.     var request = UnityWebRequest.Get(uri); //Has valid .data attribute
    3. #else
    4.     var request = UnityWebRequestTexture.GetTexture( uri, true ); //.data is always null
    5. #endif
     
    Last edited: Apr 9, 2021
  2. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @DerrickBarra

    Thanks very much for providing the sample project/repo! It's been extremely helpful.

    I'm able to see the buggy white/red rendering now when I run your project. And I see what you mean about `data` being null.

    I'll work on another bugfix release, this time using the code/approach you originally suggested (UnityWebRequest followed by UnityWebRequestTexture).
     
  3. IMC-Lab

    IMC-Lab

    Joined:
    Mar 28, 2014
    Posts:
    4
    Looks like a great asset! Does it work on iOS? Thanks:)
     
  4. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    Thanks @IMC-Lab!

    I haven't tested it myself on iOS yet (it's still on my TODO list), but a few users have told me it is working well for them on iOS.

    I'll send you a free copy in a DM, so you can try it yourself.

    The quickest way to test it is to do an iOS build of the example scene (Assets/Piglet/Examples/RuntimeImport/Scenes/RuntimeImport.unity), and then run it on your iPhone. If you see the spinning Piglet model ("Sir Piggleston"), then it is working!
     
  5. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @IMC-Lab,

    It seems that there's no way to a send a private message with an attachment on this forum.

    Send me an e-mail at awesomesaucelabs@gmail.com, and I'll reply with your free copy.

    Thanks for your interest!
     
  6. JudahMantell

    JudahMantell

    Joined:
    Feb 28, 2017
    Posts:
    476
    I feel like this is a simple question, but I can't seem to figure it out. Hopefully, someone else would benefit as well:
    Is it possible to get the name of a model being imported from the GltfImportStep?
    I'm using the OnProgress method to display a progress bar, but I want to display the name of what's being imported, rather than just the step.

    Here's my code so far:
    Code (CSharp):
    1.    
    2. private void OnProgress(GltfImportStep step, int completed, int total)
    3.     {
    4.         int percentage = Mathf.RoundToInt(completed / total * 100);
    5.         gltfImportStepString = "Importing Model: " + step + percentage+"%";
    6.     }
    7.  
     
  7. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @MidnightCoffeeInc,

    Yes, I can see how that would be a bit tricky, especially if you have multiple GltfImportTask's executing simultaneously and they're all using the same progress callback. (I assume that is your situation?)

    The first solution that comes to mind is to use an anonymous function (a.k.a. lambda function) for your progress callback.

    For example, when you are first creating the import task, instead of doing:

    Code (CSharp):
    1. _task.OnProgress = OnProgess;
    you could do something like:

    Code (CSharp):
    1.  
    2. string myModelName = "foo";
    3. _task.OnProgress = (step, completed, total) => {
    4.      int percentage = Mathf.RoundToInt(completed / total * 100);
    5.      gltfImportStepString = "Importing Model: " + myModelName + step + percentage+"%";
    6. };
    The anonymous function will "remember" the value of
    myModelName
    variable from the surrounding context.

    EDIT: Forgot trailing semicolon on last line.
     
    travlake likes this.
  8. JudahMantell

    JudahMantell

    Joined:
    Feb 28, 2017
    Posts:
    476
    Interesting, I'll try that, thanks!!
    EDIT: Works exactly like I need, thanks again :)
     
    Last edited: Apr 12, 2021
  9. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
  10. DerrickBarra

    DerrickBarra

    Joined:
    Nov 19, 2013
    Posts:
    210
    @awesomesaucelabs : Found a better way of importing textures!

    So the version below allows us to re-use the same UnityWebRequest without having to create a second UnityWebRequestTexture, and also allows us to enable mipmaps if needed (this should probably be exposed to the user as an option, for my purposes I prefer mipmaps to be enabled).

    Code (CSharp):
    1. static public IEnumerable<(Texture2D, bool)> ReadTextureEnum(Uri uri)
    2.         {
    3.             // Note!: Using `UnityWebRequestTexture`
    4.             // is preferable to `Texture2D.LoadImage`
    5.             // because it does not block the main Unity thread.
    6.  
    7.             var request = UnityWebRequest.Get(uri);
    8.             request.SendWebRequest();
    9.  
    10.             while (!request.isDone)
    11.                 yield return (null, false);
    12.  
    13.             if (request.HasError())
    14.                 throw new Exception(string.Format(
    15.                     "failed to load image URI {0}: {1}",
    16.                     uri, request.error));
    17.  
    18.             var data = request.downloadHandler.data;
    19.  
    20.             if( IsKtx2Data( data ) )
    21.             {
    22. #if KTX_UNITY_0_9_1_OR_NEWER
    23.                 foreach( var result in LoadKtx2Data( data ) )
    24.                     yield return (result, false);
    25. #elif KTX_UNITY
    26.                 Debug.LogWarning("Failed to load texture in KTX2 format, "+
    27.                      "because KtxUnity package is older than 0.9.1.");
    28.                 yield return (null, false);
    29. #else
    30.                 Debug.LogWarning("Failed to load texture in KTX2 format "+
    31.                     "because KtxUnity package is not installed. Please install KtxUnity "+
    32.                     "by following the directions at https://github.com/atteneder/KtxUnity "+
    33.                     "(requires Unity 2019.3+).");
    34.                 yield return (null, false);
    35. #endif
    36.                 yield break;
    37.             }
    38.             else
    39.             {
    40.                 Texture2D texture = new Texture2D( 2, 2, TextureFormat.ARGB32, true, false );
    41.                 texture.LoadImage( data, true );
    42.  
    43.                 yield return (texture, true);
    44.             }
    45.            
    46.         } //END ReadTextureEnum
     
  11. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    Thanks for your help, @DerrickBarra!

    Actually, I think I prefer your original solution (i.e.
    UnityWebRequest
    followed by
    UnityWebRequestTexture
    ). Unfortunately,
    LoadImage
    completely blocks the main Unity thread while it's performing PNG/JPG compression, whereas
    UnityWebRequestTexture
    does PNG/JPG decompression on a background thread. So
    LoadImage
    works fine for edit-time glTF imports, but can cause unacceptable stalling of the main Unity thread during runtime glTF imports. For example, I've seen LoadImage take as long as 200ms to load a large PNG image on my PC.

    Downloading/reading the whole image file twice definitely isn't ideal, but I think it's probably the lesser of two evils in this case. Most of the time the "URI" that gets passed to
    ReadTextureEnum
    is a local temp file rather than an HTTP(S) URL, so the cost of "downloading" the file a second time isn't actually as bad as it looks.

    In future work, I have a couple of ideas for improving the performance of your two-request solution:

    (1) In many (but not all) cases, it's possible to detect the image format (KTX2 vs. PNG/JPG) in upstream code, before the call to
    ReadTextureEnum
    even gets made. So I could have two versions of the
    ReadTextureEnum
    method -- one for KTX2 and one for PNG/JPG.
    (2) In cases where the image *is* coming from an HTTP(S) URL, I might be able to write a custom
    DownloadHandler
    for
    UnityWebRequest
    that only downloads the first few bytes to determine the image format. Unity provides the DownloadHandlerScript class to help people write custom download handlers, but I haven't tried it yet.

    I'm currently doing some performance comparisons on PC and WebGL to make sure that your original two-request fix doesn't hurt the performance too badly. If it looks okay, I will go ahead and publish another Piglet release (1.2.2) in the next day or so.

    I'm a bit swamped at the moment, so I'll have to experiment with more optimal solutions later. But I think it's important to get KTX2 working properly again in Unity 2021.1.1f1 as soon as I can.
     
  12. DerrickBarra

    DerrickBarra

    Joined:
    Nov 19, 2013
    Posts:
    210
    @awesomesaucelabs : The only side benefit that LoadImage provides then is being able to change the mipmap settings. I haven't seen a way to do that via UnityWebRequestTexture.
     
  13. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @DerrickBarra,

    Yes, I think you are right (no way to control mipmap settings with
    UnityWebRequestTexture
    ).

    UnityWebRequestTexture
    also lacks a
    linear
    parameter, which creates a lot of work for me in order to correctly handle color space conversions. (Currently, Piglet doesn't correctly handle Linear rendering mode, but I've been working on fixing it on the shader side.)

    Another annoyance with
    UnityWebRequestTexture
    is that you can't load texture data directly from a
    byte[]
    , so I have to write the data out to a temp file and then read it back in again.

    I'm glad that
    UnityWebRequestTexture
    exists (Piglet depends pretty heavily on it), but at the same time there's a lot of room for improvement.
     
  14. DerrickBarra

    DerrickBarra

    Joined:
    Nov 19, 2013
    Posts:
    210
    @awesomesaucelabs Our team is progressing on switching over to Piglet for our primary software that runs on WebGL, and I noticed an import error when loading GLTF/GLB's that are located on the browser's IDBFS.

    upload_2021-4-16_10-56-10.png

    Our files are downloaded + cached onto the IDBFS via a UnityWebRequest in a previous step, and then I pass the file path location to Piglet for loading via the RuntimeGltfImporter.GetImportTask( path ) command.

    I'll keep investigating, I know loading via file path is possible, so maybe there's a different load command I should be using or Piglet is using a File.ReadAllBytes() command? I remember reading somewhere that you have to read bytes via the UnityWebRequest to avoid errors.
     
  15. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @DerrickBarra

    Thanks for the vote of confidence! It's exciting to see BrandXR and other companies use my software.

    I'm not sure how to read from "file:///idbfs" in a Unity WebGL app or if it's even possible (I would certainly like to know!). I remember that I ran into some issues with that.

    I worked around those issues in Piglet by first reading the file into memory (on the javascript side) then creating a temporary URL for the data using
    URL.createObjectURL
    (again on the javascript side).

    The
    UriUtil.CreateUri
    method in Piglet might be helpful (Assets/Piglet/Scripts/Util/UriUtil.cs):

    Code (CSharp):
    1.         /// <summary>
    2.         /// Return a URI through which the given data (byte[])
    3.         /// can be read.  This method was written to facilitate
    4.         /// the use of UnityWebRequestTexture with in-memory
    5.         /// PNG/JPG data.
    6.         /// </summary>
    7.         static public IEnumerable<string> CreateUri(byte[] data)
    8.         {
    9.             // Note: While it is possible to read/write files in
    10.             // Application.temporaryCachePath in a WebGL build
    11.             // using standard C# I/O methods (e.g. File.WriteAllBytes),
    12.             // there is no straightforward way to read such files
    13.             // via a URI. In particular, UnityWebRequest/UnityWebRequestTexture
    14.             // will fail with a browser permissions error when given *any*
    15.             // local file path, including paths under
    16.             // Application.temporaryCachePath or Application.persisentDataPath.
    17.             // See this thread for a discussion of the issue:
    18.             // https://forum.unity.com/threads/indexeddb-files-and-www.461171/
    19.             //
    20.             // To work around this issue, I create a temporary URL for the
    21.             // file on the Javascript side, using `createObjectUrl`.
    22.             // I got this idea from the following post on the Unity Forum:
    23.             // https://forum.unity.com/threads/how-do-i-let-the-user-load-an-image-from-their-harddrive-into-a-webgl-app.380985/#post-2474594
    24.  
    25. #if UNITY_WEBGL && !UNITY_EDITOR
    26.             yield return JsLib.CreateObjectUrl(data, data.Length);
    27. #else
    28.             string path = Path.Combine(Application.temporaryCachePath,
    29.                 StringUtil.GetRandomString(8));
    30.  
    31.             foreach (var unused in FileUtil.WriteAllBytes(path, data))
    32.                 yield return null;
    33.  
    34.             yield return path;
    35. #endif
    36.         }
    37.  
    And the corresponding code on the javascript side (Assets/Piglet/Plugins/WebGL/Piglet.jslib) is:

    Code (JavaScript):
    1.     // Given a C# byte[] array, return a localhost URL through which
    2.     // the data can be read.  This method was written to facilitate
    3.     // using UnityWebRequestTexture on in-memory PNG/JPG data.
    4.     CreateObjectUrl: function(array, size)
    5.     {
    6.         // Copy the input data (`array`) from the heap to
    7.         // a separate array (`copy`).  This is necessary
    8.         // because any views on the heap (e.g. `slice` below)
    9.         // are invalidated when Unity increases the
    10.         // the heap size.  It is safe to use the data in
    11.         // place if it is used immediately (i.e. before
    12.         // this function returns).
    13.         //
    14.         // For background info, see:
    15.         // https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#access-memory-from-javascript
    16.  
    17.         var slice = new Uint8Array(HEAPU8.buffer, array, size);
    18.         var copy = new Uint8Array(slice);
    19.         var blob = new Blob([copy], {type: 'application/octet-stream'});
    20.         var url = URL.createObjectURL(blob);
    21.  
    22.         // Return a C# string to the caller.
    23.         //
    24.         // For discussion, see:
    25.         // https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html
    26.  
    27.         var bufferSize = lengthBytesUTF8(url) + 1;
    28.         var buffer = _malloc(bufferSize);
    29.         stringToUTF8(url, buffer, bufferSize);
    30.  
    31.         return buffer;
    32.     }
     
  16. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @DerrickBarra,

    By the way, it's going well with my (second) KTX2 texture-loading fix.

    I did some refactoring which allows me to avoid making two web requests in almost all cases. (The only case where two requests need to be made is when the PNG/JPG/KTX2 file is being read from an HTTP URL, but that almost never happens in practice, since the PNG/JPG/KTX2 is usually embedded inside the .glb/.zip, or is available as a local file alongside the .gltf).

    I've been testing the fix today and it's working great. I'm just doing some final sanity checks, and then I will submit the new release to the asset store (either today or tomorrow).
     
  17. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @DerrickBarra,

    Actually, you might be able to solve the issue by reading the entire file into a byte[] array (using
    File.ReadAllBytes
    ), then passing the byte[] array to
    GetImportTask
    , instead of passing the idbfs path directly.

    Piglet uses a
    UnityWebRequest
    to read in the .gltf/.glb/.zip file, and
    UnityWebRequest
    produces errors when attempting to read a URI that starts with
    file:///idfs
    .
     
    Last edited: Apr 16, 2021
  18. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @DerrickBarra,

    FYI, Piglet 1.2.2 with the KTX2 texture-loading fixes/refactoring is published on the Asset Store now.

    (BTW, since the web demo is unaffected by the bug, it is still using Piglet 1.2.0.)
     
  19. DerrickBarra

    DerrickBarra

    Joined:
    Nov 19, 2013
    Posts:
    210
    @awesomesaucelabs Sounds good, I'll update asap. Oh and I decided to just use Piglet with byte[] links from my local cache in WebGL.

    How's the progress on the Draco loading? Run into any hiccups?
     
  20. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @DerrickBarra

    Glad to hear it is working!

    No major hiccups with Draco so far -- still aiming to release it by the end of the month. Just need to do a bit more testing and write the documentation.

    On hiatus here for the next few days to do my taxes. (Taxes in Canada are due on April 30th.)
     
  21. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @DerrickBarra

    I have a couple of users that have been waiting a long time for bug fixes (several weeks), but since Draco is almost done I think I will just go ahead and release it anyway.
     
  22. DerrickBarra

    DerrickBarra

    Joined:
    Nov 19, 2013
    Posts:
    210
    Sounds good to me, once the upgrade drops I'll try it out and let you know if I find any bugs.
     
  23. virgilcwyile

    virgilcwyile

    Joined:
    Jan 31, 2016
    Posts:
    73
    Is Ram consumption optimised in Piglet? I have a big time problem with the other GLTF importers. They just import the .GLTF file and takes lot of memory when loaded multiple objects from server.
     
  24. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @virgilcwyile,

    To be honest I haven't done much profiling of RAM usage (yet!).

    I'd be happy to send you a free copy over e-mail, so you can try it out yourself. (I can't send you a copy through this forum because there's no support for attachments on private messages.) If you're game, send me an e-mail at awesomesaucelabs@gmail.com.
     
  25. Boemak

    Boemak

    Joined:
    May 29, 2013
    Posts:
    48
    Hey,

    Will you be supporting the "saving" into the Asset folder? I use it quite a bunch when saving from Blender.

    I bought Piglet because of the material extraction, but this is something I would really appreciate.
     
  26. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @Boemak,

    Yep, I want that too :) I realize it would make everyone's workflow much better (i.e. more automated), and a few people have requested it already.

    However, it might be a while (e.g. months) before I get around to implementing that, because I have a few works-in-progress already that I plan to finish first (Draco support, iOS testing, bug fixes).
     
  27. Boemak

    Boemak

    Joined:
    May 29, 2013
    Posts:
    48
    No problem, I can wait. :)
     
  28. cdaniel09

    cdaniel09

    Joined:
    Jun 10, 2016
    Posts:
    5
    Installed and attempted to drop-drag a zip with GLTF. Get this error?

    IOException: Win32 IO returned ERROR_INVALID_NAME. Path: C:\Users\cdani\Unity-Projects\WWWF8-AfterHours\Assets\CluesC:
    System.IO.Directory.CreateDirectoriesInternal (System.String path) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    System.IO.Directory.CreateDirectory (System.String path) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    System.IO.DirectoryInfo.Create () (at <695d1cc93cca45069c528c15c9fdd749>:0)
    (wrapper remoting-invoke-with-check) System.IO.DirectoryInfo.Create()
    System.IO.Directory.CreateDirectoriesInternal (System.String path) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    System.IO.Directory.CreateDirectory (System.String path) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    System.IO.DirectoryInfo.Create () (at <695d1cc93cca45069c528c15c9fdd749>:0)
    (wrapper remoting-invoke-with-check) System.IO.DirectoryInfo.Create()
    System.IO.Directory.CreateDirectoriesInternal (System.String path) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    System.IO.Directory.CreateDirectory (System.String path) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    System.IO.DirectoryInfo.Create () (at <695d1cc93cca45069c528c15c9fdd749>:0)
    (wrapper remoting-invoke-with-check) System.IO.DirectoryInfo.Create()
    System.IO.Directory.CreateDirectoriesInternal (System.String path) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    System.IO.Directory.CreateDirectory (System.String path) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    System.IO.DirectoryInfo.Create () (at <695d1cc93cca45069c528c15c9fdd749>:0)
    (wrapper remoting-invoke-with-check) System.IO.DirectoryInfo.Create()
    System.IO.Directory.CreateDirectoriesInternal (System.String path) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    System.IO.Directory.CreateDirectory (System.String path) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    System.IO.DirectoryInfo.Create () (at <695d1cc93cca45069c528c15c9fdd749>:0)
    (wrapper remoting-invoke-with-check) System.IO.DirectoryInfo.Create()
    System.IO.Directory.CreateDirectoriesInternal (System.String path) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    System.IO.Directory.CreateDirectory (System.String path) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    Piglet.EditorGltfImportCache..ctor (System.String importBaseDir) (at Assets/Piglet/Scripts/Importer/Editor/EditorGltfImportCache.cs:97)
    Piglet.EditorGltfImporter..ctor (System.String gltfPath, System.String importPath, Piglet.GltfImportOptions importOptions, Piglet.GltfImporter+ProgressCallback progressCallback) (at Assets/Piglet/Scripts/Importer/Editor/EditorGltfImporter.cs:46)
    Piglet.EditorGltfImporter.GetImportTask (System.String gltfPath, System.String importPath, Piglet.GltfImportOptions importOptions) (at Assets/Piglet/Scripts/Importer/Editor/EditorGltfImporter.cs:76)
    Piglet.ProjectBrowserGltfImporter+<ImportCoroutine>d__5.MoveNext () (at Assets/Piglet/Editor/ProjectBrowser/ProjectBrowserGltfImporter.cs:202)
    Piglet.ProjectBrowserGltfImporter.<StartImport>g__ImporterUpdate|4_0 () (at Assets/Piglet/Editor/ProjectBrowser/ProjectBrowserGltfImporter.cs:149)
    UnityEditor.EditorApplication.Internal_CallUpdateFunctions () (at <e09fc44b2b464346872ad04477f51ab1>:0)
     
  29. cdaniel09

    cdaniel09

    Joined:
    Jun 10, 2016
    Posts:
    5
    Never mind - i uninstalled and did something else. Can you please issue a refund? cdaniel09@gmail.com
    Thanks
     
  30. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @cdaniel09,

    No problem -- I just sent your refund via PayPal.

    Best of luck with your project!
     
  31. cdaniel09

    cdaniel09

    Joined:
    Jun 10, 2016
    Posts:
    5
    Thank you
     
  32. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @cdaniel09,

    Due to some strange glitch with the forum, your original message about the ERROR_INVALID_NAME error was not visible until now.

    Anyhow, thanks for reporting it. I'm not sure exactly what is going on, but another user recently reported the same error (happening at the same place in the Piglet code). That other person said that when they loaded the glTF file from a different directory with a shorter path, the error went away.

    It seems like some kind of Windows quirk with long paths and/or certain characters in the filename. I will try to figure it out.
     
  33. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    Piglet 1.3.0 released!

    Happy Friday everyone :)

    I'm happy to announce the release of Piglet 1.3.0, which finally adds support for Draco mesh compression! This functionality is provided by integrating with @tteneder's awesome DracoUnity package. Please note that I recommend using DracoUnity 1.4.0 for now, rather than DracoUnity 2.0.0-preview. See Draco Mesh Compression in the Piglet manual for background info and setup instructions.

    The main benefit of using Draco compression is that it can significantly reduce your glTF file sizes. For example, my "Sir Piggleston" model gets reduced from 492 KB to 90 KB (80% reduction). Based on my testing so far, loading Draco-compressed glTF files is neither slower nor faster than loading vanilla glTF files. That's good because that means Draco is basically zero-cost compression!

    If you want to see some real-world examples of Draco in action, try comparing the vanilla and Draco-compressed example models at the Piglet Web Demo. When combined with KTX2 texture compression (again thanks to @atteneder's KtxUnity package), I am seeing combined compression rates of 80%-90%, which is awesome!

    Finally, if you're interested in learning about the algorithm behind Draco, I recommend checking out these links:

    * EdgeBreaker, the Heart of Google Draco (introductory blog post)
    * original paper about EdgeBreaker algorithm
    * second EdgeBreaker paper with simplified algorithm

    Changelog

    Shout-outs

    @tteneder Thanks for making DracoUnity and for your support!

    @DerrickBarra It's been a long wait, but Piglet finally has support for both KTX2 and Draco. Hurray!

    @ASGS_DumbFox @Makio64 @Pode Because you also expressed interest in Draco support!

    @MidnightCoffeeInc Piglet now skips over meshes with type POINTS/LINES and issues a warning (instead of crashing!)
     
    Last edited: May 14, 2021
    tteneder and DerrickBarra like this.
  34. DerrickBarra

    DerrickBarra

    Joined:
    Nov 19, 2013
    Posts:
    210
    @awesomesaucelabs Congrats on the release, that's a major milestone!

    I'm going to integrate the new version and I'll hit you up if we find anything off about it. At this point, you've got the best GLTF importer around in Unity (for speed, support, and accuracy compared to files uploaded to Sketchfab)
     
  35. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
  36. DerrickBarra

    DerrickBarra

    Joined:
    Nov 19, 2013
    Posts:
    210
    @awesomesaucelabs so the Draco loading is working, but I'm seeing some bugs in editor that spam the console log.

    upload_2021-5-14_11-55-3.png

    These errors appear when playback is stopped in editor, very weird. I tried deleting my project, and also reimporting the project assets. Not quite sure why Draco code is running in editor.
     
  37. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @DerrickBarra,

    Can you advise which version of DracoUnity you have installed?

    In the manual, I currently advise to use DracoUnity 1.4.0 (should have mentioned that in my release announcement). I have seen similar errors with DracoUnity 2.0.0-preview when switching the build platform to WebGL in the Editor.
     
  38. DerrickBarra

    DerrickBarra

    Joined:
    Nov 19, 2013
    Posts:
    210
    That might be it, I'll go back to 1.4.0 and let you know.

    Edit: Yep! DracoUnity 2.0.0 beta has that weird bug, but 1.4.0 works well. Thanks for pointing that out.
     
  39. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @DerrickBarra,

    Glad to hear! (I added a note to my release announcement above.)

    I imagine that bug will go away when DracoUnity 2.0.0 gets released. Right now, people can easily trip on it, because the "Installer Package" on the GitHub page installs whatever is the latest tagged version, and currently that is 2.0.0-preview.
     
  40. Pode

    Pode

    Joined:
    Nov 13, 2013
    Posts:
    145
  41. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
  42. tteneder

    tteneder

    Unity Technologies

    Joined:
    Feb 22, 2011
    Posts:
    175
    @awesomesaucelabs fyi DracoUnity 2.x/3.x is out! They are identical, except starting with 3.0 the coordinate system conversion changed. It's already put to use in glTFast 4.x which supports Editor import now.

    Happy upgrading! Let me know if it works out (or not).
     
    awesomesaucelabs likes this.
  43. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @tteneder,

    Excellent. Congrats on the new release and thanks for the heads up!

    There is a good chance that Piglet 1.3.0 already works fine with DracoUnity 2.x/3.x, since I've already added the code to support the new API. But I will do some more testing next week to make sure.

    Note to Piglet users: If you are wondering, the main benefit of upgrading to DracoUnity 2.x/3.x would be potential performance improvements. If you run into issues with DracoUnity 2.x/3.x, you can always downgrade to DracoUnity 1.4.0 in the Package Manager window (or edit your
    Packages/manifest.json
    and reopen Unity) and everything should work fine again. Also, you can find instructions for installing a pinned version of DracoUnity in the Draco Mesh Compression section of the Piglet manual.
     
    tteneder likes this.
  44. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    Hi all!

    Just to follow up about DracoUnity 2.x/3.x testing:

    Unfortunately, I'm currently seeing some issues when loading skinned meshes with DracoUnity 2.x/3.x, as described in https://github.com/atteneder/DracoUnity/issues/21

    Right now, I'm not sure whether the problem is on the Piglet side or on the DracoUnity side, but I'm sure we'll figure it out.

    In the meantime, I recommend sticking with DracoUnity 1.4.0 (which works great, btw!).
     
  45. ASGS_DumbFox

    ASGS_DumbFox

    Joined:
    Sep 23, 2017
    Posts:
    22
    @awesomesaucelabs Hey!

    We came across an issue loading a model and wanted to make you aware in the event other users run into the same thing.

    When loading this model:


    We are seeing parts of the mesh missing. Or at least at first glance it appears to be missing, but what we found after reviewing in the editor is that these sections of the mesh are actually duplicated from the left side and are scaled by -1 to be used on the right side.



    When loaded from piglet, these mesh pieces are overlapping with the left side as their scale is being reverted. This issue also affects the right-handed sword.

    We see the same issue when loading in the Piglet web viewer:



    But we don't see this issue when loading in the Babylon sandbox:



    It would appear if a model doesn't have their transform scale set as a positive value this issue will occur. Each model that was imported improperly had a negative value in the X-Axis.

    Thanks!
     
  46. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    @ASGS_DumbFox,

    Thanks for reporting this! (And for the example model, screenshots, and troubleshooting hints!)

    My suspicion is that it has something to do with the transformation from glTF right-handed coordinates to Unity left-handed coordinates.

    Currently I am troubleshooting the DracoUnity 3.x orientation changes, and this problem seems kind of related. With any luck, I'll be able to fix both problems in one go.

    I'll let you know when it's fixed!
     
  47. ASGS_DumbFox

    ASGS_DumbFox

    Joined:
    Sep 23, 2017
    Posts:
    22
    Thanks for the quick response! I'll keep an eye out for a fix and let you know if we come across anything else.
     
  48. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    Piglet 1.3.1 released!

    Hi everyone :)

    Today's 1.3.1 release provides important compatibility fixes for the recently released DracoUnity 2.x/3.x versions. It is now safe (and recommended) to use the latest version of DracoUnity with Piglet, which is currently DracoUnity 3.0.3. (Previously, using DracoUnity 2.x/3.x with Piglet 1.3.0 would result in "unfreed collections" errors and/or incorrect GameObject orientations.)

    I usually don't make announcements for bugfix releases, but since a lot of you have expressed interest in Draco, I wanted to let you know about this fix. So far I haven't noticed any significant performance gains with DracoUnity 2.x/3.x (at least not in the context of Piglet), but at least you no longer need to pin to DracoUnity 1.4.0.

    Also, I've updated the web demo to use Piglet 1.3.1 and DracoUnity 3.0.3 now.

    Happy coding!

    Shout-outs

    @tteneder: Thanks again for your help with adjusting to the API changes!

    @DerrickBarra, @Makio64, @Pode, @ASGS_DumbFox: CC'ing you since you expressed interest in Draco support.

    @ASGS_DumbFox: Sorry, but I have not solved the issue with your Kratos model yet. You are right that the problem is triggered by the use of negative scales. The bug also seems to be limited to the case where the glTF node transforms are specified using matrices rather than separate translation/rotation/scale vectors. I consider this to be an important bug and I will keep working on it.
     
    Last edited: Jun 16, 2021
    tteneder likes this.
  49. DerrickBarra

    DerrickBarra

    Joined:
    Nov 19, 2013
    Posts:
    210
    Awesome, we'll let you know if we run into any bugs after the update.
     
  50. awesomesaucelabs

    awesomesaucelabs

    Joined:
    Aug 6, 2019
    Posts:
    191
    Thanks, @DerrickBarra!

    Updating is not urgent since the Piglet 1.3.0 / DracoUnity 1.4.0 combo works fine too.