From 08f95cd7207033cc860a28f8fff37c8b95131500 Mon Sep 17 00:00:00 2001 From: chenmiwei Date: Mon, 27 Sep 2021 18:26:17 +0800 Subject: [PATCH] import lights --- .../USD.NET.Unity/Geometry/LightSample.cs | 153 ++++++++++++++++++ .../Scripts/IO/Geometry/LightExporter.cs | 0 .../Scripts/IO/Geometry/LightImporter.cs | 18 +++ .../Scripts/IO/Scene/HierarchyBuilder.cs | 17 +- .../Runtime/Scripts/IO/Scene/PrimMap.cs | 8 + .../Scripts/IO/Scene/SceneImportOptions.cs | 1 + .../Runtime/Scripts/IO/Scene/SceneImporter.cs | 36 +++++ 7 files changed, 231 insertions(+), 2 deletions(-) create mode 100644 package/com.unity.formats.usd/Dependencies/USD.NET.Unity/Geometry/LightSample.cs create mode 100644 package/com.unity.formats.usd/Runtime/Scripts/IO/Geometry/LightExporter.cs create mode 100644 package/com.unity.formats.usd/Runtime/Scripts/IO/Geometry/LightImporter.cs diff --git a/package/com.unity.formats.usd/Dependencies/USD.NET.Unity/Geometry/LightSample.cs b/package/com.unity.formats.usd/Dependencies/USD.NET.Unity/Geometry/LightSample.cs new file mode 100644 index 000000000..5ef05a2cd --- /dev/null +++ b/package/com.unity.formats.usd/Dependencies/USD.NET.Unity/Geometry/LightSample.cs @@ -0,0 +1,153 @@ +using UnityEngine; + +namespace USD.NET.Unity +{ + [System.Serializable] + public class LightSampleBase : XformSample + { + public LightSampleBase() + { + } + + public virtual void CopyFromLight(UnityEngine.Light light, bool convertTransformToUsd = true) + { + var tr = light.transform; + transform = UnityEngine.Matrix4x4.TRS(tr.localPosition, + tr.localRotation, + tr.localScale); + if (convertTransformToUsd) + { + ConvertTransform(); + } + } + + public virtual void CopyToLight(UnityEngine.Light light, bool setTransform) + { + if (setTransform) + { + var tr = light.transform; + var xf = transform; + UnityTypeConverter.SetTransform(xf, tr); + } + } + } + + [System.Serializable] + [UsdSchema("DistantLight")] + public class DistantLightSample : LightSampleBase + { + // Core Light parameters + public float angle; + public float intensity; + + public DistantLightSample() + { + } + + public DistantLightSample(UnityEngine.Light fromLight) + { + CopyFromLight(fromLight); + } + + override public void CopyFromLight(UnityEngine.Light light, bool convertTransformToUsd = true) + { + intensity = light.intensity; + base.CopyFromLight(light, convertTransformToUsd); + } + + override public void CopyToLight(UnityEngine.Light light, bool setTransform) + { + light.type = LightType.Directional; + light.intensity = intensity; + base.CopyToLight(light, setTransform); + } + } + + [System.Serializable] + [UsdSchema("SphereLight")] + public class SphereLightSample : LightSampleBase + { + // Core Light parameters + public bool treatAsPoint; + public float radius; + + [UsdNamespace("shaping:cone")] + public float angle; + + public SphereLightSample() + { + } + + public SphereLightSample(UnityEngine.Light fromLight) + { + CopyFromLight(fromLight); + } + + override public void CopyFromLight(UnityEngine.Light light, bool convertTransformToUsd = true) + { + treatAsPoint = true; + radius = light.range; + if (light.spotAngle > 0) + { + angle = light.spotAngle; + } + base.CopyFromLight(light, convertTransformToUsd); + } + + override public void CopyToLight(UnityEngine.Light light, bool setTransform) + { + if (angle > 0) + { + light.type = LightType.Spot; + light.spotAngle = angle; + } + else + { + light.type = LightType.Point; + } + + light.range = radius; + base.CopyToLight(light, setTransform); + } + } + + [System.Serializable] + [UsdSchema("RectLight")] + public class RectLightSample : LightSampleBase + { + public RectLightSample() + { + } + + public RectLightSample(UnityEngine.Light fromLight) + { + base.CopyFromLight(fromLight); + } + + override public void CopyToLight(UnityEngine.Light light, bool setTransform) + { + light.type = LightType.Rectangle; + base.CopyToLight(light, setTransform); + } + } + + [System.Serializable] + [UsdSchema("DiskLight")] + public class DiskLightSample : LightSampleBase + { + public DiskLightSample() + { + } + + public DiskLightSample(UnityEngine.Light fromLight) + { + base.CopyFromLight(fromLight); + } + + override public void CopyToLight(UnityEngine.Light light, bool setTransform) + { + light.type = LightType.Disc; + base.CopyToLight(light, setTransform); + } + } +} \ No newline at end of file diff --git a/package/com.unity.formats.usd/Runtime/Scripts/IO/Geometry/LightExporter.cs b/package/com.unity.formats.usd/Runtime/Scripts/IO/Geometry/LightExporter.cs new file mode 100644 index 000000000..e69de29bb diff --git a/package/com.unity.formats.usd/Runtime/Scripts/IO/Geometry/LightImporter.cs b/package/com.unity.formats.usd/Runtime/Scripts/IO/Geometry/LightImporter.cs new file mode 100644 index 000000000..93de91a3b --- /dev/null +++ b/package/com.unity.formats.usd/Runtime/Scripts/IO/Geometry/LightImporter.cs @@ -0,0 +1,18 @@ + + +using UnityEngine; +using USD.NET.Unity; + +namespace Unity.Formats.USD +{ + public static class LightImporter where T : LightSampleBase + { + public static void BuildLight(T usdLight, + GameObject go, + SceneImportOptions options) + { + var light = ImporterBase.GetOrAddComponent(go); + usdLight.CopyToLight(light, setTransform: false); + } + } +} \ No newline at end of file diff --git a/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/HierarchyBuilder.cs b/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/HierarchyBuilder.cs index 13250da71..f3ab622e9 100644 --- a/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/HierarchyBuilder.cs +++ b/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/HierarchyBuilder.cs @@ -133,8 +133,8 @@ static JobHandle BeginReading(Scene scene, { FindPathsJob.usdRoot = usdRoot; FindPathsJob.scene = scene; - FindPathsJob.results = new SdfPath[9][]; - FindPathsJob.queries = new FindPathsJob.IQuery[9]; + FindPathsJob.results = new SdfPath[13][]; + FindPathsJob.queries = new FindPathsJob.IQuery[13]; if (options.ShouldBindMaterials) { @@ -167,6 +167,15 @@ static JobHandle BeginReading(Scene scene, FindPathsJob.queries[8] = (FindPathsJob.IQuery) new FindPathsJob.Query(); + if (options.importLights) + { + FindPathsJob.queries[9] = (FindPathsJob.IQuery) new FindPathsJob.Query(); + FindPathsJob.queries[10] = (FindPathsJob.IQuery) new FindPathsJob.Query(); + FindPathsJob.queries[11] = (FindPathsJob.IQuery) new FindPathsJob.Query(); + FindPathsJob.queries[12] = (FindPathsJob.IQuery) new FindPathsJob.Query(); + + } + var findPathsJob = new FindPathsJob(); var findHandle = findPathsJob.Schedule(FindPathsJob.queries.Length, 1); findHandle.Complete(); @@ -185,6 +194,10 @@ static JobHandle BeginReading(Scene scene, map.SkelRoots = FindPathsJob.results[5]; map.Skeletons = FindPathsJob.results[6]; map.Xforms = FindPathsJob.results[7]; + map.DirectionalLights = FindPathsJob.results[9]; + map.SphereLights = FindPathsJob.results[10]; + map.RectLights = FindPathsJob.results[11]; + map.DiscLights = FindPathsJob.results[12]; ReadHierJob.paths = FindPathsJob.results.Where(i => i != null).SelectMany(i => i).ToArray(); ReadHierJob.result = new HierInfo[ReadHierJob.paths.Length]; diff --git a/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/PrimMap.cs b/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/PrimMap.cs index 8466ad37e..8873d8ecb 100644 --- a/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/PrimMap.cs +++ b/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/PrimMap.cs @@ -47,6 +47,10 @@ public struct InstanceRoot public SdfPath[] SkelRoots { get; set; } public SdfPath[] Skeletons { get; set; } public SdfPath[] Materials { get; set; } + public SdfPath[] DirectionalLights { get; set; } + public SdfPath[] SphereLights { get; set; } + public SdfPath[] RectLights { get; set; } + public SdfPath[] DiscLights { get; set; } // Normal objects in the hierarchy. private Dictionary m_prims = new Dictionary(); @@ -166,6 +170,10 @@ public void Clear() SkelRoots = null; Skeletons = null; Materials = null; + DirectionalLights = null; + SphereLights = null; + RectLights = null; + DiscLights = null; } } } diff --git a/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/SceneImportOptions.cs b/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/SceneImportOptions.cs index 339c99cab..c976d47bf 100644 --- a/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/SceneImportOptions.cs +++ b/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/SceneImportOptions.cs @@ -100,6 +100,7 @@ public class SceneImportOptions public bool importHierarchy = true; public bool importCameras = true; + public bool importLights = true; public bool importMeshes = true; public bool importSkinning = true; public bool importSkinWeights = true; diff --git a/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/SceneImporter.cs b/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/SceneImporter.cs index 52b5ae28a..5b558a247 100644 --- a/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/SceneImporter.cs +++ b/package/com.unity.formats.usd/Runtime/Scripts/IO/Scene/SceneImporter.cs @@ -750,6 +750,42 @@ public static IEnumerator BuildScene(Scene scene, Profiler.EndSample(); } + // Lights. + if (importOptions.importLights) + { + Profiler.BeginSample("USD: Lights"); + + void importLights(pxr.SdfPath[] dest) where T : LightSampleBase, new() + { + foreach (var pathAndSample in scene.ReadAll(dest)) + { + try + { + GameObject go = primMap[pathAndSample.path]; + NativeImporter.ImportObject(scene, go, scene.GetPrimAtPath(pathAndSample.path), importOptions); + XformImporter.BuildXform(pathAndSample.path, pathAndSample.sample, go, importOptions, scene); + + if (scene.AccessMask == null || scene.IsPopulatingAccessMask) + { + LightImporter.BuildLight(pathAndSample.sample, go, importOptions); + } + } + catch (System.Exception ex) + { + Debug.LogException( + new ImportException("Error processing light <" + pathAndSample.path + ">", ex)); + } + } + } + + importLights(primMap.DirectionalLights); + importLights(primMap.SphereLights); + importLights(primMap.RectLights); + importLights(primMap.DiscLights); + + Profiler.EndSample(); + } + // Build out masters for instancing. Profiler.BeginSample("USD: Build Instances"); foreach (var masterRootPath in primMap.GetMasterRootPaths())