예제 #1
0
        // ------------------------------------------------------------------------------------------ //
        // Main Export Logic.
        // ------------------------------------------------------------------------------------------ //

        public static void Export(GameObject root,
                                  Scene scene,
                                  BasisTransformation basisTransform,
                                  bool exportUnvarying,
                                  bool zeroRootTransform,
                                  bool exportMaterials      = false,
                                  bool exportMonoBehaviours = false)
        {
            var context = new ExportContext();

            context.scene          = scene;
            context.basisTransform = basisTransform;
            context.exportRoot     = root.transform.parent;
            SyncExportContext(root, context);

            // Since this is a one-shot convenience function, we will automatically split the export
            // into varying and unvarying data, unless the user explicitly requested unvarying.
            if (exportUnvarying && scene.Time != null)
            {
                double?oldTime = scene.Time;
                scene.Time = null;
                Export(root, context, zeroRootTransform);
                scene.Time = oldTime;
            }

            // Export data for the requested time.
            context.exportMaterials = exportMaterials;
            Export(root, context, zeroRootTransform);
        }
예제 #2
0
        static void ExportSelected(BasisTransformation basisTransform,
                                   string fileExtension      = "usd",
                                   bool exportMonoBehaviours = false)
        {
            Scene scene = null;

            foreach (GameObject go in Selection.gameObjects)
            {
                if (scene == null)
                {
                    scene = InitForSave(go.name, fileExtension);
                    if (scene == null)
                    {
                        return;
                    }
                }

                try {
                    SceneExporter.Export(go, scene, basisTransform,
                                         exportUnvarying: true, zeroRootTransform: false,
                                         exportMonoBehaviours: exportMonoBehaviours);
                } catch (System.Exception ex) {
                    Debug.LogException(ex);
                    continue;
                }
            }

            if (scene != null)
            {
                scene.Save();
                scene.Close();
            }
        }
 public static void Export(GameObject root,
                           Scene scene,
                           BasisTransformation basisTransform)
 {
     SceneExporter.Export(root, scene, basisTransform,
                          exportUnvarying: true, zeroRootTransform: false);
 }
        public static void WriteSparseOverrides(Scene scene,
                                                PrimMap primMap,
                                                BasisTransformation changeHandedness,
                                                float tolerance = 0.0001f)
        {
            var oldMode = scene.WriteMode;

            scene.WriteMode = Scene.WriteModes.Over;

            try
            {
                foreach (var path in scene.Find <XformableSample>())
                {
                    GameObject go;
                    if (!primMap.TryGetValue(path, out go))
                    {
                        continue;
                    }

                    var tx    = go.transform;
                    var xfNew = XformSample.FromTransform(tx);
                    var xfOld = new XformSample();

                    scene.Read(path, xfOld);

                    bool areClose = true;
                    for (int i = 0; i < 16; i++)
                    {
                        if (Mathf.Abs(xfNew.transform[i] - xfOld.transform[i]) > tolerance)
                        {
                            areClose = false;
                            break;
                        }
                    }

                    if (areClose)
                    {
                        continue;
                    }

                    if (changeHandedness == BasisTransformation.SlowAndSafe)
                    {
                        xfNew.ConvertTransform();
                    }

                    scene.Write(path, xfNew);
                }
            }
            finally
            {
                scene.WriteMode = oldMode;
            }
        }
