/// <summary>
        /// 指定された<see cref="VRMSpringBoneColliderGroup"/>を基に<see cref="DynamicBoneCollider"/>を設定します。
        /// </summary>
        /// <param name="colliderGroup"></param>
        /// <param name="bonesForCollisionWithOtherAvatar"></param>
        /// <returns>生成した<see cref="DynamicBoneCollider"/>のリスト。</returns>
        private static IEnumerable <MonoBehaviour> ConvertVRMSpringBoneColliderGroup(
            VRMSpringBoneColliderGroup colliderGroup
            )
        {
            var bone = colliderGroup.gameObject;

            return(colliderGroup.Colliders.Select(collider => {
                var dynamicBoneCollider = bone.AddComponent(DynamicBoneColliderType);
                DynamicBoneColliderType.GetField("m_Center").SetValue(dynamicBoneCollider, collider.Offset);
                DynamicBoneColliderType.GetField("m_Radius").SetValue(dynamicBoneCollider, collider.Radius);
                return dynamicBoneCollider as MonoBehaviour;
            }).ToList());
        }
Example #2
0
        /// <summary>
        /// 指定された<see cref="VRMSpringBoneColliderGroup"/>を基に<see cref="DynamicBoneCollider"/>を設定します。
        /// </summary>
        /// <param name="colliderGroup"></param>
        /// <param name="bonesForCollisionWithOtherAvatar"></param>
        /// <returns>生成した<see cref="DynamicBoneCollider"/>のリスト。</returns>
        private static IEnumerable <dynamic> ConvertVRMSpringBoneColliderGroup(
            VRMSpringBoneColliderGroup colliderGroup
            )
        {
            var bone = colliderGroup.gameObject;

            return(colliderGroup.Colliders.Select(collider =>
            {
                dynamic dynamicBoneCollider = bone.AddComponent(DynamicBoneColliderType);
                dynamicBoneCollider.m_Center = collider.Offset;
                dynamicBoneCollider.m_Radius = collider.Radius;
                return dynamicBoneCollider;
            }).ToList());
        }
        /// <summary>
        /// VRMSpringBone、およびVRMSpringBoneColliderGroupをコピーします。
        /// </summary>
        /// <param name="sourceSpringBone"></param>
        /// <param name="destination"></param>
        /// <param name="sourceSkeletonBones"></param>
        /// <param name="transformMapping"></param>
        /// <returns>更新された <c>transformMapping</c> を返します。</returns>
        private static IDictionary <Transform, Transform> CopySpringBone(
            VRMSpringBone sourceSpringBone,
            GameObject destination,
            Dictionary <HumanBodyBones, Transform> sourceSkeletonBones,
            IDictionary <Transform, Transform> transformMapping
            )
        {
            var destinationSecondary = destination.transform.Find("secondary").gameObject;

            ComponentUtility.CopyComponent(sourceSpringBone);
            ComponentUtility.PasteComponentAsNew(destinationSecondary);
            var destinationSpringBone = destinationSecondary.GetComponents <VRMSpringBone>().Last();

            if (destinationSpringBone.m_center)
            {
                destinationSpringBone.m_center = transformMapping.ContainsKey(destinationSpringBone.m_center)
                    ? transformMapping[destinationSpringBone.m_center]
                    : (transformMapping[destinationSpringBone.m_center] = BoneMapper.FindCorrespondingBone(
                           sourceBone: destinationSpringBone.m_center,
                           source: sourceSpringBone.transform.root.gameObject,
                           destination,
                           sourceSkeletonBones
                           ));
            }

            for (var i = 0; i < destinationSpringBone.RootBones.Count; i++)
            {
                var sourceSpringBoneRoot = destinationSpringBone.RootBones[i];

                destinationSpringBone.RootBones[i] = sourceSpringBoneRoot
                    ? (transformMapping.ContainsKey(sourceSpringBoneRoot)
                        ? transformMapping[sourceSpringBoneRoot]
                        : (transformMapping[sourceSpringBoneRoot] = BoneMapper.FindCorrespondingBone(
                               sourceBone: sourceSpringBoneRoot,
                               source: sourceSpringBone.transform.root.gameObject,
                               destination,
                               sourceSkeletonBones
                               )))
                    : null;
            }

            for (var i = 0; i < destinationSpringBone.ColliderGroups.Length; i++)
            {
                var sourceColliderGroup = destinationSpringBone.ColliderGroups[i];

                var destinationColliderGroupTransform = sourceColliderGroup
                    ? (transformMapping.ContainsKey(sourceColliderGroup.transform)
                        ? transformMapping[sourceColliderGroup.transform]
                        : (transformMapping[sourceColliderGroup.transform] = BoneMapper.FindCorrespondingBone(
                               sourceBone: sourceColliderGroup.transform,
                               source: sourceSpringBone.transform.root.gameObject,
                               destination,
                               sourceSkeletonBones
                               )))
                    : null;

                VRMSpringBoneColliderGroup destinationColliderGroup = null;
                if (destinationColliderGroupTransform)
                {
                    CopyVRMSpringBones.CopySpringBoneColliderGroups(
                        sourceBone: sourceColliderGroup.transform,
                        destinationBone: destinationColliderGroupTransform
                        );
                    destinationColliderGroup
                        = destinationColliderGroupTransform.GetComponent <VRMSpringBoneColliderGroup>();
                }
                destinationSpringBone.ColliderGroups[i] = destinationColliderGroup;
            }

            return(transformMapping);
        }
