/// <summary>
        /// クラスに含まれる処理を適用します。
        /// </summary>
        /// <param name="avatar"></param>
        /// <param name="swayingParametersConverter"></param>
        /// <returns></returns>
        internal static IEnumerable <Converter.Message> Apply(
            GameObject avatar,
            Converter.SwayingObjectsConverterSetting swayingObjectsConverterSetting,
            Converter.SwayingParametersConverter swayingParametersConverter
            )
        {
            var messages = new List <Converter.Message>();

            ConvertMeta(avatar: avatar);
            ConvertVRMFirstPerson(avatar: avatar);

            if (DynamicBoneType == null ||
                swayingObjectsConverterSetting == Converter.SwayingObjectsConverterSetting.RemoveSwayingObjects)
            {
                return(messages);
            }

            IDictionary <VRMSpringBoneColliderGroup, IEnumerable <MonoBehaviour> > dynamicBoneColliderGroups = null;

            if (swayingObjectsConverterSetting == Converter.SwayingObjectsConverterSetting.ConvertVrmSpringBonesAndVrmSpringBoneColliderGroups)
            {
                RemoveUnusedColliderGroups(avatar: avatar);
                dynamicBoneColliderGroups = ConvertVRMSpringBoneColliderGroups(avatar);
            }
            ConvertVRMSpringBones(
                avatar: avatar,
                dynamicBoneColliderGroups: dynamicBoneColliderGroups,
                swayingParametersConverter: swayingParametersConverter
                );

            messages.AddRange(GetMessagesAboutDynamicBoneLimits(avatar: avatar));

            return(messages);
        }
        /// <summary>
        /// クラスに含まれる処理を適用します。
        /// </summary>
        /// <param name="avatar"></param>
        /// <param name="swayingParametersConverter"></param>
        /// <returns></returns>
        internal static IEnumerable <(string, MessageType)> Apply(
            GameObject avatar,
            Converter.SwayingObjectsConverterSetting swayingObjectsConverterSetting,
            Converter.SwayingParametersConverter swayingParametersConverter
            )
        {
            var messages = new List <(string, MessageType)>();

            ConvertMeta(avatar: avatar);
            ConvertVRMFirstPerson(avatar: avatar);

            if (DynamicBoneType == null ||
                swayingObjectsConverterSetting == Converter.SwayingObjectsConverterSetting.RemoveSwayingObjects)
            {
                return(messages);
            }

            IDictionary <VRMSpringBoneColliderGroup, IEnumerable <dynamic> > dynamicBoneColliderGroups = null;

            if (swayingObjectsConverterSetting == Converter.SwayingObjectsConverterSetting.ConvertVrmSpringBonesAndVrmSpringBoneColliderGroups)
            {
                RemoveUnusedColliderGroups(avatar: avatar);
                dynamicBoneColliderGroups = ConvertVRMSpringBoneColliderGroups(avatar);
            }
            ConvertVRMSpringBones(
                avatar: avatar,
                dynamicBoneColliderGroups: dynamicBoneColliderGroups,
                swayingParametersConverter: swayingParametersConverter
                );

            messages.AddRange(VRChatUtility.CalculateDynamicBoneLimitations(prefabInstance: avatar));

            return(messages);
        }
        /// <summary>
        /// 指定された<see cref="VRMSpringBone"/>を基に<see cref="DynamicBone"/>を設定します。
        /// </summary>
        /// <param name="springBone"></param>
        /// <param name="dynamicBoneColliderGroups">キーに<see cref="VRMSpringBoneColliderGroup"/>、値に対応する<see cref="DynamicBoneCollider"/>のリストを持つジャグ配列。</param>
        /// <param name="swayingParametersConverter"></param>
        private static void ConvertVRMSpringBone(
            VRMSpringBone springBone,
            IDictionary <VRMSpringBoneColliderGroup, IEnumerable <MonoBehaviour> > dynamicBoneColliderGroups,
            Converter.SwayingParametersConverter swayingParametersConverter
            )
        {
            var springBoneParameters = new SpringBoneParameters(stiffnessForce: springBone.m_stiffnessForce, dragForce: springBone.m_dragForce);
            var boneInfo             = new BoneInfo(vrmMeta: springBone.gameObject.GetComponentsInParent <VRMMeta>()[0]);

            foreach (var transform in springBone.RootBones)
            {
                var dynamicBone = springBone.gameObject.AddComponent(DynamicBoneType);
                DynamicBoneType.GetField("m_Root").SetValue(dynamicBone, transform);
                DynamicBoneType.GetField("m_Exclusions").SetValue(dynamicBone, new List <Transform>());

                DynamicBoneParameters dynamicBoneParameters = null;
                if (swayingParametersConverter != null)
                {
                    dynamicBoneParameters = swayingParametersConverter(
                        springBoneParameters: springBoneParameters,
                        boneInfo: boneInfo
                        );
                }
                if (dynamicBoneParameters != null)
                {
                    DynamicBoneType.GetField("m_Damping").SetValue(dynamicBone, dynamicBoneParameters.Damping);
                    DynamicBoneType.GetField("m_DampingDistrib")
                    .SetValue(dynamicBone, dynamicBoneParameters.DampingDistrib);
                    DynamicBoneType.GetField("m_Elasticity").SetValue(dynamicBone, dynamicBoneParameters.Elasticity);
                    DynamicBoneType.GetField("m_ElasticityDistrib")
                    .SetValue(dynamicBone, dynamicBoneParameters.ElasticityDistrib);
                    DynamicBoneType.GetField("m_Stiffness").SetValue(dynamicBone, dynamicBoneParameters.Stiffness);
                    DynamicBoneType.GetField("m_StiffnessDistrib")
                    .SetValue(dynamicBone, dynamicBoneParameters.StiffnessDistrib);
                    DynamicBoneType.GetField("m_Inert").SetValue(dynamicBone, dynamicBoneParameters.Inert);
                    DynamicBoneType.GetField("m_InertDistrib")
                    .SetValue(dynamicBone, dynamicBoneParameters.InertDistrib);
                }

                DynamicBoneType.GetField("m_Gravity")
                .SetValue(dynamicBone, springBone.m_gravityDir * springBone.m_gravityPower);
                DynamicBoneType.GetField("m_Radius").SetValue(dynamicBone, springBone.m_hitRadius);
                if (dynamicBoneColliderGroups != null)
                {
                    var        colliders = Activator.CreateInstance(type: DynamicBoneColliderBaseListType);
                    MethodInfo addMethod = DynamicBoneColliderBaseListType.GetMethod("Add");
                    foreach (var collider in springBone.ColliderGroups.SelectMany(
                                 colliderGroup => dynamicBoneColliderGroups[colliderGroup]
                                 ))
                    {
                        addMethod.Invoke(colliders, new[] { collider });
                    }
                    DynamicBoneType.GetField("m_Colliders").SetValue(dynamicBone, colliders);
                }
            }
        }
 /// <summary>
 /// 子孫の<see cref="VRMSpringBone"/>を基に<see cref="DynamicBone"/>を設定します。
 /// </summary>
 /// <param name="avatar"></param>
 /// <param name="dynamicBoneColliderGroups">キーに<see cref="VRMSpringBoneColliderGroup"/>、値に対応する<see cref="DynamicBoneCollider"/>のリストを持つジャグ配列。</param>
 /// <param name="swayingParametersConverter"></param>
 private static void ConvertVRMSpringBones(
     GameObject avatar,
     IDictionary <VRMSpringBoneColliderGroup, IEnumerable <MonoBehaviour> > dynamicBoneColliderGroups,
     Converter.SwayingParametersConverter swayingParametersConverter
     )
 {
     foreach (var springBone in avatar.GetComponentsInChildren <VRMSpringBone>())
     {
         ConvertVRMSpringBone(springBone: springBone, dynamicBoneColliderGroups: dynamicBoneColliderGroups, swayingParametersConverter: swayingParametersConverter);
     }
 }