예제 #5
0
        /// <summary>
        /// Convert the SceneImportOptions to a serializable form.
        /// </summary>
        public void OptionsToState(SceneImportOptions options)
        {
            m_usdRootPath      = options.usdRootPath;
            m_projectAssetPath = options.projectAssetPath;
            m_changeHandedness = options.changeHandedness;
            m_scale            = options.scale;
            m_interpolation    = options.interpolate ?
                                 Scene.InterpolationMode.Linear :
                                 Scene.InterpolationMode.Held;

            // Scenegraph options.
            m_payloadPolicy        = options.payloadPolicy;
            m_importCameras        = options.importCameras;
            m_importMeshes         = options.importMeshes;
            m_importSkinning       = options.importSkinning;
            m_importHierarchy      = options.importHierarchy;
            m_importTransforms     = options.importTransforms;
            m_importSceneInstances = options.importSceneInstances;
            m_importPointInstances = options.importPointInstances;
            m_importMonoBehaviors  = options.importMonoBehaviours;

            // Mesh options.
            m_points              = options.meshOptions.points;
            m_topology            = options.meshOptions.topology;
            m_boundingBox         = options.meshOptions.boundingBox;
            m_color               = options.meshOptions.color;
            m_normals             = options.meshOptions.normals;
            m_tangents            = options.meshOptions.tangents;
            m_st                  = options.meshOptions.texcoord0;
            m_texcoord1           = options.meshOptions.texcoord1;
            m_texcoord2           = options.meshOptions.texcoord2;
            m_texcoord3           = options.meshOptions.texcoord3;
            m_generateLightmapUVs = options.meshOptions.generateLightmapUVs;

            m_unwrapAngleError = options.meshOptions.unwrapAngleError;
            m_unwrapAreaError  = options.meshOptions.unwrapAreaError;
            m_unwrapHardAngle  = options.meshOptions.unwrapHardAngle;
            m_unwrapPackMargin = options.meshOptions.unwrapPackMargin;

            m_debugShowSkeletonBindPose = options.meshOptions.debugShowSkeletonBindPose;
            m_debugShowSkeletonRestPose = options.meshOptions.debugShowSkeletonRestPose;

            // Materials & instancing.
            m_useOriginalShaderIfAvailable = options.materialMap.useOriginalShaderIfAvailable;
            m_materialImportMode           = options.materialImportMode;
            m_enableGpuInstancing          = options.enableGpuInstancing;
            m_displayColorMaterial         = options.materialMap.DisplayColorMaterial;
            m_specularWorkflowMaterial     = options.materialMap.SpecularWorkflowMaterial;
            m_metallicWorkflowMaterial     = options.materialMap.MetallicWorkflowMaterial;
        }
예제 #6
0
        private GameObject LoadUSD(Object usdObject, BasisTransformation changeHandedness = BasisTransformation.SlowAndSafeAsFBX)
        {
            InitUsd.Initialize();
            var usdPath       = Path.GetFullPath(AssetDatabase.GetAssetPath(usdObject));
            var stage         = pxr.UsdStage.Open(usdPath, pxr.UsdStage.InitialLoadSet.LoadNone);
            var scene         = Scene.Open(stage);
            var importOptions = new SceneImportOptions();

            importOptions.changeHandedness   = changeHandedness;
            importOptions.scale              = 0.01f;
            importOptions.materialImportMode = MaterialImportMode.ImportDisplayColor;
            var usdRoot = ImportHelpers.ImportSceneAsGameObject(scene, importOptions: importOptions);

            scene.Close();
            return(usdRoot);
        }
예제 #7
0
        public static Matrix4x4 GetLocalTransformMatrix(
            Transform tr,
            bool correctZUp,
            bool isRootPrim,
            BasisTransformation conversionType)
        {
            var  localRot    = tr.localRotation;
            bool fastConvert = conversionType == BasisTransformation.FastWithNegativeScale;

            if (correctZUp && isRootPrim)
            {
                float invert = fastConvert ? 1 : -1;
                localRot = localRot * Quaternion.AngleAxis(invert * 90, Vector3.right);
            }

            var mat = Matrix4x4.TRS(tr.localPosition, localRot, tr.localScale);

            // Unity uses a forward vector that matches DirectX, but USD matches OpenGL, so a change of
            // basis is required. There are shortcuts, but this is fully general.
            //
            // Here we can either put a partial conversion at the root (fast & dangerous) or convert the
            // entire hierarchy, along with the points, normals and triangle winding. The benefit of the
            // full conversion is that there are no negative scales left in the hierarchy.
            //
            // Note that this is the correct partial conversion for the root transforms, however the
            // camera and light matrices must contain the other half of the conversion
            // (e.g. mat * basisChangeInverse).
            if (fastConvert && isRootPrim)
            {
                // Partial change of basis.
                var basisChange = Matrix4x4.identity;
                // Invert the forward vector.
                basisChange[2, 2] = -1;
                mat = basisChange * mat;
            }
            else if (!fastConvert)
            {
                // Full change of basis.
                mat = UnityTypeConverter.ChangeBasis(mat);
            }

            return(mat);
        }
        public static void ExportGameObjects(GameObject[] objects, Scene scene, BasisTransformation basisTransform,
                                             bool exportMonoBehaviours = false)
        {
            if (scene == null)
            {
                return;
            }

            foreach (GameObject go in objects)
            {
                try
                {
                    SceneExporter.Export(go, scene, basisTransform,
                                         exportUnvarying: true, zeroRootTransform: false,
                                         exportMonoBehaviours: exportMonoBehaviours);
                }
                catch (System.Exception ex)
                {
                    Debug.LogException(ex);
                }
            }
            scene.Save();
            scene.Close();
        }
