/// <summary> /// { /// "colliderGroups": [ /// ], /// "boneGroups": [ /// ], /// } /// </summary> /// <param name="gltf"></param> /// <param name="vrm0"></param> /// <returns></returns> public static VRMC_springBone Migrate(UniGLTF.glTF gltf, JsonNode vrm0) { var springBone = new VRMC_springBone { Colliders = new List <Collider>(), ColliderGroups = new List <ColliderGroup>(), Springs = new List <Spring>(), }; // NOTE: ColliderGroups をマイグレーションする. // ColliderGroup は Spring から index で参照されているため、順序を入れ替えたり増減させてはいけない. foreach (var vrm0ColliderGroup in vrm0["colliderGroups"].ArrayItems()) { // { // "node": 14, // "colliders": [ // { // "offset": { // "x": 0.025884293, // "y": -0.120000005, // "z": 0 // }, // "radius": 0.05 // }, // { // "offset": { // "x": -0.02588429, // "y": -0.120000005, // "z": 0 // }, // "radius": 0.05 // }, // { // "offset": { // "x": 0, // "y": -0.0220816135, // "z": 0 // }, // "radius": 0.08 // } // ] // }, // NOTE: 1.0 では ColliderGroup は Collider の実体ではなく index を参照する. var colliderIndices = new List <int>(); if (vrm0ColliderGroup.ContainsKey("node") && vrm0ColliderGroup.ContainsKey("colliders")) { var nodeIndex = vrm0ColliderGroup["node"].GetInt32(); // NOTE: ColliderGroup に含まれる Collider をマイグレーションする. foreach (var vrm0Collider in vrm0ColliderGroup["colliders"].ArrayItems()) { if (!vrm0Collider.ContainsKey("offset")) { continue; } if (!vrm0Collider.ContainsKey("radius")) { continue; } colliderIndices.Add(springBone.Colliders.Count); springBone.Colliders.Add(new Collider { Node = nodeIndex, Shape = new ColliderShape { Sphere = new ColliderShapeSphere { Offset = MigrateVector3.Migrate(vrm0Collider["offset"]), Radius = vrm0Collider["radius"].GetSingle() } } }); } } var colliderGroup = new ColliderGroup() { Colliders = colliderIndices.ToArray(), }; springBone.ColliderGroups.Add(colliderGroup); } foreach (var vrm0BoneGroup in vrm0["boneGroups"].ArrayItems()) { // { // "comment": "", // "stiffiness": 2, // "gravityPower": 0, // "gravityDir": { // "x": 0, // "y": -1, // "z": 0 // }, // "dragForce": 0.7, // "center": -1, // "hitRadius": 0.02, // "bones": [ // 97, // 99, // 101, // 113, // 114 // ], // "colliderGroups": [ // 3, // 4, // 5 // ] // }, var migrator = new SpringBoneGroupMigrator(gltf, vrm0BoneGroup); springBone.Springs.AddRange(migrator.Springs); } return(springBone); }
public static VRMC_springBone ToGltf(this SpringBoneManager self, List <Node> nodes, List <glTFNode> gltfNodes) { if (self == null) { return(null); } var springBone = new VRMC_springBone(); // // VRMC_node_collider // foreach (var x in self.Colliders) { var index = nodes.IndexOfThrow(x.Node); var collider = new VRMC_node_collider(); foreach (var y in x.Colliders) { switch (y.ColliderType) { case VrmSpringBoneColliderTypes.Sphere: { var sphere = new ColliderShapeSphere { Radius = y.Radius, Offset = y.Offset.ToFloat3(), }; collider.Shapes.Add(new ColliderShape { Sphere = sphere, }); break; } case VrmSpringBoneColliderTypes.Capsule: { var capsule = new ColliderShapeCapsule { Radius = y.Radius, Offset = y.Offset.ToFloat3(), Tail = y.CapsuleTail.ToFloat3(), }; collider.Shapes.Add(new ColliderShape { Capsule = capsule, }); } break; default: throw new NotImplementedException(); } } // // add to node.extensions // UniGLTF.Extensions.VRMC_node_collider.GltfSerializer.SerializeTo(ref gltfNodes[index].extensions, collider); } // // VRMC_springBone // foreach (var x in self.Springs) { var settingIndex = springBone.Settings.Count; springBone.Settings.Add(x.ToGltf(nodes)); foreach (var bone in x.Bones) { var spring = new Spring { Name = x.Comment, HitRadius = x.HitRadius, SpringRoot = nodes.IndexOfThrow(bone), Setting = settingIndex, Colliders = x.Colliders.Select(y => nodes.IndexOfThrow(y.Node)).ToArray(), }; springBone.Springs.Add(spring); } } return(springBone); }
/// <summary> /// { /// "colliderGroups": [ /// ], /// "boneGroups": [ /// ], /// } /// </summary> /// <param name="gltf"></param> /// <param name="vrm0"></param> /// <returns></returns> public static VRMC_springBone Migrate(UniGLTF.glTF gltf, JsonNode vrm0) { var springBone = new VRMC_springBone { Colliders = new List <Collider>(), ColliderGroups = new List <ColliderGroup>(), Springs = new List <Spring>(), }; foreach (var vrm0ColliderGroup in vrm0["colliderGroups"].ArrayItems()) { // { // "node": 14, // "colliders": [ // { // "offset": { // "x": 0.025884293, // "y": -0.120000005, // "z": 0 // }, // "radius": 0.05 // }, // { // "offset": { // "x": -0.02588429, // "y": -0.120000005, // "z": 0 // }, // "radius": 0.05 // }, // { // "offset": { // "x": 0, // "y": -0.0220816135, // "z": 0 // }, // "radius": 0.08 // } // ] // }, var colliders = new List <int>(); foreach (var vrm0Collider in vrm0ColliderGroup["colliders"].ArrayItems()) { colliders.Add(springBone.Colliders.Count); springBone.Colliders.Add(new Collider { Node = vrm0ColliderGroup["node"].GetInt32(), Shape = new ColliderShape { Sphere = new ColliderShapeSphere { Offset = MigrateVector3.Migrate(vrm0Collider["offset"]), Radius = vrm0Collider["radius"].GetSingle() } } }); } var colliderGroup = new ColliderGroup() { Colliders = colliders.ToArray(), }; springBone.ColliderGroups.Add(colliderGroup); } foreach (var vrm0BoneGroup in vrm0["boneGroups"].ArrayItems()) { // { // "comment": "", // "stiffiness": 2, // "gravityPower": 0, // "gravityDir": { // "x": 0, // "y": -1, // "z": 0 // }, // "dragForce": 0.7, // "center": -1, // "hitRadius": 0.02, // "bones": [ // 97, // 99, // 101, // 113, // 114 // ], // "colliderGroups": [ // 3, // 4, // 5 // ] // }, var migrator = new SpringBoneGroupMigrator(gltf, vrm0BoneGroup); springBone.Springs.AddRange(migrator.Springs); } return(springBone); }
public static VRMC_springBone ToGltf(this SpringBoneManager self, List <Node> nodes, List <glTFNode> gltfNodes) { if (self == null) { return(null); } var springBone = new VRMC_springBone(); // // VRMC_node_collider // foreach (var nodeCollider in self.Springs.SelectMany(x => x.Colliders)) { var index = nodes.IndexOfThrow(nodeCollider.Node); var gltfCollider = new VRMC_node_collider(); foreach (var y in nodeCollider.Colliders) { switch (y.ColliderType) { case VrmSpringBoneColliderTypes.Sphere: { var sphere = new ColliderShapeSphere { Radius = y.Radius, Offset = y.Offset.ToFloat3(), }; gltfCollider.Shapes.Add(new ColliderShape { Sphere = sphere, }); break; } case VrmSpringBoneColliderTypes.Capsule: { var capsule = new ColliderShapeCapsule { Radius = y.Radius, Offset = y.Offset.ToFloat3(), Tail = y.CapsuleTail.ToFloat3(), }; gltfCollider.Shapes.Add(new ColliderShape { Capsule = capsule, }); } break; default: throw new NotImplementedException(); } } // // add to node.extensions // UniGLTF.Extensions.VRMC_node_collider.GltfSerializer.SerializeTo(ref gltfNodes[index].extensions, gltfCollider); } // // VRMC_springBone // foreach (var x in self.Springs) { var spring = new Spring { Name = x.Comment, Colliders = x.Colliders.Select(y => nodes.IndexOfThrow(y.Node)).ToArray(), }; foreach (var y in x.Joints) { spring.Joints.Add(new SpringBoneJoint { HitRadius = y.HitRadius, DragForce = y.DragForce, GravityDir = y.GravityDir.ToFloat3(), GravityPower = y.GravityPower, Stiffness = y.Stiffness, }); } springBone.Springs.Add(spring); } return(springBone); }