private void CreateMorphs(TBodySkin skin) { if (skin == null || skin.morph == null || skin.morph.BlendDatas.Count <= 0) { return; } if (!vertexIndexMap.ContainsKey(skin.obj.name)) { Debug.Log($"Morph: {skin.obj.name} -> Missing vertex base!"); return; } int vertexBase = vertexIndexMap[skin.obj.name]; Debug.Log($"Morph: {skin.obj.name} -> {skin.morph.BlendDatas.Count} ({vertexBase})"); for (int j = 0; j < skin.morph.BlendDatas.Count; j++) { BlendData blendData = skin.morph.BlendDatas[j]; if (blendData != null) { PmxMorph pmxMorph = GetOrCreateMorph(blendData.name); for (int k = 0; k < blendData.v_index.Length; k++) { PmxVertexMorph pmxVertexMorph = new PmxVertexMorph(blendData.v_index[k] + vertexBase, new PmxLib.Vector3(-blendData.vert[k].x, blendData.vert[k].z, blendData.vert[k].y)); pmxVertexMorph.Offset *= scaleFactor; pmxMorph.OffsetList.Add(pmxVertexMorph); } } } }
private PmxVertexMorph ReadPmxVertexMorph() { var morph = new PmxVertexMorph(); morph.Index = _reader.ReadVarLenIntAsInt32(VertexElementSize, true); morph.Offset = _reader.ReadVector3(); return(morph); }
private void WritePmxVertexMorph([NotNull] PmxVertexMorph morph) { _writer.WriteInt32AsVarLenInt(morph.Index, MorphElementSize); _writer.Write(morph.Offset); }
private static IReadOnlyList <PmxMorph> AddEmotionMorphs([NotNull] Mesh mesh) { var morphs = new List <PmxMorph>(); var s = mesh.Shape; if (s != null) { Debug.Assert(s.Channels.Count == s.Shapes.Count, "s.Channels.Count == s.Shapes.Count"); Debug.Assert(s.Channels.Count == s.FullWeights.Count, "s.Channels.Count == s.FullWeights.Count"); var morphCount = s.Channels.Count; for (var i = 0; i < morphCount; i++) { var channel = s.Channels[i]; var shape = s.Shapes[i]; var vertices = s.Vertices; var morph = new PmxMorph(); var morphName = channel.Name.Substring(12); // - "blendShape1." if (ConversionConfig.Current.TranslateFacialExpressionNamesToMmd) { morph.Name = MorphUtils.LookupMorphName(morphName); } else { morph.Name = morphName; } morph.NameEnglish = morphName; morph.OffsetKind = MorphOffsetKind.Vertex; var offsets = new List <PmxBaseMorph>(); for (var j = shape.FirstVertex; j < shape.FirstVertex + shape.VertexCount; ++j) { var v = vertices[(int)j]; var m = new PmxVertexMorph(); var offset = v.Vertex.ToOpenTK().FixUnityToOpenTK(); if (ConversionConfig.Current.ScaleToPmxSize) { offset = offset * ScalingConfig.ScaleUnityToPmx; } m.Index = (int)v.Index; m.Offset = offset; offsets.Add(m); } morph.Offsets = offsets.ToArray(); morphs.Add(morph); } // Now some custom morphs for our model to be compatible with TDA. do { PmxMorph CreateCompositeMorph(string mltdTruncMorphName, params string[] truncNames) { int FindIndex <T>(IReadOnlyList <T> list, T item) { var comparer = EqualityComparer <T> .Default; for (var i = 0; i < list.Count; ++i) { if (comparer.Equals(item, list[i])) { return(i); } } return(-1); } var morph = new PmxMorph(); if (ConversionConfig.Current.TranslateFacialExpressionNamesToMmd) { morph.Name = MorphUtils.LookupMorphName(mltdTruncMorphName); } else { morph.Name = mltdTruncMorphName; } morph.NameEnglish = mltdTruncMorphName; var offsets = new List <PmxBaseMorph>(); var vertices = s.Vertices; foreach (var channel in truncNames.Select(name => { // name: e.g. "E_metoji_l" // ch_ex005_016tsu has "blendShape2.E_metoji_l" instead of the common one "blendShape1.E_metoji_l" // so the old method (string equal to full name) breaks. var chan = s.Channels.SingleOrDefault(ch => ch.Name.EndsWith(name)); if (chan == null) { Trace.WriteLine($"Warning: required blend channel not found: {name}"); } return(chan); })) { if (channel == null) { continue; } var channelIndex = FindIndex(s.Channels, channel); var shape = s.Shapes[channelIndex]; morph.OffsetKind = MorphOffsetKind.Vertex; for (var j = shape.FirstVertex; j < shape.FirstVertex + shape.VertexCount; ++j) { var v = vertices[(int)j]; var m = new PmxVertexMorph(); var offset = v.Vertex.ToOpenTK().FixUnityToOpenTK(); if (ConversionConfig.Current.ScaleToPmxSize) { offset = offset * ScalingConfig.ScaleUnityToPmx; } m.Index = (int)v.Index; m.Offset = offset; offsets.Add(m); } } morph.Offsets = offsets.ToArray(); return(morph); } morphs.Add(CreateCompositeMorph("E_metoji", "E_metoji_l", "E_metoji_r")); } while (false); } return(morphs.ToArray()); }