Example #1
0
        public static void FixSwayReferences([NotNull, ItemNotNull] params SwayController[] controllers)
        {
            var colliders = new List <SwayCollider>();
            var joints    = new List <SwayBone>();

            foreach (var controller in controllers)
            {
                colliders.AddRange(controller.Colliders);
                joints.AddRange(controller.SwayBones);
            }

            foreach (var collider in colliders)
            {
                if (collider.BridgeTargetPath == null)
                {
                    continue;
                }

                var target = colliders.Find(col => col.Path == collider.BridgeTargetPath);

                Debug.Assert(target != null);

                collider.BridgeTarget = target;
            }

            foreach (var joint in joints)
            {
                if (joint.SideLinkPath != null)
                {
                    var sideLink = joints.Find(link => link.Path == joint.SideLinkPath);

                    Debug.Assert(sideLink != null);

                    joint.SideLink = sideLink;
                }

                if (joint.ColliderPaths != null)
                {
                    var swayBoneColliders = new SwayCollider[joint.ColliderPaths.Length];

                    for (var i = 0; i < joint.ColliderPaths.Length; ++i)
                    {
                        // e.g.: MODEL_00/BODY_SCALE/BASE/KOSHI/MOMO_L#0
                        var targetPath = joint.ColliderPaths[i];

                        var indexOfHash = targetPath.IndexOf('#');

                        if (indexOfHash >= 0)
                        {
                            targetPath = targetPath.Substring(0, indexOfHash);
                        }

                        var collider = colliders.Find(col => col.Path == targetPath);

                        Debug.Assert(collider != null);

                        swayBoneColliders[i] = collider;
                    }

                    joint.Colliders = swayBoneColliders;
                }
            }
        }
