예제 #1
0
        public SpringBoneManager CreateVrmSpringBone(List <Node> nodes)
        {
            var gltfVrm = Gltf.Extensions.VRMCSpringBone;

            if ((gltfVrm is null))
            {
                return(null);
            }

            var springBone = new SpringBoneManager();

            // springs
            foreach (var group in gltfVrm.Springs.GroupBy(x => x.Setting.Value))
            {
                var sb = new SpringBone();
                sb.Comment   = group.First().Name;
                sb.HitRadius = group.First().HitRadius.Value;
                var setting = gltfVrm.Settings[group.Key];
                sb.DragForce    = setting.DragForce.Value;
                sb.GravityDir   = setting.GravityDir.ToVector3();
                sb.GravityPower = setting.GravityPower.Value;
                sb.Stiffness    = setting.Stiffness.Value;

                foreach (var spring in group)
                {
                    // root
                    sb.Bones.Add(nodes[spring.SpringRoot.Value]);
                    // collider
                    foreach (var colliderNode in spring.Colliders)
                    {
                        var collider = springBone.Colliders.FirstOrDefault(x => x.Node == nodes[colliderNode]);
                        if (collider == null)
                        {
                            collider = new SpringBoneColliderGroup(nodes[colliderNode], Gltf.Nodes[colliderNode].Extensions.VRMCNodeCollider.Shapes.Select(x =>
                            {
                                if (x.Sphere != null)
                                {
                                    return(VrmSpringBoneCollider.CreateSphere(x.Sphere.Offset.ToVector3(), x.Sphere.Radius.Value));
                                }
                                else if (x.Capsule != null)
                                {
                                    return(VrmSpringBoneCollider.CreateCapsule(x.Capsule.Offset.ToVector3(), x.Capsule.Radius.Value, x.Capsule.Tail.ToVector3()));
                                }
                                else
                                {
                                    throw new NotImplementedException();
                                }
                            }));
                            springBone.Colliders.Add(collider);
                        }
                        sb.Colliders.Add(collider);
                    }
                }

                springBone.Springs.Add(sb);
            }

            return(springBone);
        }
예제 #2
0
 static VrmSpringBoneCollider CreateCollider(VrmProtobuf.ColliderShape z)
 {
     if (z.Sphere != null)
     {
         return(VrmSpringBoneCollider.CreateSphere(z.Sphere.Offset.ToVector3(), z.Sphere.Radius.Value));
     }
     if (z.Capsule != null)
     {
         return(VrmSpringBoneCollider.CreateCapsule(z.Capsule.Offset.ToVector3(), z.Capsule.Radius.Value, z.Capsule.Tail.ToVector3()));
     }
     throw new NotImplementedException();
 }
예제 #3
0
        static VrmSpringBoneCollider CreateCollider(VrmProtobuf.VRMCSpringBone.Types.ColliderGroup.Types.Collider z)
        {
            switch (z.Type)
            {
            case VrmProtobuf.VRMCSpringBone.Types.ColliderGroup.Types.ColliderTypes.Sphere:
                return(VrmSpringBoneCollider.CreateSphere(z.Offset.ToVector3(), z.Radius));

            case VrmProtobuf.VRMCSpringBone.Types.ColliderGroup.Types.ColliderTypes.Capsule:
                return(VrmSpringBoneCollider.CreateCapsule(z.Offset.ToVector3(), z.Radius, z.Tail.ToVector3()));
            }

            throw new Exception();
        }