Ejemplo n.º 5
0
        /// <summary>
        /// 指定された<see cref="VRMSpringBone"/>を基に<see cref="DynamicBone"/>を設定します。
        /// </summary>
        /// <param name="springBone"></param>
        /// <param name="dynamicBoneColliderGroups">キーに<see cref="VRMSpringBoneColliderGroup"/>、値に対応する<see cref="DynamicBoneCollider"/>のリストを持つジャグ配列。</param>
        /// <param name="swayingParametersConverter"></param>
        private static void ConvertVRMSpringBone(
            VRMSpringBone springBone,
            IDictionary <VRMSpringBoneColliderGroup, IEnumerable <dynamic> > dynamicBoneColliderGroups,
            Converter.SwayingParametersConverter swayingParametersConverter
            )
        {
            var springBoneParameters = new SpringBoneParameters()
            {
                StiffnessForce = springBone.m_stiffnessForce,
                DragForce      = springBone.m_dragForce,
            };
            var boneInfo = new BoneInfo(vrmMeta: springBone.gameObject.GetComponentsInParent <VRMMeta>()[0]);

            foreach (var transform in springBone.RootBones)
            {
                dynamic dynamicBone = springBone.gameObject.AddComponent(DynamicBoneType);
                dynamicBone.m_Root       = transform;
                dynamicBone.m_Exclusions = new List <Transform>();

                DynamicBoneParameters dynamicBoneParameters = null;
                if (swayingParametersConverter != null)
                {
                    dynamicBoneParameters = swayingParametersConverter(
                        springBoneParameters: springBoneParameters,
                        boneInfo: boneInfo
                        );
                }
                if (dynamicBoneParameters != null)
                {
                    dynamicBone.m_Damping           = dynamicBoneParameters.Damping;
                    dynamicBone.m_DampingDistrib    = dynamicBoneParameters.DampingDistrib;
                    dynamicBone.m_Elasticity        = dynamicBoneParameters.Elasticity;
                    dynamicBone.m_ElasticityDistrib = dynamicBoneParameters.ElasticityDistrib;
                    dynamicBone.m_Stiffness         = dynamicBoneParameters.Stiffness;
                    dynamicBone.m_StiffnessDistrib  = dynamicBoneParameters.StiffnessDistrib;
                    dynamicBone.m_Inert             = dynamicBoneParameters.Inert;
                    dynamicBone.m_InertDistrib      = dynamicBoneParameters.InertDistrib;
                }

                dynamicBone.m_Gravity = springBone.m_gravityDir * springBone.m_gravityPower;
                dynamicBone.m_Radius  = springBone.m_hitRadius;
                if (dynamicBoneColliderGroups != null)
                {
                    dynamic colliders = Activator.CreateInstance(type: DynamicBoneColliderBaseListType);
                    foreach (var collider in springBone.ColliderGroups.SelectMany(
                                 colliderGroup => dynamicBoneColliderGroups[colliderGroup]
                                 ))
                    {
                        colliders.Add(collider);
                    }
                    dynamicBone.m_Colliders = colliders;
                }
            }
        }
