diff --git a/Editor/RL.cs b/Editor/RL.cs index b31cfd6..4fefb59 100644 --- a/Editor/RL.cs +++ b/Editor/RL.cs @@ -23,6 +23,7 @@ using System.IO; using UnityEditor.Animations; using System.Reflection; +using System.Linq; namespace Reallusion.Import { @@ -56,66 +57,97 @@ public class RL { "RL_G6_Standard_Series", BaseGeneration.G1 }, { "NonStdLookAtDataCopyFromCCBase", BaseGeneration.ActorCore }, { "ActorBuild", BaseGeneration.ActorBuild }, - { "ActorScan", BaseGeneration.ActorCore } + { "ActorScan", BaseGeneration.ActorCore }, + { "AccuRig", BaseGeneration.ActorBuild } }; - - public static BaseGeneration GetCharacterGeneration(GameObject fbx, string generationString) + + public static bool CharacterContainsBones(Transform[] bones, string[] boneNames) { - if (!string.IsNullOrEmpty(generationString)) + foreach (string n in boneNames) { - if (GENERATION_MAP.TryGetValue(generationString, out BaseGeneration gen)) return gen; + bool found = false; + foreach (Transform b in bones) + { + if (b.name == n) + { + found = true; + break; + } + } + if (!found) return false; } - else + return true; + } + + public static BaseGeneration GetCharacterGeneration(GameObject fbx, string generationString) + { + if (fbx) { - if (fbx) - { - Transform[] children = fbx.transform.GetComponentsInChildren(true); - foreach (Transform child in children) - { - string objectName = child.gameObject.name; + Transform[] children = fbx.transform.GetComponentsInChildren(true); - if (objectName.iContains("RootNode_0_")) return BaseGeneration.ActorCore; - if (objectName.iContains("CC_Base_L_Pinky3")) return BaseGeneration.G3; - if (objectName.iContains("pinky_03_l")) return BaseGeneration.GameBase; - if (objectName.iContains("CC_Base_L_Finger42")) return BaseGeneration.G1; - if (objectName.iContains("RL_BoneRoot")) - { - if (child.Find("CC_Base_Hip")) - { - Material acMat = GetActorCoreSingleMaterial(fbx); - if (acMat) return BaseGeneration.ActorCore; - else return BaseGeneration.G3; - } + if (!string.IsNullOrEmpty(generationString)) + { + if (GENERATION_MAP.TryGetValue(generationString, out BaseGeneration gen)) + { + // some ActorScan characters are really GameBase + if (CharacterContainsBones(children, new string[] { "head", "pelvis", "spine_02" })) + { + gen = BaseGeneration.GameBase; } + + return gen; } + } + + // check game base + if (CharacterContainsBones(children, new string[] { "head", "pelvis", "spine_02" })) + return BaseGeneration.GameBase; - foreach (Transform child in children) - { - string objectName = child.gameObject.name; + foreach (Transform child in children) + { + string objectName = child.gameObject.name; - if (objectName.iContains("CC_Game_Body") || objectName.iContains("CC_Game_Tongue")) + if (objectName.iContains("RootNode_0_")) return BaseGeneration.ActorCore; + if (objectName.iContains("CC_Base_L_Pinky3")) return BaseGeneration.G3; + if (objectName.iContains("pinky_03_l")) return BaseGeneration.GameBase; + if (objectName.iContains("CC_Base_L_Finger42")) return BaseGeneration.G1; + if (objectName.iContains("RL_BoneRoot")) + { + if (child.Find("CC_Base_Hip")) { - return BaseGeneration.GameBase; + Material acMat = GetActorCoreSingleMaterial(fbx); + if (acMat) return BaseGeneration.ActorCore; + else return BaseGeneration.G3; } + } + } - if (objectName == "CC_Base_Body") + foreach (Transform child in children) + { + string objectName = child.gameObject.name; + + if (objectName.iContains("CC_Game_Body") || objectName.iContains("CC_Game_Tongue")) + { + return BaseGeneration.GameBase; + } + + if (objectName == "CC_Base_Body") + { + Renderer renderer = child.GetComponent(); + foreach (Material mat in renderer.sharedMaterials) { - Renderer renderer = child.GetComponent(); - foreach (Material mat in renderer.sharedMaterials) - { - if (!mat) continue; - - string materialName = mat.name; - if (materialName.iContains("Skin_Body")) - return BaseGeneration.G1; - else if (materialName.iContains("Std_Skin_Body")) - return BaseGeneration.G3; - else if (materialName.iContains("ga_skin_body")) - return BaseGeneration.GameBase; - } + if (!mat) continue; + + string materialName = mat.name; + if (materialName.iContains("Skin_Body")) + return BaseGeneration.G1; + else if (materialName.iContains("Std_Skin_Body")) + return BaseGeneration.G3; + else if (materialName.iContains("ga_skin_body")) + return BaseGeneration.GameBase; } } - } + } } return BaseGeneration.Unknown; } diff --git a/Runtime/WrinkleManager.cs b/Runtime/WrinkleManager.cs index 14d8440..f8bd363 100644 --- a/Runtime/WrinkleManager.cs +++ b/Runtime/WrinkleManager.cs @@ -652,7 +652,10 @@ void Start() { foreach (Material mat in smr.materials) { - if (mat.IsKeywordEnabled("BOOLEAN_IS_HEAD_ON")) + // catch a few more possibilities for wrinkle shaders + if (mat.IsKeywordEnabled("BOOLEAN_IS_HEAD_ON") || + mat.IsKeywordEnabled("BOOLEAN_USE_WRINKLE_ON") || + mat.shader.name.Contains("_HeadShaderWrinkle_")) { headMaterial = mat; break;