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); }
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(); }
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(); }
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); }
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); }