예제 #4
0
        public static bool LoadVrm(this Model self, Gltf gltf)
        {
            var gltfVrm = gltf.extensions?.VRM;

            if (gltfVrm == null)
            {
                return(false);
            }

            var Vrm = new Vrm(gltfVrm.meta.FromGltf(self.Textures), gltfVrm.exporterVersion, gltfVrm.specVersion);

            self.Vrm = Vrm;

            if (gltfVrm.humanoid != null)
            {
                foreach (var humanBone in gltfVrm.humanoid.humanBones)
                {
                    if (humanBone.bone != GltfFormat.HumanoidBones.unknown)
                    {
                        self.Nodes[humanBone.node].HumanoidBone = (VrmLib.HumanoidBones)humanBone.bone;
                    }
                }
            }

            if (!self.CheckVrmHumanoid())
            {
                throw new Exception("duplicate human bone");
            }

            // blendshape
            if (gltfVrm.blendShapeMaster != null &&
                gltfVrm.blendShapeMaster.blendShapeGroups != null &&
                gltfVrm.blendShapeMaster.blendShapeGroups.Any())
            {
                Vrm.BlendShape = gltfVrm.blendShapeMaster.FromGltf(self.MeshGroups, self.Materials, self.Nodes);
            }

            // secondary
            if (!(gltfVrm.secondaryAnimation is null))
            {
                Vrm.SpringBone = new SpringBoneManager();

                // colliders
                Vrm.SpringBone.Colliders.AddRange(
                    gltfVrm.secondaryAnimation.colliderGroups.Select(y =>
                                                                     new SpringBoneColliderGroup(
                                                                         self.Nodes[y.node],
                                                                         y.colliders.Select(z => VrmSpringBoneCollider.CreateSphere(z.offset, z.radius))
                                                                         )
                                                                     ));

                // springs
                Vrm.SpringBone.Springs.AddRange(gltfVrm.secondaryAnimation.boneGroups.Select(x =>
                {
                    var sb = new SpringBone();
                    sb.Bones.AddRange(x.bones.Select(y => self.Nodes[y]));
                    if (x.center >= 0)
                    {
                        sb.Origin = self.Nodes[x.center];
                    }
                    sb.Colliders.AddRange(x.colliderGroups.Select(y => Vrm.SpringBone.Colliders[y]));
                    sb.Comment      = x.comment;
                    sb.DragForce    = x.dragForce;
                    sb.GravityDir   = x.gravityDir;
                    sb.GravityPower = x.gravityPower;
                    sb.HitRadius    = x.hitRadius;
                    sb.Stiffness    = x.stiffiness;
                    return(sb);
                }));
            }

            // material(already replaced)

            if (gltfVrm.firstPerson != null)
            {
                Vrm.FirstPerson = gltfVrm.firstPerson.FromGltf(self.Nodes, self.MeshGroups);
                Vrm.LookAt      = gltfVrm.firstPerson.LookAtFromGltf();
                Vrm.LookAt.OffsetFromHeadBone = gltfVrm.firstPerson.firstPersonBoneOffset;
            }

            return(true);
        }
예제 #5
0
        public SpringBoneManager CreateVrmSpringBone(List <Node> nodes)
        {
            if ((gltfVrmSpringBone is null))
            {
                return(null);
            }

            var springBoneManager = new SpringBoneManager();

            // springs
            if (gltfVrmSpringBone.Springs != null)
            {
                foreach (var gltfSpring in gltfVrmSpringBone.Springs)
                {
                    var springBone = new SpringBone();
                    springBone.Comment = gltfSpring.Name;

                    // joint
                    foreach (var gltfJoint in gltfSpring.Joints)
                    {
                        var joint = new SpringJoint(nodes[gltfJoint.Node.Value]);
                        joint.HitRadius    = gltfJoint.HitRadius.Value;
                        joint.DragForce    = gltfJoint.DragForce.Value;
                        joint.GravityDir   = gltfJoint.GravityDir.ToVector3();
                        joint.GravityPower = gltfJoint.GravityPower.Value;
                        joint.Stiffness    = gltfJoint.Stiffness.Value;
                        joint.Exclude      = gltfJoint.Exclude.GetValueOrDefault();
                        springBone.Joints.Add(joint);
                    }

                    // collider
                    springBone.Colliders.AddRange(gltfSpring.Colliders.Select(colliderNode =>
                    {
                        if (UniGLTF.Extensions.VRMC_node_collider.GltfDeserializer.TryGet(Gltf.nodes[colliderNode].extensions,
                                                                                          out UniGLTF.Extensions.VRMC_node_collider.VRMC_node_collider extension))
                        {
                            var collider = new SpringBoneColliderGroup(nodes[colliderNode], extension.Shapes.Select(x =>
                            {
                                if (x.Sphere != null)
                                {
                                    return(VrmSpringBoneCollider.CreateSphere(x.Sphere.Offset.ToVector3(), x.Sphere.Radius.Value));
                                }
                                else if (x.Capsule != null)
                                {
                                    return(VrmSpringBoneCollider.CreateCapsule(x.Capsule.Offset.ToVector3(), x.Capsule.Radius.Value, x.Capsule.Tail.ToVector3()));
                                }
                                else
                                {
                                    throw new NotImplementedException();
                                }
                            }));
                            return(collider);
                        }
                        else
                        {
                            return(null);
                        }
                    }).Where(x => x != null));

                    springBoneManager.Springs.Add(springBone);
                }
            }

            return(springBoneManager);
        }