From 05fa5e6c225c764a91049726dceb2bac8269ab88 Mon Sep 17 00:00:00 2001 From: soupday <79094830+soupday@users.noreply.github.com> Date: Mon, 12 Dec 2022 11:02:54 +0000 Subject: [PATCH] 1.4.2 OSX and linux file path support. Model Import settings adjusted. Mesh Tools only enabled on prefabs instances. Bake material replace fix. Eye occlusion shaders factor in color alpha channel. --- CHANGELOG.md | 7 + Editor/Compute/RLBakeShader.compute | 6 +- Editor/ComputeBake.cs | 25 +- Editor/ImporterMenu.cs | 2 +- Editor/MeshUtil.cs | 412 +++++++++--------- Editor/Pipeline.cs | 2 +- Editor/RL.cs | 53 ++- Editor/StrandHair.cs | 2 +- Editor/Util.cs | 69 ++- ...Template_Baked_EyeOcclusionCustom_HDRP.mat | 3 +- .../RL_Template_Baked_EyeOcclusion_HDRP.mat | 2 +- .../RL_Template_Default_EyeOcclusion_HDRP.mat | 2 +- .../RL_Template_Baked_EyeOcclusion_HDRP_T.mat | 2 +- ..._EyeOcclusionShader_Baked_HDRP.shadergraph | 2 +- .../RL_EyeOcclusionShader_HDRP.shadergraph | 366 +++++++++++++++- Runtime/WeightMapper.cs | 39 +- package.json | 2 +- 17 files changed, 717 insertions(+), 279 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59ab29d..2d115bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ Changelog ========= +### v 1.4.2 +- OSX and Linux file path support. +- Tweaked character model importer settings for better normal import and blend shape normal generation. Should reduce mesh smoothing issues. +- Disabled Menu Mesh Tools when not working on a generated prefab. (The tools cannot operate directly on an FBX) +- Fixed Bake not replacing materials with baked versions. +- Eye Occlusion shaders factor in Occlusion Color alpha value. + ### v 1.4.1 - Traditional material glossiness fix. - High poly (sub-division) hair mesh extraction fix. diff --git a/Editor/Compute/RLBakeShader.compute b/Editor/Compute/RLBakeShader.compute index 9512c2f..32b2e5d 100644 --- a/Editor/Compute/RLBakeShader.compute +++ b/Editor/Compute/RLBakeShader.compute @@ -1448,7 +1448,7 @@ float EyeOcclusionGradient(float2 uv) float alpha2 = saturate(smoothstep(eoTop2Min, eoTop2Max, y) * eoOcclusionStrength2); float edge2 = ((1.0 - eoTearDuctPosition) * eoTearDuctWidth) + eoTearDuctPosition; float tearDuctMask = (1.0 - smoothstep(eoTearDuctPosition, edge2, x)); - return pow(max(alpha1, alpha2) * tearDuctMask, eoOcclusionPower); + return pow(saturate(max(alpha1, alpha2) * tearDuctMask), eoOcclusionPower); } [numthreads(1, 1, 1)] @@ -1458,8 +1458,8 @@ void RLEyeOcclusionDiffuse(uint3 id : SV_DispatchThreadID) float4 alpha = EyeOcclusionGradient(uv); //float4 color = sRGBToLinearApprox(eoEyeOcclusionColor); - float4 color = eoEyeOcclusionColor * alpha; - color.a = alpha; + // premultiply + float4 color = eoEyeOcclusionColor * alpha; Result[id.xy] = color; } diff --git a/Editor/ComputeBake.cs b/Editor/ComputeBake.cs index 7670e25..7410b2f 100644 --- a/Editor/ComputeBake.cs +++ b/Editor/ComputeBake.cs @@ -372,25 +372,26 @@ public void BakeMaterials() if (sourceName.iEndsWith("_2nd_Pass")) continue; bakedMaterial = BakeHairMaterial(sharedMat, sourceName, out firstPass, out secondPass); + } - if (firstPass && secondPass) + if (firstPass && secondPass) + { + ReplaceMaterial(sharedMat, firstPass); + // Get the 2nd pass shared material + foreach (Material secondPassMat in renderer.sharedMaterials) { - ReplaceMaterial(sharedMat, firstPass); - // Get the 2nd pass shared material - foreach (Material secondPassMat in renderer.sharedMaterials) + if (secondPassMat != sharedMat && secondPassMat.name.iEndsWith("_2nd_Pass")) { - if (secondPassMat != sharedMat && secondPassMat.name.iEndsWith("_2nd_Pass")) - { - ReplaceMaterial(secondPassMat, secondPass); - } + ReplaceMaterial(secondPassMat, secondPass); } } - else if (bakedMaterial) - { - ReplaceMaterial(sharedMat, bakedMaterial); - } + } + else if (bakedMaterial) + { + ReplaceMaterial(sharedMat, bakedMaterial); } } + } } } diff --git a/Editor/ImporterMenu.cs b/Editor/ImporterMenu.cs index f1b4d28..f969ef5 100644 --- a/Editor/ImporterMenu.cs +++ b/Editor/ImporterMenu.cs @@ -142,7 +142,7 @@ public static void DoTest() { CharacterInfo ci = ImporterWindow.Current.Character; ComputeBake baker = new ComputeBake(ci.Fbx, ci); - Texture2D gradient = baker.BakeGradientMap("Assets\\Test", "Gradient"); + Texture2D gradient = baker.BakeGradientMap("Assets" + Path.DirectorySeparatorChar + "Test", "Gradient"); } */ } diff --git a/Editor/MeshUtil.cs b/Editor/MeshUtil.cs index fb49d60..e348bff 100644 --- a/Editor/MeshUtil.cs +++ b/Editor/MeshUtil.cs @@ -41,9 +41,9 @@ private static void DoReverse() } [MenuItem("Reallusion/Mesh Tools/Reverse Triangle Order", true)] - private static bool ValudidateDoReverse() + private static bool ValidateDoReverse() { - return Selection.gameObjects.Length > 0; + return Util.IsSavedPrefabInSelection(); } [MenuItem("Reallusion/Mesh Tools/Prune Blend Shapes", priority = 101)] @@ -57,9 +57,9 @@ private static void DoPrune() } [MenuItem("Reallusion/Mesh Tools/Prune Blend Shapes", true)] - private static bool ValudidateDoPrune() + private static bool ValidateDoPrune() { - return Selection.gameObjects.Length > 0; + return Util.IsSavedPrefabInSelection(); } [MenuItem("Reallusion/Mesh Tools/Auto Smooth Mesh", priority = 102)] @@ -83,9 +83,9 @@ private static void DoAutoSmoothMesh() } [MenuItem("Reallusion/Mesh Tools/Auto Smooth Mesh", true)] - private static bool ValudidateDoAutoSmoothMesh() + private static bool ValidateDoAutoSmoothMesh() { - return Selection.gameObjects.Length > 0; + return Util.IsSavedPrefabInSelection(); } [MenuItem("Reallusion/Mesh Tools/Open or Close Character Mouth", priority = 201)] @@ -95,7 +95,7 @@ private static void DoOpenCloseMouth() } [MenuItem("Reallusion/Mesh Tools/Open or Close Character Mouth", true)] - private static bool ValudidateDoOpenCloseMouth() + private static bool ValidateDoOpenCloseMouth() { return WindowManager.IsPreviewScene && WindowManager.GetPreviewScene().GetPreviewCharacter() != null; } @@ -107,7 +107,7 @@ private static void DoOpenCloseEyes() } [MenuItem("Reallusion/Mesh Tools/Open or Close Character Eyes", true)] - private static bool ValudidateDoOpenCloseEyes() + private static bool ValidateDoOpenCloseEyes() { return WindowManager.IsPreviewScene && WindowManager.GetPreviewScene().GetPreviewCharacter() != null; } @@ -119,7 +119,7 @@ private static void DoLookLeft() } [MenuItem("Reallusion/Mesh Tools/Eye/Look Left", true)] - private static bool ValudidateDoLookLeft() + private static bool ValidateDoLookLeft() { return WindowManager.IsPreviewScene && WindowManager.GetPreviewScene().GetPreviewCharacter() != null; } @@ -131,7 +131,7 @@ private static void DoLookRight() } [MenuItem("Reallusion/Mesh Tools/Eye/Look Right", true)] - private static bool ValudidateDoLookRight() + private static bool ValidateDoLookRight() { return WindowManager.IsPreviewScene && WindowManager.GetPreviewScene().GetPreviewCharacter() != null; } @@ -143,7 +143,7 @@ private static void DoLookUp() } [MenuItem("Reallusion/Mesh Tools/Eye/Look Up", true)] - private static bool ValudidateDoLookUp() + private static bool ValidateDoLookUp() { return WindowManager.IsPreviewScene && WindowManager.GetPreviewScene().GetPreviewCharacter() != null; } @@ -155,7 +155,7 @@ private static void DoLookDown() } [MenuItem("Reallusion/Mesh Tools/Eye/Look Down", true)] - private static bool ValudidateDoLookDown() + private static bool ValidateDoLookDown() { return WindowManager.IsPreviewScene && WindowManager.GetPreviewScene().GetPreviewCharacter() != null; } @@ -167,11 +167,43 @@ private static void DoLookForward() } [MenuItem("Reallusion/Mesh Tools/Eye/Look Forward", true)] - private static bool ValudidateDoLookForward() + private static bool ValidateDoLookForward() { return WindowManager.IsPreviewScene && WindowManager.GetPreviewScene().GetPreviewCharacter() != null; } + public static bool GetSourcePrefab(Object obj, string folderName, + out string characterName, out string meshFolder, out Object prefabObject) + { + characterName = ""; + meshFolder = ""; + prefabObject = null; + + if (!obj) return false; + + GameObject fbxAsset = Util.FindRootPrefabAssetFromSceneObject(obj); + + if (!fbxAsset) + { + Debug.LogWarning("Object: " + obj.name + " is not part of an imported CC3/4 character!"); + return false; + } + + prefabObject = PrefabUtility.GetCorrespondingObjectFromSource(obj); + if (!prefabObject || !AssetDatabase.GetAssetPath(prefabObject).iEndsWith(".prefab")) + { + Debug.LogWarning("Object: " + obj.name + " is not part of prefab asset!"); + return false; + } + + string fbxPath = AssetDatabase.GetAssetPath(fbxAsset); + characterName = Path.GetFileNameWithoutExtension(fbxPath); + string fbxFolder = Path.GetDirectoryName(fbxPath); + meshFolder = Path.Combine(fbxFolder, folderName, characterName); + + return true; + } + public static Mesh GetMeshFrom(Object obj) { if (obj.GetType() == typeof(Mesh)) @@ -251,92 +283,86 @@ public static bool ReplaceMesh(Object obj, Mesh mesh) public static void PruneBlendShapes(Object obj) { - if (!obj) return; - - GameObject sceneRoot = Util.GetScenePrefabInstanceRoot(obj); - GameObject asset = PrefabUtility.GetCorrespondingObjectFromSource(sceneRoot); - Object srcObj = PrefabUtility.GetCorrespondingObjectFromSource(obj); - Mesh srcMesh = GetMeshFrom(srcObj); - string path = AssetDatabase.GetAssetPath(asset); - - if (string.IsNullOrEmpty(path)) + if (GetSourcePrefab(obj, PRUNED_FOLDER_NAME, out string characterName, out string meshFolder, out Object srcObj)) { - Util.LogWarn("Object: " + obj.name + " has no source Prefab Asset."); - path = Path.Combine("Assets", "dummy.prefab"); - } + //GameObject sceneRoot = Util.GetScenePrefabInstanceRoot(obj); + //GameObject asset = PrefabUtility.GetCorrespondingObjectFromSource(sceneRoot); + //Object srcObj = PrefabUtility.GetCorrespondingObjectFromSource(obj); + //string path = AssetDatabase.GetAssetPath(asset); - if (!srcMesh) - { - Util.LogError("No mesh found in selected object."); - return; - } + Mesh srcMesh = GetMeshFrom(srcObj); - string folder = Path.GetDirectoryName(path); - string meshFolder = Path.Combine(folder, PRUNED_FOLDER_NAME); + if (!srcMesh) + { + Util.LogError("No mesh found in selected object."); + return; + } + + Mesh dstMesh = new Mesh(); + dstMesh.indexFormat = srcMesh.indexFormat; + dstMesh.vertices = srcMesh.vertices; + dstMesh.uv = srcMesh.uv; + dstMesh.uv2 = srcMesh.uv2; + dstMesh.normals = srcMesh.normals; + dstMesh.colors = srcMesh.colors; + dstMesh.boneWeights = srcMesh.boneWeights; + dstMesh.bindposes = srcMesh.bindposes; + dstMesh.bounds = srcMesh.bounds; + dstMesh.tangents = srcMesh.tangents; + dstMesh.triangles = srcMesh.triangles; + dstMesh.subMeshCount = srcMesh.subMeshCount; + + for (int s = 0; s < srcMesh.subMeshCount; s++) + { + SubMeshDescriptor submesh = srcMesh.GetSubMesh(s); + dstMesh.SetSubMesh(s, submesh); + } - Mesh dstMesh = new Mesh(); - dstMesh.indexFormat = srcMesh.indexFormat; - dstMesh.vertices = srcMesh.vertices; - dstMesh.uv = srcMesh.uv; - dstMesh.uv2 = srcMesh.uv2; - dstMesh.normals = srcMesh.normals; - dstMesh.colors = srcMesh.colors; - dstMesh.boneWeights = srcMesh.boneWeights; - dstMesh.bindposes = srcMesh.bindposes; - dstMesh.bounds = srcMesh.bounds; - dstMesh.tangents = srcMesh.tangents; - dstMesh.triangles = srcMesh.triangles; - dstMesh.subMeshCount = srcMesh.subMeshCount; + // copy any blendshapes across + if (srcMesh.blendShapeCount > 0) + { + Vector3[] deltaVerts = new Vector3[srcMesh.vertexCount]; + Vector3[] deltaNormals = new Vector3[srcMesh.vertexCount]; + Vector3[] deltaTangents = new Vector3[srcMesh.vertexCount]; - for (int s = 0; s < srcMesh.subMeshCount; s++) - { - SubMeshDescriptor submesh = srcMesh.GetSubMesh(s); - dstMesh.SetSubMesh(s, submesh); - } + for (int i = 0; i < srcMesh.blendShapeCount; i++) + { + string name = srcMesh.GetBlendShapeName(i); - // copy any blendshapes across - if (srcMesh.blendShapeCount > 0) - { - Vector3[] deltaVerts = new Vector3[srcMesh.vertexCount]; - Vector3[] deltaNormals = new Vector3[srcMesh.vertexCount]; - Vector3[] deltaTangents = new Vector3[srcMesh.vertexCount]; + int frameCount = srcMesh.GetBlendShapeFrameCount(i); + for (int f = 0; f < frameCount; f++) + { + float frameWeight = srcMesh.GetBlendShapeFrameWeight(i, f); + srcMesh.GetBlendShapeFrameVertices(i, f, deltaVerts, deltaNormals, deltaTangents); - for (int i = 0; i < srcMesh.blendShapeCount; i++) - { - string name = srcMesh.GetBlendShapeName(i); + Vector3 deltaSum = Vector3.zero; + for (int d = 0; d < srcMesh.vertexCount; d++) deltaSum += deltaVerts[d]; + //Debug.Log(name + ": deltaSum = " + deltaSum.ToString()); - int frameCount = srcMesh.GetBlendShapeFrameCount(i); - for (int f = 0; f < frameCount; f++) - { - float frameWeight = srcMesh.GetBlendShapeFrameWeight(i, f); - srcMesh.GetBlendShapeFrameVertices(i, f, deltaVerts, deltaNormals, deltaTangents); - - Vector3 deltaSum = Vector3.zero; - for (int d = 0; d < srcMesh.vertexCount; d++) deltaSum += deltaVerts[d]; - //Debug.Log(name + ": deltaSum = " + deltaSum.ToString()); - - if (deltaSum.magnitude > 0.1f) - dstMesh.AddBlendShapeFrame(name, frameWeight, deltaVerts, deltaNormals, deltaTangents); + if (deltaSum.magnitude > 0.1f) + dstMesh.AddBlendShapeFrame(name, frameWeight, deltaVerts, deltaNormals, deltaTangents); + } } } - } - - // Save the mesh asset. - if (!AssetDatabase.IsValidFolder(meshFolder)) - AssetDatabase.CreateFolder(folder, PRUNED_FOLDER_NAME); - string meshPath = Path.Combine(meshFolder, srcObj.name + ".mesh"); - AssetDatabase.CreateAsset(dstMesh, meshPath); - if (obj.GetType() == typeof(GameObject)) - { - GameObject go = (GameObject)obj; - if (go) + // Save the mesh asset. + if (Util.EnsureAssetsFolderExists(meshFolder)) { - Mesh createdMesh = AssetDatabase.LoadAssetAtPath(meshPath); + string meshPath = Path.Combine(meshFolder, srcObj.name + ".mesh"); + AssetDatabase.CreateAsset(dstMesh, meshPath); - if (!ReplaceMesh(obj, createdMesh)) + if (obj.GetType() == typeof(GameObject)) { - Util.LogError("Unable to set mesh in selected object!"); + GameObject go = (GameObject)obj; + if (go) + { + Mesh createdMesh = AssetDatabase.LoadAssetAtPath(meshPath); + + if (!ReplaceMesh(obj, createdMesh)) + { + Util.LogError("Unable to set mesh in selected object!"); + } + } } } } @@ -389,108 +415,95 @@ public static Mesh CopyMesh(Mesh srcMesh) public static void ReverseTriangleOrder(Object obj) { - if (!obj) return; - GameObject fbxAsset = Util.FindRootPrefabAssetFromSceneObject(obj); - string fbxPath = AssetDatabase.GetAssetPath(fbxAsset); - string characterName = Path.GetFileNameWithoutExtension(fbxPath); - string fbxFolder = Path.GetDirectoryName(fbxPath); - string meshFolder = Path.Combine(fbxFolder, MESH_FOLDER_NAME, characterName); - // fetch the mesh from the prefab - Object srcObj = PrefabUtility.GetCorrespondingObjectFromSource(obj); - Mesh srcMesh = GetMeshFrom(srcObj); - - if (!srcMesh) return; - - if (string.IsNullOrEmpty(fbxPath)) - { - Util.LogWarn("Object: " + obj.name + " has no source Prefab Asset."); - fbxPath = Path.Combine("Assets", "dummy.prefab"); - } - - if (!srcMesh) + if (GetSourcePrefab(obj, MESH_FOLDER_NAME, out string characterName, out string meshFolder, out Object srcObj)) { - Util.LogError("No mesh found in selected object."); - return; - } - - Mesh dstMesh = new Mesh(); - dstMesh.indexFormat = srcMesh.indexFormat; - dstMesh.vertices = srcMesh.vertices; - dstMesh.uv = srcMesh.uv; - dstMesh.uv2 = srcMesh.uv2; - dstMesh.normals = srcMesh.normals; - dstMesh.colors = srcMesh.colors; - dstMesh.boneWeights = srcMesh.boneWeights; - dstMesh.bindposes = srcMesh.bindposes; - dstMesh.bounds = srcMesh.bounds; - dstMesh.tangents = srcMesh.tangents; - - int[] reversed = new int[srcMesh.triangles.Length]; - int[] forward = srcMesh.triangles; + Mesh srcMesh = GetMeshFrom(srcObj); - // first pass: reverse the triangle order for each submesh - for (int s = 0; s < srcMesh.subMeshCount; s++) - { - SubMeshDescriptor submesh = srcMesh.GetSubMesh(s); - int start = submesh.indexStart; - int end = start + submesh.indexCount; - int j = end - 3; - for (int i = start; i < end; i += 3) + if (!srcMesh) { - reversed[j] = forward[i]; - reversed[j + 1] = forward[i + 1]; - reversed[j + 2] = forward[i + 2]; - j -= 3; + Util.LogError("No mesh found in selected object."); + return; } - } - dstMesh.triangles = reversed; - dstMesh.subMeshCount = srcMesh.subMeshCount; + Mesh dstMesh = new Mesh(); + dstMesh.indexFormat = srcMesh.indexFormat; + dstMesh.vertices = srcMesh.vertices; + dstMesh.uv = srcMesh.uv; + dstMesh.uv2 = srcMesh.uv2; + dstMesh.normals = srcMesh.normals; + dstMesh.colors = srcMesh.colors; + dstMesh.boneWeights = srcMesh.boneWeights; + dstMesh.bindposes = srcMesh.bindposes; + dstMesh.bounds = srcMesh.bounds; + dstMesh.tangents = srcMesh.tangents; + + int[] reversed = new int[srcMesh.triangles.Length]; + int[] forward = srcMesh.triangles; + + // first pass: reverse the triangle order for each submesh + for (int s = 0; s < srcMesh.subMeshCount; s++) + { + SubMeshDescriptor submesh = srcMesh.GetSubMesh(s); + int start = submesh.indexStart; + int end = start + submesh.indexCount; + int j = end - 3; + for (int i = start; i < end; i += 3) + { + reversed[j] = forward[i]; + reversed[j + 1] = forward[i + 1]; + reversed[j + 2] = forward[i + 2]; + j -= 3; + } + } - // second pass: copy sub-mesh data (vertex and triangle data must be present for this) - for (int s = 0; s < srcMesh.subMeshCount; s++) - { - SubMeshDescriptor submesh = srcMesh.GetSubMesh(s); - dstMesh.SetSubMesh(s, submesh); - } + dstMesh.triangles = reversed; + dstMesh.subMeshCount = srcMesh.subMeshCount; - // copy any blendshapes across - if (srcMesh.blendShapeCount > 0) - { - Vector3[] bufVerts = new Vector3[srcMesh.vertexCount]; - Vector3[] bufNormals = new Vector3[srcMesh.vertexCount]; - Vector3[] bufTangents = new Vector3[srcMesh.vertexCount]; + // second pass: copy sub-mesh data (vertex and triangle data must be present for this) + for (int s = 0; s < srcMesh.subMeshCount; s++) + { + SubMeshDescriptor submesh = srcMesh.GetSubMesh(s); + dstMesh.SetSubMesh(s, submesh); + } - for (int i = 0; i < srcMesh.blendShapeCount; i++) + // copy any blendshapes across + if (srcMesh.blendShapeCount > 0) { - string name = srcMesh.GetBlendShapeName(i); + Vector3[] bufVerts = new Vector3[srcMesh.vertexCount]; + Vector3[] bufNormals = new Vector3[srcMesh.vertexCount]; + Vector3[] bufTangents = new Vector3[srcMesh.vertexCount]; - int frameCount = srcMesh.GetBlendShapeFrameCount(i); - for (int f = 0; f < frameCount; f++) + for (int i = 0; i < srcMesh.blendShapeCount; i++) { - float frameWeight = srcMesh.GetBlendShapeFrameWeight(i, f); - srcMesh.GetBlendShapeFrameVertices(i, f, bufVerts, bufNormals, bufTangents); - dstMesh.AddBlendShapeFrame(name, frameWeight, bufVerts, bufNormals, bufTangents); + string name = srcMesh.GetBlendShapeName(i); + + int frameCount = srcMesh.GetBlendShapeFrameCount(i); + for (int f = 0; f < frameCount; f++) + { + float frameWeight = srcMesh.GetBlendShapeFrameWeight(i, f); + srcMesh.GetBlendShapeFrameVertices(i, f, bufVerts, bufNormals, bufTangents); + dstMesh.AddBlendShapeFrame(name, frameWeight, bufVerts, bufNormals, bufTangents); + } } } - } - - // Save the mesh asset. - if (Util.EnsureAssetsFolderExists(meshFolder)) - { - string meshPath = Path.Combine(meshFolder, srcObj.name + "_Inverted.mesh"); - AssetDatabase.CreateAsset(dstMesh, meshPath); - if (obj.GetType() == typeof(GameObject)) + // Save the mesh asset. + if (Util.EnsureAssetsFolderExists(meshFolder)) { - GameObject go = (GameObject)obj; - if (go) - { - Mesh createdMesh = AssetDatabase.LoadAssetAtPath(meshPath); + string meshPath = Path.Combine(meshFolder, srcObj.name + "_Inverted.mesh"); + AssetDatabase.CreateAsset(dstMesh, meshPath); - if (!ReplaceMesh(obj, createdMesh)) + if (obj.GetType() == typeof(GameObject)) + { + GameObject go = (GameObject)obj; + if (go) { - Util.LogError("Unable to set mesh in selected object!"); + Mesh createdMesh = AssetDatabase.LoadAssetAtPath(meshPath); + + if (!ReplaceMesh(obj, createdMesh)) + { + Util.LogError("Unable to set mesh in selected object!"); + } } } } @@ -1442,47 +1455,42 @@ public static long SpatialHash(Vector3 v) public static void AutoSmoothMesh(Object obj) { - if (!obj) return; - GameObject fbxAsset = Util.FindRootPrefabAssetFromSceneObject(obj); - string fbxPath = AssetDatabase.GetAssetPath(fbxAsset); - string characterName = Path.GetFileNameWithoutExtension(fbxPath); - string fbxFolder = Path.GetDirectoryName(fbxPath); - string meshFolder = Path.Combine(fbxFolder, MESH_FOLDER_NAME, characterName); - Object srcObj = PrefabUtility.GetCorrespondingObjectFromSource(obj); - - if (srcObj) + if (GetSourcePrefab(obj, MESH_FOLDER_NAME, out string characterName, out string meshFolder, out Object srcObj)) { Mesh srcMesh = GetMeshFrom(srcObj); - if (srcMesh) + if (!srcMesh) { - if (srcMesh.name.iEndsWith("_Smoothed")) - { - Util.LogWarn("Mesh is already smoothed!"); - return; - } + Util.LogError("No mesh found in selected object."); + return; + } - Mesh dstMesh = CopyMesh(srcMesh); - SmoothNormals2(dstMesh, 120f); + if (srcMesh.name.iEndsWith("_Smoothed")) + { + Util.LogWarn("Mesh is already smoothed!"); + return; + } - // Save the mesh asset. - if (Util.EnsureAssetsFolderExists(meshFolder)) - { - string meshPath = Path.Combine(meshFolder, srcObj.name + "_Smoothed.mesh"); - AssetDatabase.CreateAsset(dstMesh, meshPath); + Mesh dstMesh = CopyMesh(srcMesh); + SmoothNormals2(dstMesh, 120f); + + // Save the mesh asset. + if (Util.EnsureAssetsFolderExists(meshFolder)) + { + string meshPath = Path.Combine(meshFolder, srcObj.name + "_Smoothed.mesh"); + AssetDatabase.CreateAsset(dstMesh, meshPath); - if (obj.GetType() == typeof(GameObject)) + if (obj.GetType() == typeof(GameObject)) + { + GameObject go = (GameObject)obj; + if (go) { - GameObject go = (GameObject)obj; - if (go) - { - Mesh createdMesh = AssetDatabase.LoadAssetAtPath(meshPath); + Mesh createdMesh = AssetDatabase.LoadAssetAtPath(meshPath); - if (ReplaceMesh(obj, createdMesh)) - Util.LogAlways("Auto Smooth Mesh Complete!"); - else - Util.LogError("Unable to set mesh in selected object!"); - } + if (ReplaceMesh(obj, createdMesh)) + Util.LogAlways("Auto Smooth Mesh Complete!"); + else + Util.LogError("Unable to set mesh in selected object!"); } } } diff --git a/Editor/Pipeline.cs b/Editor/Pipeline.cs index 7a74b5d..5bb2626 100644 --- a/Editor/Pipeline.cs +++ b/Editor/Pipeline.cs @@ -40,7 +40,7 @@ public enum MaterialQuality { None, Default, High, Baked } public static class Pipeline { - public const string VERSION = "1.4.1"; + public const string VERSION = "1.4.2"; #if HDRP_10_5_0_OR_NEWER // version diff --git a/Editor/RL.cs b/Editor/RL.cs index 044796e..9914bf9 100644 --- a/Editor/RL.cs +++ b/Editor/RL.cs @@ -118,34 +118,41 @@ public static BaseGeneration GetCharacterGeneration(GameObject fbx, string gener } public static void HumanoidImportSettings(GameObject fbx, ModelImporter importer, string characterName, BaseGeneration generation, CharacterInfo.RigOverride rigOverride, QuickJSON jsonData) - { - importer.importNormals = ModelImporterNormals.Calculate; - //importer.importNormals = ModelImporterNormals.Import; - importer.importTangents = ModelImporterTangents.CalculateMikk; + { + // import normals to avoid mesh smoothing issues + importer.importNormals = ModelImporterNormals.Import; importer.importBlendShapes = true; + // importing blend shape normals gives disasterously bad results, they need to be recalculated, + // ideally using the legacy blend shape normals option, but this has not been exposed to scripts so... importer.importBlendShapeNormals = ModelImporterNormals.Calculate; + // when recalculating blend shape normals, recalculate using only area weights, + // this produces the best results on CC3/4 body meshes + importer.normalCalculationMode = ModelImporterNormalCalculationMode.AreaWeighted; + // prefer smoothing groups (though usually there aren't any) + importer.normalSmoothingSource = ModelImporterNormalSmoothingSource.PreferSmoothingGroups; + // default angle of 60 degrees + importer.normalSmoothingAngle = 60f; + importer.importTangents = ModelImporterTangents.CalculateMikk; importer.generateAnimations = ModelImporterGenerateAnimations.GenerateAnimations; importer.animationType = ModelImporterAnimationType.Human; - importer.avatarSetup = ModelImporterAvatarSetup.CreateFromThisModel; - importer.autoGenerateAvatarMappingIfUnspecified = true; + importer.avatarSetup = ModelImporterAvatarSetup.CreateFromThisModel; + importer.autoGenerateAvatarMappingIfUnspecified = true; + if (generation == BaseGeneration.Unknown) { - if (!characterName.Contains("_Motion")) + switch (rigOverride) { - switch (rigOverride) - { - case CharacterInfo.RigOverride.None: - importer.animationType = ModelImporterAnimationType.None; - break; - case CharacterInfo.RigOverride.Humanoid: - importer.animationType = ModelImporterAnimationType.Human; - break; - case CharacterInfo.RigOverride.Generic: - default: - importer.animationType = ModelImporterAnimationType.Generic; - break; - } + case CharacterInfo.RigOverride.None: + importer.animationType = ModelImporterAnimationType.None; + break; + case CharacterInfo.RigOverride.Humanoid: + importer.animationType = ModelImporterAnimationType.Human; + break; + case CharacterInfo.RigOverride.Generic: + default: + importer.animationType = ModelImporterAnimationType.Generic; + break; } return; } @@ -370,9 +377,9 @@ public static void HumanoidImportSettings(GameObject fbx, ModelImporter importer human.armStretch = 0.05f; human.legStretch = 0.05f; human.feetSpacing = 0.0f; - human.hasTranslationDoF = false; + human.hasTranslationDoF = true; - if (jsonData != null || !characterName.iContains("_Motion")) + if (jsonData != null) { Transform[] transforms = fbx.GetComponentsInChildren(); SkeletonBone[] bones = new SkeletonBone[transforms.Length]; @@ -383,7 +390,7 @@ public static void HumanoidImportSettings(GameObject fbx, ModelImporter importer bones[i].rotation = transforms[i].localRotation; bones[i].scale = transforms[i].localScale; } - human.skeleton = bones; + human.skeleton = bones; } importer.humanDescription = human; diff --git a/Editor/StrandHair.cs b/Editor/StrandHair.cs index 81f9d62..307d9fe 100644 --- a/Editor/StrandHair.cs +++ b/Editor/StrandHair.cs @@ -113,7 +113,7 @@ public GameObject Import() if (doneSomething) { - //prefabAsset = PrefabUtility.SaveAsPrefabAsset(prefabInstance, "Assets\\test.prefab"); + //prefabAsset = PrefabUtility.SaveAsPrefabAsset(prefabInstance, "Assets" + Path.DirectorySeparatorChar + "test.prefab"); //PrefabUtility.ApplyPrefabInstance(prefabInstance, InteractionMode.UserAction); //PrefabUtility.SavePrefabAsset(prefabAsset); WindowManager.onTimer += SavePrefabDelayed; diff --git a/Editor/Util.cs b/Editor/Util.cs index 0382026..239cadd 100644 --- a/Editor/Util.cs +++ b/Editor/Util.cs @@ -92,9 +92,37 @@ public static bool IsCC3CharacterAtPath(string assetPath) } } + return false; + } + + public static bool IsSavedPrefabInSelection() + { + if (Selection.gameObjects.Length > 1) + { + foreach (GameObject sel in Selection.gameObjects) + { + GameObject instanceRoot = GetScenePrefabInstanceRoot(sel); + GameObject prefabSource = PrefabUtility.GetCorrespondingObjectFromSource(instanceRoot); + if (prefabSource) + { + if (AssetDatabase.GetAssetPath(prefabSource).iEndsWith(".prefab")) return true; + } + } + } + else if (Selection.gameObjects.Length == 1) + { + GameObject instanceRoot = GetScenePrefabInstanceRoot(Selection.gameObjects[0]); + GameObject prefabSource = PrefabUtility.GetCorrespondingObjectFromSource(instanceRoot); + if (prefabSource) + { + if (AssetDatabase.GetAssetPath(prefabSource).iEndsWith(".prefab")) return true; + } + } + return false; } + public static Color LinearTosRGBOld(Color c) { if (c.r < 0f) c.r = 0f; @@ -271,8 +299,28 @@ public static string GetRelativePath(string fullPath) fullPath = Path.GetFullPath(fullPath); string basePath = Path.GetFullPath(Path.GetDirectoryName(Application.dataPath)); - string[] fullSplit = fullPath.Split('\\'); - string[] baseSplit = basePath.Split('\\'); + string[] fullSplit; + string[] baseSplit; + + // check OS and split the path accordingly + // There is also Path.DirectorySeparatorChar + // But this will remind me to treat the absolute path roots differently (If I ever need to) + if (Application.platform == RuntimePlatform.WindowsEditor) + { + fullSplit = fullPath.Split('\\'); + baseSplit = basePath.Split('\\'); + } + else if (Application.platform == RuntimePlatform.OSXEditor || + Application.platform == RuntimePlatform.LinuxEditor) + { + fullSplit = fullPath.Split('/'); + baseSplit = basePath.Split('/'); + } + else + { + Debug.LogError("Unsupported Platform: " + Application.platform); + return fullPath; + } int sharedRootIndex = -1; @@ -290,7 +338,7 @@ public static string GetRelativePath(string fullPath) for (int i = sharedRootIndex + 1; i < fullSplit.Length - 1; i++) { - relativePath += fullSplit[i] + "\\"; + relativePath += fullSplit[i] + Path.DirectorySeparatorChar; } relativePath += fullSplit[fullSplit.Length - 1]; @@ -525,12 +573,15 @@ public static Object FindAsset(string search, string[] folders = null) public static string CombineJsonTexPath(string fbxPath, string jsonTexPath) { - // remove any ./ prefix from the json path - if (jsonTexPath.iStartsWith("./")) - jsonTexPath = jsonTexPath.Substring(2); - // convert slashes to backslashes - jsonTexPath = jsonTexPath.Replace("/", "\\"); - return Path.Combine(fbxPath, jsonTexPath); + // remove any ./ .\ prefix from the start of the json texture path + if (jsonTexPath.iStartsWith("./") || jsonTexPath.iStartsWith(".\\")) + jsonTexPath = jsonTexPath.Substring(2); + + // convert slashes/backslashes to OS dependant separator + if (Path.DirectorySeparatorChar != '\\') jsonTexPath = jsonTexPath.Replace('\\', Path.DirectorySeparatorChar); + if (Path.DirectorySeparatorChar != '/') jsonTexPath = jsonTexPath.Replace('/', Path.DirectorySeparatorChar); + + return Path.Combine(fbxPath, jsonTexPath); } public static GameObject FindPreviewScenePrefab() diff --git a/HDRP/Material Templates/RL_Template_Baked_EyeOcclusionCustom_HDRP.mat b/HDRP/Material Templates/RL_Template_Baked_EyeOcclusionCustom_HDRP.mat index ba38a15..7f61329 100644 --- a/HDRP/Material Templates/RL_Template_Baked_EyeOcclusionCustom_HDRP.mat +++ b/HDRP/Material Templates/RL_Template_Baked_EyeOcclusionCustom_HDRP.mat @@ -62,7 +62,7 @@ Material: - _AlphaSrcBlend: 1 - _AlphaToMask: 0 - _AlphaToMaskInspectorValue: 0 - - _BlendMode: 0 + - _BlendMode: 4 - _CullMode: 2 - _CullModeForward: 2 - _DepthOffsetEnable: 0 @@ -75,6 +75,7 @@ Material: - _ExpandLower: 0 - _ExpandOut: 0.0001 - _ExpandOuter: 0 + - _ExpandScale: 1 - _ExpandUpper: 0 - _OpaqueCullMode: 2 - _RayTracing: 0 diff --git a/HDRP/Material Templates/RL_Template_Baked_EyeOcclusion_HDRP.mat b/HDRP/Material Templates/RL_Template_Baked_EyeOcclusion_HDRP.mat index 6d8bc20..cfd1224 100644 --- a/HDRP/Material Templates/RL_Template_Baked_EyeOcclusion_HDRP.mat +++ b/HDRP/Material Templates/RL_Template_Baked_EyeOcclusion_HDRP.mat @@ -148,7 +148,7 @@ Material: - _AlphaToMask: 0 - _AlphaToMaskInspectorValue: 0 - _Anisotropy: 0 - - _BlendMode: 0 + - _BlendMode: 4 - _CoatMask: 0 - _CullMode: 2 - _CullModeForward: 2 diff --git a/HDRP/Material Templates/RL_Template_Default_EyeOcclusion_HDRP.mat b/HDRP/Material Templates/RL_Template_Default_EyeOcclusion_HDRP.mat index 8b8d01f..79f30b5 100644 --- a/HDRP/Material Templates/RL_Template_Default_EyeOcclusion_HDRP.mat +++ b/HDRP/Material Templates/RL_Template_Default_EyeOcclusion_HDRP.mat @@ -148,7 +148,7 @@ Material: - _AlphaToMask: 0 - _AlphaToMaskInspectorValue: 0 - _Anisotropy: 0 - - _BlendMode: 0 + - _BlendMode: 4 - _CoatMask: 0 - _CullMode: 2 - _CullModeForward: 2 diff --git a/HDRP/Material Templates/Tessellation/RL_Template_Baked_EyeOcclusion_HDRP_T.mat b/HDRP/Material Templates/Tessellation/RL_Template_Baked_EyeOcclusion_HDRP_T.mat index 13a84a7..a4c569a 100644 --- a/HDRP/Material Templates/Tessellation/RL_Template_Baked_EyeOcclusion_HDRP_T.mat +++ b/HDRP/Material Templates/Tessellation/RL_Template_Baked_EyeOcclusion_HDRP_T.mat @@ -148,7 +148,7 @@ Material: - _AlphaToMask: 0 - _AlphaToMaskInspectorValue: 0 - _Anisotropy: 0 - - _BlendMode: 0 + - _BlendMode: 4 - _CoatMask: 0 - _CullMode: 2 - _CullModeForward: 2 diff --git a/HDRP/Shaders/RL_EyeOcclusionShader_Baked_HDRP.shadergraph b/HDRP/Shaders/RL_EyeOcclusionShader_Baked_HDRP.shadergraph index d1a9e6b..adb6673 100644 --- a/HDRP/Shaders/RL_EyeOcclusionShader_Baked_HDRP.shadergraph +++ b/HDRP/Shaders/RL_EyeOcclusionShader_Baked_HDRP.shadergraph @@ -3606,7 +3606,7 @@ "m_MaterialNeedsUpdateHash": 529, "m_SurfaceType": 1, "m_RenderingPass": 4, - "m_BlendMode": 0, + "m_BlendMode": 4, "m_ZTest": 4, "m_ZWrite": false, "m_TransparentCullMode": 2, diff --git a/HDRP/Shaders/RL_EyeOcclusionShader_HDRP.shadergraph b/HDRP/Shaders/RL_EyeOcclusionShader_HDRP.shadergraph index 927302e..2a22cb8 100644 --- a/HDRP/Shaders/RL_EyeOcclusionShader_HDRP.shadergraph +++ b/HDRP/Shaders/RL_EyeOcclusionShader_HDRP.shadergraph @@ -350,6 +350,12 @@ }, { "m_Id": "96931c2b5aac42b2a442b9ca60a129c5" + }, + { + "m_Id": "7c2230fe520044b58efc8b0f3f81aef9" + }, + { + "m_Id": "ecde9701255540e39bcfa999dd550f0d" } ], "m_GroupDatas": [ @@ -973,6 +979,20 @@ "m_SlotId": 1 } }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7c2230fe520044b58efc8b0f3f81aef9" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "ecde9701255540e39bcfa999dd550f0d" + }, + "m_SlotId": 0 + } + }, { "m_OutputSlot": { "m_Node": { @@ -1262,9 +1282,9 @@ }, "m_InputSlot": { "m_Node": { - "m_Id": "f0929bd816264348880d393c528dc110" + "m_Id": "ecde9701255540e39bcfa999dd550f0d" }, - "m_SlotId": 0 + "m_SlotId": 1 } }, { @@ -1351,6 +1371,20 @@ "m_SlotId": 0 } }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "bec97d41a4a84aa58e0ff22f2f7adfd5" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7c2230fe520044b58efc8b0f3f81aef9" + }, + "m_SlotId": 0 + } + }, { "m_OutputSlot": { "m_Node": { @@ -1561,6 +1595,20 @@ "m_SlotId": 0 } }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "ecde9701255540e39bcfa999dd550f0d" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f0929bd816264348880d393c528dc110" + }, + "m_SlotId": 0 + } + }, { "m_OutputSlot": { "m_Node": { @@ -2054,6 +2102,21 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "0849de1856524196bea67d0ee093a200", + "m_Id": 3, + "m_DisplayName": "B", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", @@ -2425,6 +2488,21 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "13b4961ea7184a73b293fd76bbfd7aef", + "m_Id": 1, + "m_DisplayName": "R", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "R", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", @@ -3546,6 +3624,54 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "355268a43b6e48dea87571f06cda6de3", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", @@ -4546,6 +4672,21 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "50ec9220e9124189843d269d70762d66", + "m_Id": 4, + "m_DisplayName": "A", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDTarget", @@ -5782,6 +5923,50 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SplitNode", + "m_ObjectId": "7c2230fe520044b58efc8b0f3f81aef9", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Split", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -500.0, + "y": 248.0, + "width": 120.0, + "height": 149.0 + } + }, + "m_Slots": [ + { + "m_Id": "f44b24f60cca48a085cb422425ddf87c" + }, + { + "m_Id": "13b4961ea7184a73b293fd76bbfd7aef" + }, + { + "m_Id": "d61084f6481c4883a126b05b0e5e279c" + }, + { + "m_Id": "0849de1856524196bea67d0ee093a200" + }, + { + "m_Id": "50ec9220e9124189843d269d70762d66" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.BlockNode", @@ -7622,6 +7807,54 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "b48702e1b8f04f169f1a5a483eede9c9", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", @@ -8163,8 +8396,8 @@ "m_Expanded": true, "m_Position": { "serializedVersion": "2", - "x": -186.00006103515626, - "y": 309.0, + "x": -686.0, + "y": 172.0, "width": 161.0, "height": 34.0 } @@ -9116,6 +9349,21 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "d61084f6481c4883a126b05b0e5e279c", + "m_Id": 2, + "m_DisplayName": "G", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "G", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.PowerNode", @@ -9825,6 +10073,54 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "e2bb4c5c5239491caeb73a86dd38021d", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "e00": 2.0, + "e01": 2.0, + "e02": 2.0, + "e03": 2.0, + "e10": 2.0, + "e11": 2.0, + "e12": 2.0, + "e13": 2.0, + "e20": 2.0, + "e21": 2.0, + "e22": 2.0, + "e23": 2.0, + "e30": 2.0, + "e31": 2.0, + "e32": 2.0, + "e33": 2.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", @@ -10263,6 +10559,44 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", + "m_ObjectId": "ecde9701255540e39bcfa999dd550f0d", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Multiply", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -212.0, + "y": 351.0, + "width": 208.0, + "height": 302.0 + } + }, + "m_Slots": [ + { + "m_Id": "355268a43b6e48dea87571f06cda6de3" + }, + { + "m_Id": "e2bb4c5c5239491caeb73a86dd38021d" + }, + { + "m_Id": "b48702e1b8f04f169f1a5a483eede9c9" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", @@ -10515,6 +10849,30 @@ "m_Space": 0 } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "f44b24f60cca48a085cb422425ddf87c", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", diff --git a/Runtime/WeightMapper.cs b/Runtime/WeightMapper.cs index 88b42f6..0acac3b 100644 --- a/Runtime/WeightMapper.cs +++ b/Runtime/WeightMapper.cs @@ -54,9 +54,9 @@ public class PhysicsSettings [HideInInspector] public float selfMargin; [Space(8)] - [Range(1f, 500f)] + [Range(1f, 5000f)] public float solverFrequency; - [Range(1f, 50f)] + [Range(1f, 500f)] public float stiffnessFrequency; [Space(8)] [Range(0f, 1f)] @@ -103,6 +103,7 @@ public void Copy(PhysicsSettings p) public bool updateColliders = true; public bool optimizeColliders = true; public bool includeAllLimbColliders = false; + public bool updateConstraints = true; [HideInInspector] public string characterGUID; @@ -122,8 +123,8 @@ public void ApplyWeightMap() // add cloth component Cloth cloth = clothTarget.GetComponent(); - if (!cloth) cloth = clothTarget.AddComponent(); - + if (!cloth) cloth = clothTarget.AddComponent(); + // generate a mapping dictionary of cloth vertices to mesh vertices Dictionary uniqueVertices = new Dictionary(); int count = 0; @@ -134,15 +135,7 @@ public void ApplyWeightMap() { uniqueVertices.Add(SpatialHash(meshVertices[k]), count++); } - } - - // reset coefficients - ClothSkinningCoefficient[] coefficients = new ClothSkinningCoefficient[cloth.coefficients.Length]; - Array.Copy(cloth.coefficients, coefficients, coefficients.Length); - for (int i = 0; i < cloth.coefficients.Length; i++) - { - coefficients[i].maxDistance = 0; - } + } // fetch UV's List uvs = new List(); @@ -155,7 +148,16 @@ public void ApplyWeightMap() List detectedColliders = new List(colliders.Count); ColliderManager colliderManager = gameObject.GetComponentInParent(); if (colliderManager) colliders.AddRange(colliderManager.colliders); - else colliders.AddRange(gameObject.transform.parent.GetComponentsInChildren()); + else colliders.AddRange(gameObject.transform.parent.GetComponentsInChildren()); + + ClothSkinningCoefficient[] coefficients = new ClothSkinningCoefficient[cloth.coefficients.Length]; + Array.Copy(cloth.coefficients, coefficients, coefficients.Length); + + // reset coefficients + for (int i = 0; i < cloth.coefficients.Length; i++) + { + coefficients[i].maxDistance = 0; + } // apply weight maps to cloth coefficients and cloth settings for (int i = 0; i < mesh.subMeshCount; i++)// @@ -181,7 +183,7 @@ public void ApplyWeightMap() cloth.friction = data.friction; cloth.damping = Mathf.Pow(data.damping, 0.333f); cloth.selfCollisionDistance = data.selfMargin * modelScale; - cloth.selfCollisionStiffness = 1f; + cloth.selfCollisionStiffness = 1f; bool doColliders = updateColliders && data.softRigidCollision; @@ -277,10 +279,13 @@ public void ApplyWeightMap() } } } - } + } // set coefficients - cloth.coefficients = coefficients; + if (updateConstraints) + { + cloth.coefficients = coefficients; + } // set colliders if (updateColliders) diff --git a/package.json b/package.json index de5e214..0198f38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.soupday.cc3_unity_tools", - "version": "1.4.1", + "version": "1.4.2", "displayName": "CC/iC Unity Tools HDRP", "description": "Unity importer for Character Creator 3 & 4 and iClone 7 and 8.", "unity": "2020.3",