// ------------------------------------------------------------------------------------------ // // 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); }
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; } }
/// <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; }
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); }
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(); }
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])); } }