Example #2
0
        public static SwayController Parse([NotNull] string text)
        {
            var lines = text.Split(LineSeps);

            for (var i = 0; i < lines.Length; ++i)
            {
                var l = lines[i];

                if (l.Length == 0)
                {
                    continue;
                }

                if (l[l.Length - 1] == '\r')
                {
                    lines[i] = l.TrimEnd(TrimSeps);
                }
            }

            var controller = new SwayController();

            var managers  = new List <SwayManager>();
            var colliders = new List <SwayCollider>();
            var swayBones = new List <SwayBone>();

            for (var i = 0; i < lines.Length; ++i)
            {
                var line = lines[i];

                if (line.Length == 0)
                {
                    continue;
                }

                var topKeyValue = ParseKeyValue(line);

                switch (topKeyValue.Key)
                {
                case "Top":
                    controller.Top = topKeyValue.Value;
                    break;

                case "SwayManager":
                    var sm = ReadSwayManger();
                    managers.Add(sm);
                    break;

                case "SwayCollider":
                    var sc = ReadSwayCollider();
                    colliders.Add(sc);
                    break;

                case "SwayBone":
                    var sb = ReadSwayBone();
                    swayBones.Add(sb);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(topKeyValue.Key), topKeyValue.Key, null);
                }

                SwayManager ReadSwayManger()
                {
                    var kv         = ParseKeyValue(line);
                    var manager    = new SwayManager();
                    var anyPropSet = false;

                    do
                    {
                        switch (kv.Key)
                        {
                        case "SwayManager":
                            manager.Path = kv.Value;
                            break;

                        case "gravity":
                            manager.Gravity = ParseVector3(kv.Value);
                            anyPropSet      = true;
                            break;

                        case "stiffnessForce":
                            manager.StiffnessForce = Convert.ToSingle(kv.Value);
                            anyPropSet             = true;
                            break;

                        case "dragForce":
                            manager.DragForce = Convert.ToSingle(kv.Value);
                            anyPropSet        = true;
                            break;

                        case "followForce":
                            manager.FollowForce = Convert.ToSingle(kv.Value);
                            anyPropSet          = true;
                            break;

                        case "lineMoveLimit":
                            manager.LineMoveLimit = Convert.ToSingle(kv.Value);
                            anyPropSet            = true;
                            break;

                        case "sidelineMoveLimit":
                            manager.SideLineMoveLimit = Convert.ToSingle(kv.Value);
                            anyPropSet = true;
                            break;

                        default:
                            Debug.Print("Unknow property key/value: {0} / {1}", kv.Key, kv.Value);
                            break;
                        }

                        {
                            ++i;
                            line = lines[i];

                            if (line.Length == 0 || line[0] != ' ')
                            {
                                // A new entry (manager/collider/bone) starts.
                                // Decrease counter so the next reading attempt will work with auto counter increment.
                                --i;
                                break;
                            }

                            kv = ParseKeyValue(line);
                        }
                    } while (true);

                    if (!anyPropSet)
                    {
                        throw new ArgumentException("Empty SwayManager body");
                    }

                    return(manager);
                }

                SwayCollider ReadSwayCollider()
                {
                    var kv         = ParseKeyValue(line);
                    var collider   = new SwayCollider();
                    var anyPropSet = false;

                    do
                    {
                        switch (kv.Key)
                        {
                        case "SwayCollider":
                            collider.Path = kv.Value;
                            break;

                        case "type":
                            collider.Type = ParseColliderType(kv.Value);
                            anyPropSet    = true;
                            break;

                        case "axis":
                            collider.Axis = ParseCollidingAxis(kv.Value);
                            anyPropSet    = true;
                            break;

                        case "radius":
                            collider.Radius = Convert.ToSingle(kv.Value);
                            anyPropSet      = true;
                            break;

                        case "distance":
                            collider.Distance = Convert.ToSingle(kv.Value);
                            anyPropSet        = true;
                            break;

                        case "offset":
                            collider.Offset = ParseVector3(kv.Value);
                            anyPropSet      = true;
                            break;

                        case "planeAxis":
                            collider.PlaneAxis = ParsePlaneAxis(kv.Value);
                            anyPropSet         = true;
                            break;

                        case "CapsuleSphere1":
                            collider.CapsuleSphere1 = Convert.ToBoolean(kv.Value);
                            anyPropSet = true;
                            break;

                        case "CapsuleSphere2":
                            collider.CapsuleSphere2 = Convert.ToBoolean(kv.Value);
                            anyPropSet = true;
                            break;

                        case "planeRotOn":
                            collider.PlaneRotationEnabled = Convert.ToBoolean(kv.Value);
                            anyPropSet = true;
                            break;

                        case "planeRotEuler":
                            collider.PlaneRotationEuler = ParseVector3(kv.Value);
                            anyPropSet = true;
                            break;

                        case "bridgetgt":
                            collider.BridgeTargetPath = kv.Value;
                            anyPropSet = true;
                            break;

                        default:
                            Debug.Print("Unknow property key/value: {0} / {1}", kv.Key, kv.Value);
                            break;
                        }

                        {
                            ++i;
                            line = lines[i];

                            if (line.Length == 0 || line[0] != ' ')
                            {
                                // A new entry (manager/collider/bone) starts.
                                // Decrease counter so the next reading attempt will work with auto counter increment.
                                --i;
                                break;
                            }

                            kv = ParseKeyValue(line);
                        }
                    } while (true);

                    if (!anyPropSet)
                    {
                        throw new ArgumentException("Empty SwayCollider body");
                    }

                    return(collider);
                }

                SwayBone ReadSwayBone()
                {
                    var kv         = ParseKeyValue(line);
                    var bone       = new SwayBone();
                    var anyPropSet = false;

                    do
                    {
                        switch (kv.Key)
                        {
                        case "SwayBone":
                            bone.Path = kv.Value;
                            break;

                        case "radius":
                            bone.Radius = Convert.ToSingle(kv.Value);
                            anyPropSet  = true;
                            break;

                        case "type":
                            bone.Type  = ParseColliderType(kv.Value);
                            anyPropSet = true;
                            break;

                        case "isSkirt":
                            bone.IsSkirt = Convert.ToBoolean(kv.Value);
                            anyPropSet   = true;
                            break;

                        case "HitMuteForce":
                            bone.HitMuteForce = Convert.ToBoolean(kv.Value);
                            anyPropSet        = true;
                            break;

                        case "HitMuteRate":
                            bone.HitMuteRate = Convert.ToSingle(kv.Value);
                            anyPropSet       = true;
                            break;

                        case "limitAngle":
                            bone.HasAngleLimit = Convert.ToBoolean(kv.Value);
                            anyPropSet         = true;
                            break;

                        case "useBindDir":
                            bone.UseBindingDirection = Convert.ToBoolean(kv.Value);
                            anyPropSet = true;
                            break;

                        case "minYAngle":
                            bone.MinYAngle = Convert.ToSingle(kv.Value);
                            anyPropSet     = true;
                            break;

                        case "maxYAngle":
                            bone.MaxYAngle = Convert.ToSingle(kv.Value);
                            anyPropSet     = true;
                            break;

                        case "minZAngle":
                            bone.MinZAngle = Convert.ToSingle(kv.Value);
                            anyPropSet     = true;
                            break;

                        case "maxZAngle":
                            bone.MaxZAngle = Convert.ToSingle(kv.Value);
                            anyPropSet     = true;
                            break;

                        case "followForce":
                            bone.FollowForce = Convert.ToSingle(kv.Value);
                            anyPropSet       = true;
                            break;

                        case "refParam":
                            bone.RefParam = ParseRefParam(kv.Value);
                            anyPropSet    = true;
                            break;

                        case "stiffnessForce":
                            bone.StiffnessForce = Convert.ToSingle(kv.Value);
                            anyPropSet          = true;
                            break;

                        case "dragForce":
                            bone.DragForce = Convert.ToSingle(kv.Value);
                            anyPropSet     = true;
                            break;

                        case "hitTwice":
                            bone.HitTwice = Convert.ToBoolean(kv.Value);
                            anyPropSet    = true;
                            break;

                        case "useLinkHit":
                            bone.UseLinkHit = Convert.ToBoolean(kv.Value);
                            anyPropSet      = true;
                            break;

                        case "gravity":
                            bone.Gravity = ParseVector3(kv.Value);
                            anyPropSet   = true;
                            break;

                        case "colliderOffset":
                            bone.ColliderOffset = ParseVector3(kv.Value);
                            anyPropSet          = true;
                            break;

                        case "sideSpringTorelance":
                            bone.SideSpringTolerance = Convert.ToSingle(kv.Value);
                            anyPropSet = true;
                            break;

                        case "sideSpringForce":
                            bone.SideSpringForce = Convert.ToSingle(kv.Value);
                            anyPropSet           = true;
                            break;

                        case "colliders": {
                            var colliderCount    = Convert.ToInt32(kv.Value);
                            var colliderPathList = new List <string>();

                            for (var j = 0; j < colliderCount; ++j)
                            {
                                ++i;
                                line = lines[i];

                                kv = ParseKeyValue(line);

                                colliderPathList.Add(kv.Value);
                            }

                            anyPropSet = true;

                            bone.ColliderPaths = colliderPathList.ToArray();
                        }
                        break;

                        case "sideLink":
                            bone.SideLinkPath = kv.Value;
                            anyPropSet        = true;
                            break;

                        default:
                            Debug.Print("Unknow property key/value: {0} / {1}", kv.Key, kv.Value);
                            break;
                        }

                        {
                            ++i;
                            line = lines[i];

                            if (line.Length == 0 || line[0] != ' ')
                            {
                                // A new entry (manager/collider/bone) starts.
                                // Decrease counter so the next reading attempt will work with auto counter increment.
                                --i;
                                break;
                            }

                            kv = ParseKeyValue(line);
                        }
                    } while (true);

                    if (!anyPropSet)
                    {
                        throw new ArgumentException("Empty SwayBone body");
                    }

                    return(bone);
                }
            }

            controller.Managers  = managers.ToArray();
            controller.Colliders = colliders.ToArray();
            controller.SwayBones = swayBones.ToArray();

            return(controller);
        }