Example #4
0
        /// <summary>
        /// 子孫の<see cref="DynamicBone"/>を基に<see cref="VRMSpringBone"/>を設定します。
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="swayingParametersConverter"></param>
        private static void SetSpringBones(GameObject instance, ParametersConverter swayingParametersConverter)
        {
            var boneInfo  = new BoneInfo(instance.GetComponent <VRMMeta>());
            var secondary = instance.transform.Find("secondary").gameObject;

            GameObject.DestroyImmediate(secondary.GetComponent <VRMSpringBone>());

            foreach (var dynamicBones in instance.GetComponentsInChildren(DynamicBoneType)
                     .Select((dynamic dynamicBone) =>
            {
                var parameters = swayingParametersConverter(new DynamicBoneParameters()
                {
                    Damping = dynamicBone.m_Damping,
                    DampingDistrib = dynamicBone.m_DampingDistrib,
                    Elasticity = dynamicBone.m_Elasticity,
                    ElasticityDistrib = dynamicBone.m_ElasticityDistrib,
                    Stiffness = dynamicBone.m_Stiffness,
                    StiffnessDistrib = dynamicBone.m_StiffnessDistrib,
                    Inert = dynamicBone.m_Inert,
                    InertDistrib = dynamicBone.m_InertDistrib,
                }, boneInfo);

                var colliderGroups = new List <VRMSpringBoneColliderGroup>();
                if (dynamicBone.m_Colliders != null)
                {
                    foreach (var collider in dynamicBone.m_Colliders)
                    {
                        if (!collider.transform.IsChildOf(instance.transform))
                        {
                            // ルート外の参照を除外
                            continue;
                        }

                        VRMSpringBoneColliderGroup colliderGroup
                            = collider.GetComponent <VRMSpringBoneColliderGroup>();
                        if (colliderGroup == null || colliderGroups.Contains(colliderGroup))
                        {
                            continue;
                        }

                        colliderGroups.Add(colliderGroup);
                    }
                }

                Vector3 gravity = dynamicBone.m_Gravity;
                return(dynamicBone, parameters, colliderGroups, compare: string.Join("\n", new[]
                {
                    parameters.StiffnessForce,
                    gravity.x,
                    gravity.y,
                    gravity.z,
                    parameters.DragForce,
                    (float)dynamicBone.m_Radius,
                }.Select(parameter => parameter.ToString("F2"))
                                                                                     .Concat(colliderGroups
                                                                                             .Select(colliderGroup => colliderGroup.transform.RelativePathFrom(instance.transform)))
                                                                                     ));
            })
                     .GroupBy(dynamicBones => dynamicBones.compare)) // 同一パラメータでグループ化
            {
                var dynamicBone = dynamicBones.First();
                var springBone  = secondary.AddComponent <VRMSpringBone>();
                springBone.m_stiffnessForce = dynamicBone.parameters.StiffnessForce;
                Vector3 gravity = dynamicBone.dynamicBone.m_Gravity;
                springBone.m_gravityPower = gravity.magnitude;
                springBone.m_gravityDir   = gravity.normalized;
                springBone.m_dragForce    = dynamicBone.parameters.DragForce;
                springBone.RootBones      = dynamicBones.Select(db => (Transform)db.dynamicBone.m_Root)
                                            .Where(transform => transform != null)
                                            .Distinct()
                                            .ToList();
                springBone.m_hitRadius    = dynamicBone.dynamicBone.m_Radius;
                springBone.ColliderGroups = dynamicBone.colliderGroups.ToArray();
            }
        }
        // Convert from VRMSpringBoneCollider
        public static SerializableSpringBoneColliderGroup FromSpringBoneColliderGroup(VRMSpringBoneColliderGroup colliderGroup)
        {
            Debug.Log($"Convert SpringBoneColliderGroup to serializable: Root={colliderGroup.transform.name}");

            var serializableCollider = new SerializableSpringBoneColliderGroup();

            serializableCollider.AttachedTo = HierarchyPath.FromTransform(colliderGroup.transform);

            // Copy values
            if (colliderGroup.Colliders != null)
            {
                foreach (var collider in colliderGroup.Colliders)
                {
                    serializableCollider.Colliders.Add(new SerializableSpringBoneCollider(collider.Offset, collider.Radius));
                }
            }

            return(serializableCollider);
        }