public static void TestVisibility() { var sample = new USD.NET.Unity.MeshSample(); var outSample = new USD.NET.Unity.MeshSample(); sample.visibility = USD.NET.Visibility.Invisible; WriteAndRead(ref sample, ref outSample, true); AssertEqual(sample.visibility, outSample.visibility); }
// Copy mesh data to Unity and assign mesh with material. void BuildMesh(USD.NET.Unity.MeshSample usdMesh, GameObject go) { var mf = go.AddComponent <MeshFilter>(); var mr = go.AddComponent <MeshRenderer>(); var unityMesh = new UnityEngine.Mesh(); var mat = Material.Instantiate(m_material); unityMesh.vertices = usdMesh.points; // Triangulate n-gons. // For best performance, triangulate off-line and skip conversion. var indices = USD.NET.Unity.UnityTypeConverter.ToVtArray(usdMesh.faceVertexIndices); var counts = USD.NET.Unity.UnityTypeConverter.ToVtArray(usdMesh.faceVertexCounts); pxr.UsdGeomMesh.Triangulate(indices, counts); USD.NET.Unity.UnityTypeConverter.FromVtArray(indices, ref usdMesh.faceVertexIndices); if (usdMesh.orientation == Orientation.LeftHanded) { // USD is right-handed, so the mesh needs to be flipped. // Unity is left-handed, but that doesn't matter here. for (int i = 0; i < usdMesh.faceVertexIndices.Length; i += 3) { int tmp = usdMesh.faceVertexIndices[i]; usdMesh.faceVertexIndices[i] = usdMesh.faceVertexIndices[i + 1]; usdMesh.faceVertexIndices[i + 1] = tmp; } } unityMesh.triangles = usdMesh.faceVertexIndices; if (usdMesh.extent.size.x > 0 || usdMesh.extent.size.y > 0 || usdMesh.extent.size.z > 0) { unityMesh.bounds = usdMesh.extent; } else { unityMesh.RecalculateBounds(); } if (usdMesh.normals != null) { unityMesh.normals = usdMesh.normals; } else { unityMesh.RecalculateNormals(); } if (usdMesh.tangents != null) { unityMesh.tangents = usdMesh.tangents; } else { unityMesh.RecalculateTangents(); } if (usdMesh.colors != null) { // NOTE: The following color conversion assumes PlayerSettings.ColorSpace == Linear. // For best performance, convert color space to linear off-line and skip conversion. if (usdMesh.colors.Length == 1) { // Constant color can just be set on the material. mat.color = usdMesh.colors[0].gamma; } else if (usdMesh.colors.Length == usdMesh.points.Length) { // Vertex colors map on to verts. // TODO: move the conversion to C++ and use the color management API. for (int i = 0; i < usdMesh.colors.Length; i++) { usdMesh.colors[i] = usdMesh.colors[i].gamma; } unityMesh.colors = usdMesh.colors; } else { // FaceVarying and uniform both require breaking up the mesh and are not yet handled in this // example. Debug.LogWarning("Uniform (color per face) and FaceVarying (color per vert per face) " + "display color not supported in this example"); } } // As in Unity, UVs are a dynamic type which can be vec2, vec3, or vec4. if (usdMesh.uv != null) { Type uvType = usdMesh.uv.GetType(); if (uvType == typeof(Vector2[])) { unityMesh.SetUVs(0, ((Vector2[])usdMesh.uv).ToList()); } else if (uvType == typeof(Vector3[])) { unityMesh.SetUVs(0, ((Vector3[])usdMesh.uv).ToList()); } else if (uvType == typeof(Vector4[])) { unityMesh.SetUVs(0, ((Vector4[])usdMesh.uv).ToList()); } else { throw new Exception("Unexpected UV type: " + usdMesh.uv.GetType()); } } mr.material = mat; mf.mesh = unityMesh; }
public void SetupScene() { InitUsd.Initialize(); // Is the stage already loaded? if (m_scene != null && m_scene.Stage.GetRootLayer().GetIdentifier() == m_usdFile) { return; } // Does the path exist? if (!System.IO.File.Exists(m_usdFile)) { return; } // Clear out the old scene. UnloadGameObjects(); // Load the new scene. m_scene = Scene.Open(m_usdFile); if (m_scene == null) { throw new Exception("Failed to load"); } // Set the time at which to read samples from USD. m_scene.Time = 0; // Handle configurable up-axis (Y or Z). Vector3 up = GetUpVector(m_scene); var rootXf = new GameObject("root"); rootXf.transform.SetParent(transform, worldPositionStays: false); if (up != Vector3.up) { rootXf.transform.localRotation = Quaternion.FromToRotation(Vector3.up, up); } // Convert from right-handed (USD) to left-handed (Unity). // The math below works out to either (1, -1, 1) or (1, 1, -1), depending on up. rootXf.transform.localScale = up + -1 * (Vector3.one - up - Vector3.right) + Vector3.right; // Assign this transform as the root. m_primMap.Add("/", rootXf); // Load transforms. foreach (var path in m_scene.AllXforms) { var xf = new USD.NET.Unity.XformSample(); m_scene.Read(path, xf); var go = new GameObject(path.GetName()); AssignTransform(xf, go); AssignParent(path, go); } // Load meshes. foreach (var path in m_scene.AllMeshes) { var mesh = new USD.NET.Unity.MeshSample(); m_scene.Read(path, mesh); var go = new GameObject(path.GetName()); AssignTransform(mesh, go); AssignParent(path, go); BuildMesh(mesh, go); } // Load cameras. foreach (var prim in m_scene.Stage.GetAllPrimsByType("Camera")) { pxr.UsdGeomCamera camera = new pxr.UsdGeomCamera(prim); var go = new GameObject(prim.GetName()); var xf = new USD.NET.Unity.XformSample(); m_scene.Read(prim.GetPath(), xf); AssignTransform(xf, go); BuildCamera(camera, go); AssignParent(prim.GetPath(), go); } // Ensure the file and the identifier match. m_usdFile = m_scene.Stage.GetRootLayer().GetIdentifier(); }
void Update() { if (string.IsNullOrEmpty(m_usdFile)) { if (m_scene == null) { return; } m_scene.Close(); m_scene = null; UnloadGameObjects(); return; } // Is the stage already loaded? if (m_scene != null && m_scene.Stage.GetRootLayer().GetIdentifier() == m_usdFile) { return; } // Does the path exist? if (!System.IO.File.Exists(m_usdFile)) { return; } // Clear out the old scene. UnloadGameObjects(); // Import the new scene. m_scene = Scene.Open(m_usdFile); if (m_scene == null) { throw new Exception("Failed to import"); } // Set the time at which to read samples from USD. m_scene.Time = m_usdTime; // Handle configurable up-axis (Y or Z). Vector3 up = GetUpVector(m_scene); var rootXf = new GameObject("root"); if (up != Vector3.up) { rootXf.transform.localRotation = Quaternion.FromToRotation(Vector3.up, up); } // Convert from right-handed (USD) to left-handed (Unity). // The math below works out to either (1, -1, 1) or (1, 1, -1), depending on up. rootXf.transform.localScale = -1 * up + -1 * (Vector3.one - up); // Assign this transform as the root. m_primMap.Add("/", rootXf); // Import transforms. foreach (var path in m_scene.AllXforms) { var xf = new USD.NET.Unity.XformSample(); m_scene.Read(path, xf); var go = new GameObject(path.GetName()); AssignTransform(xf, go); AssignParent(path, go); } // Import meshes. foreach (var path in m_scene.AllMeshes) { var mesh = new USD.NET.Unity.MeshSample(); m_scene.Read(path, mesh); var go = new GameObject(path.GetName()); AssignTransform(mesh, go); AssignParent(path, go); BuildMesh(mesh, go); } // Ensure the file and the identifier match. m_usdFile = m_scene.Stage.GetRootLayer().GetIdentifier(); }