예제 #9
0
        public void TestLeftHandedUsdMeshImport(BasisTransformation basisTransformation)
        {
            // set the baked mesh according to the basis transformation
            Object bakedLeftHandedMesh = null;

            switch (basisTransformation)
            {
            case BasisTransformation.SlowAndSafe:
                bakedLeftHandedMesh = bakedLeftHandedCube_slowAndSafe;
                break;

            case BasisTransformation.SlowAndSafeAsFBX:
                bakedLeftHandedMesh = bakedLeftHandedCube_slowAndSafeAsFbx;
                break;

            case BasisTransformation.None:
            case BasisTransformation.FastWithNegativeScale:
                // When comparing the mesh, importing with FastWithNegativeScale and None
                // will give the same result.
                bakedLeftHandedMesh = bakedLeftHandedCube_none;
                break;

            default:
                throw new System.NotImplementedException();
            }

            var rightHandedUsdRoot = LoadUSD(withCameraUsd, basisTransformation);

            Assert.IsNotNull(rightHandedUsdRoot);

            // Compare import of Left handed USD to right handed USD
            var leftHandedUsdRoot = LoadUSD(leftHandedWithCameraUsd, basisTransformation);

            Assert.IsNotNull(leftHandedUsdRoot);

            // check that the mesh does not match the right handed one
            var usdCube = rightHandedUsdRoot.transform.Find("group2/group1/pCube1");

            Assert.IsNotNull(usdCube);
            var leftHandedUsdCube = leftHandedUsdRoot.transform.Find("group2/group1/pCube1");

            Assert.IsNotNull(leftHandedUsdCube);

            var cubeMesh           = usdCube.GetComponent <MeshFilter>().sharedMesh;
            var leftHandedCubeMesh = leftHandedUsdCube.GetComponent <MeshFilter>().sharedMesh;

            // The two files are different handedness (different winding order of vertices), therefore the triangles
            // will be different, the vertices will remain the same and the normals will be flipped.
            NUnit.Framework.Assert.That(leftHandedCubeMesh.vertices.Length, Is.EqualTo(cubeMesh.vertices.Length));
            for (int i = 0; i < cubeMesh.vertices.Length; i++)
            {
                Assert.IsTrue(CheckVector3Equality(leftHandedCubeMesh.vertices[i], cubeMesh.vertices[i]),
                              string.Format("Vertex at index {0} of left and right handed cube mesh are not equal, expected equal:\nExpected:{1}\nActual:{2}",
                                            i, cubeMesh.vertices[i], leftHandedCubeMesh.vertices[i]));
            }
            NUnit.Framework.Assert.That(cubeMesh.triangles, Is.Not.EqualTo(leftHandedCubeMesh.triangles));

            NUnit.Framework.Assert.That(leftHandedCubeMesh.normals.Length, Is.EqualTo(cubeMesh.normals.Length));
            for (int i = 0; i < cubeMesh.normals.Length; i++)
            {
                // check that normals are flipped
                Assert.IsTrue(CheckVector3Equality(leftHandedCubeMesh.normals[i], -cubeMesh.normals[i]),
                              string.Format("Normal at index {0} of left and right handed cube mesh are not equal, expected equal\nExpected:{1}\nActual:{2}",
                                            i, -cubeMesh.normals[i], leftHandedCubeMesh.normals[i]));
            }

            // Check that the imported left handed cube matches the baked cube.
            var bakedCubeMesh = bakedLeftHandedMesh as Mesh;

            Assert.IsNotNull(bakedCubeMesh);

            NUnit.Framework.Assert.That(leftHandedCubeMesh.vertices.Length, Is.EqualTo(bakedCubeMesh.vertices.Length));
            for (int i = 0; i < bakedCubeMesh.vertices.Length; i++)
            {
                Assert.IsTrue(CheckVector3Equality(leftHandedCubeMesh.vertices[i], bakedCubeMesh.vertices[i]),
                              string.Format("Vertex at index {0} of left handed and baked cube mesh are not equal, expected equal:\nExpected:{1}\nActual:{2}",
                                            i, bakedCubeMesh.vertices[i], leftHandedCubeMesh.vertices[i]));
            }
            NUnit.Framework.Assert.That(bakedCubeMesh.triangles, Is.EqualTo(leftHandedCubeMesh.triangles));

            NUnit.Framework.Assert.That(leftHandedCubeMesh.normals.Length, Is.EqualTo(bakedCubeMesh.normals.Length));
            for (int i = 0; i < bakedCubeMesh.normals.Length; i++)
            {
                Assert.IsTrue(CheckVector3Equality(leftHandedCubeMesh.normals[i], bakedCubeMesh.normals[i]),
                              string.Format("Normal at index {0} of left handed and baked cube mesh are not equal, expected equal:\nExpected:{1}\nActual:{2}",
                                            i, bakedCubeMesh.normals[i], leftHandedCubeMesh.normals[i]));
            }
        }