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 072cf6c..a28b6d9 100644 --- a/HDRP/Material Templates/RL_Template_Baked_EyeOcclusionCustom_HDRP.mat +++ b/HDRP/Material Templates/RL_Template_Baked_EyeOcclusionCustom_HDRP.mat @@ -71,7 +71,7 @@ Material: - _AlphaSrcBlend: 1 - _AlphaToMask: 0 - _AlphaToMaskInspectorValue: 0 - - _BlendMode: 0 + - _BlendMode: 4 - _ConservativeDepthOffsetEnable: 0 - _CullMode: 2 - _CullModeForward: 2 diff --git a/HDRP/Material Templates/RL_Template_Baked_EyeOcclusion_HDRP.mat b/HDRP/Material Templates/RL_Template_Baked_EyeOcclusion_HDRP.mat index 6a53686..0b1f50a 100644 --- a/HDRP/Material Templates/RL_Template_Baked_EyeOcclusion_HDRP.mat +++ b/HDRP/Material Templates/RL_Template_Baked_EyeOcclusion_HDRP.mat @@ -156,7 +156,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 5518fd8..8bf0eae 100644 --- a/HDRP/Material Templates/RL_Template_Default_EyeOcclusion_HDRP.mat +++ b/HDRP/Material Templates/RL_Template_Default_EyeOcclusion_HDRP.mat @@ -156,7 +156,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 6a0290c..b452b3f 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 @@ -157,7 +157,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 e116eb8..4c64a4e 100644 --- a/HDRP/Shaders/RL_EyeOcclusionShader_Baked_HDRP.shadergraph +++ b/HDRP/Shaders/RL_EyeOcclusionShader_Baked_HDRP.shadergraph @@ -3672,7 +3672,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 18ac4c7..e98f3b4 100644 --- a/HDRP/Shaders/RL_EyeOcclusionShader_HDRP.shadergraph +++ b/HDRP/Shaders/RL_EyeOcclusionShader_HDRP.shadergraph @@ -356,6 +356,12 @@ }, { "m_Id": "96931c2b5aac42b2a442b9ca60a129c5" + }, + { + "m_Id": "8c641aa99e224ac89bc3358f490caa5b" + }, + { + "m_Id": "7af68b126c3c4da09154d656a5578593" } ], "m_GroupDatas": [ @@ -965,6 +971,20 @@ "m_SlotId": 2 } }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7af68b126c3c4da09154d656a5578593" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f0929bd816264348880d393c528dc110" + }, + "m_SlotId": 0 + } + }, { "m_OutputSlot": { "m_Node": { @@ -1021,6 +1041,20 @@ "m_SlotId": 1 } }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "8c641aa99e224ac89bc3358f490caa5b" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7af68b126c3c4da09154d656a5578593" + }, + "m_SlotId": 0 + } + }, { "m_OutputSlot": { "m_Node": { @@ -1268,9 +1302,9 @@ }, "m_InputSlot": { "m_Node": { - "m_Id": "f0929bd816264348880d393c528dc110" + "m_Id": "7af68b126c3c4da09154d656a5578593" }, - "m_SlotId": 0 + "m_SlotId": 1 } }, { @@ -1357,6 +1391,20 @@ "m_SlotId": 0 } }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "bec97d41a4a84aa58e0ff22f2f7adfd5" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "8c641aa99e224ac89bc3358f490caa5b" + }, + "m_SlotId": 0 + } + }, { "m_OutputSlot": { "m_Node": { @@ -1981,6 +2029,54 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "0732662862e74e19af2b9410c7c042e1", + "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.Vector4MaterialSlot", @@ -2161,6 +2257,30 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "099e9e3ac7ec4573b33844ffa946e377", + "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": 1, "m_Type": "UnityEditor.ShaderGraph.Internal.Vector1ShaderProperty", @@ -2603,6 +2723,21 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "17dbcade13414be4b91a01372170d3e1", + "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.Rendering.HighDefinition.ShaderGraph.HDLitData", @@ -5730,6 +5865,21 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "762e7e70dec843d48bc3ca1c0d9768d3", + "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.ShaderGraph.OneMinusNode", @@ -5819,6 +5969,54 @@ "m_Labels": [] } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "78759bc5bf494c19a66542fcc08404d0", + "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.OneMinusNode", @@ -5854,6 +6052,48 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", + "m_ObjectId": "7af68b126c3c4da09154d656a5578593", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Multiply", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -205.0000457763672, + "y": 353.0, + "width": 126.00009155273438, + "height": 118.0 + } + }, + "m_Slots": [ + { + "m_Id": "81895f67d58b4cfbb589266e6a7a59b0" + }, + { + "m_Id": "78759bc5bf494c19a66542fcc08404d0" + }, + { + "m_Id": "0732662862e74e19af2b9410c7c042e1" + } + ], + "synonyms": [ + "multiplication", + "times", + "x" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.PropertyNode", @@ -6076,6 +6316,54 @@ "m_Labels": [] } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "81895f67d58b4cfbb589266e6a7a59b0", + "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.DynamicValueMaterialSlot", @@ -6148,6 +6436,21 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "83f7db5765d24dd18f7df6dd828dc79c", + "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.DynamicVectorMaterialSlot", @@ -6425,6 +6728,52 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SplitNode", + "m_ObjectId": "8c641aa99e224ac89bc3358f490caa5b", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Split", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -520.0000610351563, + "y": 279.0, + "width": 120.00006103515625, + "height": 149.00003051757813 + } + }, + "m_Slots": [ + { + "m_Id": "099e9e3ac7ec4573b33844ffa946e377" + }, + { + "m_Id": "efed450fc22b4ac48dafbaad3ec4453c" + }, + { + "m_Id": "83f7db5765d24dd18f7df6dd828dc79c" + }, + { + "m_Id": "17dbcade13414be4b91a01372170d3e1" + }, + { + "m_Id": "762e7e70dec843d48bc3ca1c0d9768d3" + } + ], + "synonyms": [ + "separate" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", @@ -8321,9 +8670,9 @@ "m_Expanded": true, "m_Position": { "serializedVersion": "2", - "x": -186.00006103515626, - "y": 309.0, - "width": 161.0, + "x": -735.0, + "y": 209.00001525878907, + "width": 158.99993896484376, "height": 34.0 } }, @@ -10542,6 +10891,21 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "efed450fc22b4ac48dafbaad3ec4453c", + "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.SmoothstepNode", 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/Scenes/PreviewScene/Materials/floorSpot.mat b/Scenes/PreviewScene/Materials/floorSpot.mat index 1799f15..23ba6e8 100644 --- a/Scenes/PreviewScene/Materials/floorSpot.mat +++ b/Scenes/PreviewScene/Materials/floorSpot.mat @@ -2,14 +2,17 @@ %TAG !u! tag:unity3d.com,2011: --- !u!21 &2100000 Material: - serializedVersion: 6 + serializedVersion: 8 m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: floorSpot m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3} - m_ShaderKeywords: _DISABLE_SSR_TRANSPARENT _NORMALMAP_TANGENT_SPACE + m_ValidKeywords: + - _DISABLE_SSR_TRANSPARENT + - _NORMALMAP_TANGENT_SPACE + m_InvalidKeywords: [] m_LightmapFlags: 4 m_EnableInstancingVariants: 0 m_DoubleSidedGI: 0 @@ -116,6 +119,7 @@ Material: m_Texture: {fileID: 0} m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} + m_Ints: [] m_Floats: - _AORemapMax: 1 - _AORemapMin: 0 @@ -147,6 +151,7 @@ Material: - _DisplacementLockTilingScale: 1 - _DisplacementMode: 0 - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 - _DoubleSidedNormalMode: 1 - _DstBlend: 0 - _EmissiveColorMode: 1 @@ -255,4 +260,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: da692e001514ec24dbc4cca1949ff7e8, type: 3} m_Name: m_EditorClassIdentifier: - version: 11 + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: diff --git a/package.json b/package.json index 38eb80d..6233b69 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": "2021.2",