atteneder / DracoUnity

Draco 3D Data Compression Unity Package
Apache License 2.0
247 stars 40 forks source link

Draco 3D Data Compression Unity Package

openupm GitHub issues GitHub license

Unity package that integrates the Draco 3D data compression library within Unity.

Screenshot of loaded bunny meshes

Following build targets are supported

Note: Burst support is broken on iOS builds at the moment. Please deactivate Burst AOT in the project settings until this is resolved.

Installing

The easiest way to install is to download and open the Installer Package

It runs a script that installs the Draco 3D Data Compression Unity Package via a scoped registry. After that it is listed in the Package Manager and can be updated from there.

Alternative: Install via GIT URL You have to manually add the package's URL into your [project manifest](https://docs.unity3d.com/Manual/upm-manifestPrj.html) Inside your Unity project there's the folder `Packages` containing a file called `manifest.json`. You have to open it and add the following line inside the `dependencies` category: ```json "com.atteneder.draco": "https://github.com/atteneder/DracoUnity.git", ``` It should look something like this: ```json { "dependencies": { "com.atteneder.draco": "https://github.com/atteneder/DracoUnity.git", "com.unity.package-manager-ui": "2.1.2", "com.unity.modules.unitywebrequest": "1.0.0" ... } } ``` Next time you open your project in Unity, it will download the package automatically. You have to have a GIT LFS client (large file support) installed on your system. Otherwise you will get an error that the native library file (dll on Windows) is corrupt. There's more detail about how to add packages via GIT URLs in the [Unity documentation](https://docs.unity3d.com/Manual/upm-git.html).

Using

Mesh result

Minimalistic way of loading a draco file (source):

public class DracoDemo : MonoBehaviour {

    public string filePath;

    async void Start() {

        // Load file into memory
        var fullPath = Path.Combine(Application.streamingAssetsPath, filePath);
        var data = File.ReadAllBytes(fullPath);

        // Convert data to Unity mesh
        var draco = new DracoMeshLoader();
        // Async decoding has to start on the main thread and spawns multiple C# jobs.
        var mesh = await draco.ConvertDracoMeshToUnity(data);

        if (mesh != null) {
            // Use the resulting mesh
            GetComponent<MeshFilter>().mesh= mesh;
        }
    }
}

Using MeshDataArray

Starting with Unity 2020.2 you can create Meshes efficiently via MeshDataArray.

The important difference is that instead of returning a Mesh directly, it just configures the MeshData properly and fills its buffers. It's up to the user to:

Here's an examply how to do this (source):

public class DracoDemoMeshData : MonoBehaviour {

    public string filePath;

    public bool requireNormals;
    public bool requireTangents;

    async void Start() {

        // Load file into memory
        var fullPath = Path.Combine(Application.streamingAssetsPath, filePath);
        var data = File.ReadAllBytes(fullPath);

        // Convert data to Unity mesh
        var draco = new DracoMeshLoader();

        // Allocate single mesh data (you can/should bulk allocate multiple at once, if you're loading multiple draco meshes) 
        var meshDataArray = Mesh.AllocateWritableMeshData(1);

        // Async decoding has to start on the main thread and spawns multiple C# jobs.
        var result = await draco.ConvertDracoMeshToUnity(
            meshDataArray[0],
            data,
            requireNormals, // Set to true if you require normals. If Draco data does not contain them, they are allocated and we have to calculate them below
            requireTangents // Retrieve tangents is not supported, but this will ensure they are allocated and can be calculated later (see below)
            );

        if (result.success) {

            // Apply onto new Mesh
            var mesh = new Mesh();
            Mesh.ApplyAndDisposeWritableMeshData(meshDataArray,mesh);

            // If Draco mesh has bone weigths, apply them now.
            // To get these, you have to supply the correct attribute IDs
            // to `ConvertDracoMeshToUnity` above (optional paramters).
            if (result.boneWeightData != null) {
                result.boneWeightData.ApplyOnMesh(mesh);
                result.boneWeightData.Dispose();
            }

            if (result.calculateNormals) {
                // If draco didn't contain normals, calculate them.
                mesh.RecalculateNormals();
            }
            if (requireTangents) {
                // If required (e.g. for consistent specular shading), calculate tangents
                mesh.RecalculateTangents();
            }

            // Use the resulting mesh
            GetComponent<MeshFilter>().mesh = mesh;
        }
    }
}

Details and where to go next

See the signatures of all DracoMeshLoader.ConvertDracoMeshToUnity variants to see all options available.

The examples above and more can be found in the DracoUnityDemo project.

Troubleshooting - Missing code signing

The binary libraries used in this package are not code-signed. macOS in particular will not let you load the ktx_unity.bundle for that reason (see issue).

Here's the steps to make it work on macOS

  1. When you first open a project with DracoUnity (or add the package), you get prompted to remove the "broken" ktx_unity.bundle. Don't do it and click "cancel" instead.
  2. Open the macOS "System Preferencess" and go to "Security & Privacy". At the bottom of the "General" tab you should see a warning about ktx_unity.bundle. Click the "Allow anyways" button besides it.
  3. Restart Unity
  4. Now you get another, similar prompt (see step 1) with the third option "Open". Click it
  5. Now it should work (at least for development on your machine)

If you want to deploy your software using DracoUnity you either have to

Origin

This project is a fork of the existing Unity integration

Differences

Support

Like this demo? You can show your appreciation and ...

Buy me a coffee

Develop

To develop this package, check out the repository and add it as local repository in the Unity Package Manager.

Build Draco library

The native libraries are built via CI in this GitHub action

Look into the YAML file to see how the project is built with CMake.

License

Copyright (c) 2019 Andreas Atteneder, All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use files in this repository except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Third party notice

Builds upon and includes builds of Google's Draco 3D data compression library (released under the terms of Apache License 2.0).