Ejemplo n.º 6
0
        protected override bool DrawWizardGUI()
        {
            base.DrawWizardGUI();
            isValid = true;

            if (this.callbackFunctions)
            {
                Type callBackFunctions = this.callbackFunctions.GetClass();

                this.swayingParametersConverter = Delegate.CreateDelegate(
                    type: typeof(Converter.SwayingParametersConverter),
                    target: callBackFunctions,
                    method: "SwayingParametersConverter",
                    ignoreCase: false,
                    throwOnBindFailure: false
                    ) as Converter.SwayingParametersConverter;

                this.postConverting = Delegate.CreateDelegate(
                    type: typeof(Wizard.PostConverting),
                    target: callBackFunctions,
                    method: "PostConverting",
                    ignoreCase: false,
                    throwOnBindFailure: false
                    ) as Wizard.PostConverting;
            }

            var indentStyle = new GUIStyle()
            {
                padding = new RectOffset()
                {
                    left = Wizard.Indent
                }
            };

            EditorGUILayout.LabelField(
                (this.swayingParametersConverter != null ? "☑" : "☐")
                + " public static DynamicBoneParameters SwayingParametersConverter(SpringBoneParameters, BoneInfo)",
                indentStyle
                );

            EditorGUILayout.LabelField(
                (this.postConverting != null ? "☑" : "☐")
                + " public static void PostConverting(GameObject, VRMMeta)",
                indentStyle
                );

#if VRC_SDK_VRCSDK2 || VRC_SDK_VRCSDK3
            foreach (var type in Converter.RequiredComponents)
            {
                if (!this.avatar.GetComponent(type))
                {
                    EditorGUILayout.HelpBox(string.Format(_("Not set “{0}” component."), type), MessageType.Error);
                    isValid = false;
                }
            }

            IEnumerable <string> excludedSpringBoneComments = this.excludedSpringBoneComments.Except(new[] { "" });
            if (excludedSpringBoneComments.Count() > 0)
            {
                IEnumerable <string> comments = excludedSpringBoneComments.Except(
                    this.GetSpringBonesWithComments(prefab: this.avatar.gameObject, comments: excludedSpringBoneComments)
                    .Select(commentAndSpringBones => commentAndSpringBones.Key)
                    );
                if (comments.Count() > 0)
                {
                    EditorGUILayout.HelpBox(string.Join(separator: "\n• ", value: new[] { _("VRMSpringBones with the below Comments do not exist.") }
                                                        .Concat(comments).ToArray()), MessageType.Warning);
                }
            }

            if (this.combineMeshes)
            {
                IEnumerable <string> notCombineRendererObjectNames
                    = this.notCombineRendererObjectNames.Except(new[] { "" });
                if (notCombineRendererObjectNames.Count() > 0)
                {
                    IEnumerable <string> names = notCombineRendererObjectNames.Except(
                        this.avatar.GetComponentsInChildren <SkinnedMeshRenderer>()
                        .Concat <Component>(this.avatar.GetComponentsInChildren <MeshRenderer>())
                        .Select(renderer => renderer.name)
                        );
                    if (names.Count() > 0)
                    {
                        EditorGUILayout.HelpBox(string.Join(separator: "\n• ", value: new[] { _("Renderers on the below name GameObject do not exist.") }
                                                            .Concat(names).ToArray()), MessageType.Warning);
                    }
                }
            }
            else
            {
                EditorGUILayout.HelpBox(_("If you do not “Combine Meshes”,"
                                          + " and any of VRMBlendShapes references meshes other than the mesh having most shape keys"
                                          + " or the mesh is not direct child of the avatar root,"
                                          + " the avatar will not be converted correctly."), MessageType.Warning);
            }

            if (!string.IsNullOrEmpty(this.blendShapeForFingerpoint) &&
                !VRMUtility.GetUserDefinedBlendShapeClip(this.avatar, this.blendShapeForFingerpoint))
            {
                EditorGUILayout.HelpBox(string.Format(
                                            _("There is no user-defined VRMBlensShape with the name “{0}”."),
                                            this.blendShapeForFingerpoint
                                            ), MessageType.Warning);
            }

            string version = VRChatUtility.GetSupportedUnityVersion();
            if (version != "" && Application.unityVersion != version)
            {
                EditorGUILayout.HelpBox(string.Format(
                                            _("Unity {0} is running. If you are using a different version than {1}, VRChat SDK might not work correctly. Recommended using Unity downloaded from {2} ."),
                                            Application.unityVersion,
                                            version,
                                            VRChatUtility.DownloadURL
                                            ), MessageType.Warning);
            }

            if (!isValid || !this.forQuest)
            {
                return(true);
            }

            AvatarPerformanceStats statistics = new AvatarPerformanceStats();
            AvatarPerformance.CalculatePerformanceStats(
                avatarName: avatar.GetComponent <VRMMeta>().Meta.Title,
                avatarObject: this.avatar.gameObject,
                perfStats: statistics
                );
            int currentPolycount = (int)statistics.polyCount;

            int maxPolycount = VRChatUtility.AvatarPerformanceStatsLevelSets["Quest"].medium.polyCount;

            if (currentPolycount > maxPolycount)
            {
                EditorGUILayout.HelpBox(string.Format(
                                            _("The number of polygons is {0}."),
                                            currentPolycount
                                            ) + string.Format(
                                            _("If this value exceeds {0}, the avatar will not shown under the default user setting."),
                                            maxPolycount
                                            ), MessageType.Error);
            }
#else
            EditorGUILayout.HelpBox(_("VRChat SDK2 or SDK3 has not been imported."), MessageType.Error);
            isValid = false;
#endif

            return(true);
        }