internal void DropFileToHandle(IntPtr handle, dynamic script, string directory) { if (PmxModel.ShouldDrop(script)) { Drop(handle, new StringCollection() { Path.Combine(directory, ExportFileName + ".pmx") }); if (VmdSequence.ShouldDrop(script)) { Drop(handle, new StringCollection() { Path.Combine(directory, ExportFileName + ".vmd") }); } } void Drop(IntPtr hWnd, StringCollection filePaths) { Clipboard.Clear(); Clipboard.SetFileDropList(filePaths); var data = Clipboard.GetDataObject(); IDropTarget target = Control.FromHandle(hWnd); DragDropEffects dwEffect = DragDropEffects.Copy | DragDropEffects.Link; target.OnDragDrop(new DragEventArgs(data, 0, 0, 0, dwEffect, dwEffect)); Clipboard.Clear(); } }
private void BuildTextureNameMap([NotNull] PmxModel model) { var materials = model.Materials; if (materials == null) { return; } var nameList = new List <string>(); foreach (var material in materials) { if (!string.IsNullOrEmpty(material.TextureFileName)) { nameList.Add(material.TextureFileName); } if (!string.IsNullOrEmpty(material.SphereTextureFileName)) { nameList.Add(material.SphereTextureFileName); } if (!string.IsNullOrEmpty(material.ToonTextureFileName) && !ToonNameRegex.IsMatch(material.ToonTextureFileName)) { nameList.Add(material.ToonTextureFileName); } } _textureNameList.AddRange(nameList.Distinct()); }
public void InitializeContents([NotNull] PmxModel pmxModel, [NotNull] Camera camera, [NotNull] SpriteBatch spriteBatch) { _pmxModel = pmxModel; _camera = camera; var boneSegmentCount = pmxModel.Bones.Count - pmxModel.RootBoneIndices.Count; var boneSegmentPairs = new(int ParentIndex, int ChildIndex)[boneSegmentCount];
public static void ExportMaterial(PmxModel pmx, Stream outputStream) { var oldCulture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; try { using (var writer = new StreamWriter(outputStream, Encoding.Default, 2048, true)) { foreach (var mat in pmx.Materials) { writer.WriteLine($"newmtl mat{pmx.Materials.IndexOf(mat)}"); writer.WriteLine($"Ka {mat.AmbientColor.X} {mat.AmbientColor.Y} {mat.AmbientColor.Z}"); writer.WriteLine($"Kd {mat.DiffuseColor.X} {mat.DiffuseColor.Y} {mat.DiffuseColor.Z}"); //writer.WriteLine($"Ks {mat.SpecularColor.X} {mat.SpecularColor.Y} {mat.SpecularColor.Z}"); //writer.WriteLine($"Ns {mat.SpecularStrength}"); //writer.WriteLine($"d {mat.DiffuseColor.W}"); //writer.WriteLine($"Tr {1 - mat.DiffuseColor.W}"); //writer.WriteLine($"illum 2"); if (mat.TextureIndex > 0) { writer.WriteLine($"map_Ka {pmx.Textures[mat.TextureIndex].Replace("\\", "/")}"); writer.WriteLine($"map_Kd {pmx.Textures[mat.TextureIndex].Replace("\\", "/")}"); } writer.WriteLine(); //writer.WriteLine($"map_Ks {pmx.Textures[mat.TextureIndex]}"); } } } finally { Thread.CurrentThread.CurrentCulture = oldCulture; } }
private string[] BuildTextureNameMap([NotNull] PmxModel model) { var materials = model.Materials; var nameList = new List <string>(); foreach (var material in materials) { if (!string.IsNullOrEmpty(material.TextureFileName)) { nameList.Add(material.TextureFileName); } if (!string.IsNullOrEmpty(material.SphereTextureFileName)) { nameList.Add(material.SphereTextureFileName); } if (!string.IsNullOrEmpty(material.ToonTextureFileName) && !ToonNameRegex.IsMatch(material.ToonTextureFileName)) { nameList.Add(material.ToonTextureFileName); } } return(nameList.Distinct().ToArray()); }
public void Write([NotNull] PmxModel model) { EnsureNotDisposed(); WriteHeader(); WriteElementFormats(model); WritePmxModel(model); }
private void WriteJointInfo([NotNull] PmxModel model) { _writer.Write(model.Joints.Length); foreach (var joint in model.Joints) { WritePmxJoint(joint); } }
private void WriteRigidBodyInfo([NotNull] PmxModel model) { _writer.Write(model.RigidBodies.Length); foreach (var body in model.RigidBodies) { WritePmxRigidBody(body); } }
private void WriteNodeInfo([NotNull] PmxModel model) { _writer.Write(model.Nodes.Length); foreach (var node in model.Nodes) { WritePmxNode(node); } }
private void WriteMorphInfo([NotNull] PmxModel model) { _writer.Write(model.Morphs.Length); foreach (var morph in model.Morphs) { WritePmxMorph(morph); } }
private void WriteBoneInfo([NotNull] PmxModel model) { _writer.Write(model.Bones.Length); foreach (var bone in model.Bones) { WritePmxBone(bone); } }
private void WriteMaterialInfo([NotNull] PmxModel model, [NotNull, ItemNotNull] string[] textureNames) { _writer.Write(model.Materials.Length); foreach (var material in model.Materials) { WritePmxMaterial(material, textureNames); } }
private void WriteFaceInfo([NotNull] PmxModel model) { _writer.Write(model.FaceTriangles.Length); foreach (var v in model.FaceTriangles) { _writer.WriteInt32AsVarLenInt(v, VertexElementSize, true); } }
private void WriteVertexInfo([NotNull] PmxModel model) { _writer.Write(model.Vertices.Length); foreach (var vertex in model.Vertices) { WritePmxVertex(model, vertex); } }
internal void Export(dynamic script, string directory) { PmxModel.FinalizeModel(VmdSequence.MorphFrameDict.Values.Select(t => t.frame)); VmdSequence.FinalizeKeyFrame(PmxModel.ModelData.MorphArray); ExportEvent?.Invoke(this, new ExportEventArgs(Path.Combine(directory, ExportFileName + ".pmx"), Path.Combine(directory, ExportFileName + ".vmd")) { Script = script }); }
private void WritePmxVertex([NotNull] PmxModel model, [NotNull] PmxVertex vertex) { _writer.Write(vertex.Position); _writer.Write(vertex.Normal); _writer.Write(vertex.UV); for (var i = 0; i < model.UvaCount && i < PmxVertex.MaxUvaCount; ++i) { _writer.Write(vertex.Uva[i]); } _writer.Write((byte)vertex.Deformation); switch (vertex.Deformation) { case Deformation.Bdef1: _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[0].BoneIndex, BoneElementSize); break; case Deformation.Bdef2: _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[0].BoneIndex, BoneElementSize); _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[1].BoneIndex, BoneElementSize); _writer.Write(vertex.BoneWeights[0].Weight); break; case Deformation.Bdef4: case Deformation.Qdef: _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[0].BoneIndex, BoneElementSize); _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[1].BoneIndex, BoneElementSize); _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[2].BoneIndex, BoneElementSize); _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[3].BoneIndex, BoneElementSize); _writer.Write(vertex.BoneWeights[0].Weight); _writer.Write(vertex.BoneWeights[1].Weight); _writer.Write(vertex.BoneWeights[2].Weight); _writer.Write(vertex.BoneWeights[3].Weight); break; case Deformation.Sdef: { _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[0].BoneIndex, BoneElementSize); _writer.WriteInt32AsVarLenInt(vertex.BoneWeights[1].BoneIndex, BoneElementSize); _writer.Write(vertex.BoneWeights[0].Weight); _writer.Write(vertex.C0); _writer.Write(vertex.R0); _writer.Write(vertex.R1); break; } default: throw new ArgumentOutOfRangeException(); } _writer.Write(vertex.EdgeScale); }
public BoneNode[] BuildBoneHierarchy([NotNull] PmxModel pmx) { var boneList = new List <BoneNode>(); var pmxBones = pmx.Bones; var pmxBoneCount = pmxBones.Length; var boneNameMapInversion = _boneNameMapInversion; for (var i = 0; i < pmxBoneCount; i++) { var pmxBone = pmxBones[i]; var parent = pmxBone.ParentIndex >= 0 ? boneList[pmxBone.ParentIndex] : null; boneNameMapInversion.TryGetValue(pmx.Name, out var mltdBoneName); var path = mltdBoneName ?? pmxBone.Name; Vector3 t; if (parent != null) { t = pmxBone.InitialPosition - parent.InitialPosition; } else { t = pmxBone.InitialPosition; } var bone = new BoneNode(parent, i, path, t, Quaternion.Identity); boneList.Add(bone); } foreach (var bone in boneList) { var level = 0; var parent = bone.Parent; while (parent != null) { ++level; parent = parent.Parent; } bone.Level = level; } foreach (var bone in boneList) { bone.Initialize(); } return(boneList.ToArray()); }
internal ShotModelData AddShot(EntityShotBase entity) { ShotModelProvider.AddEntity(entity, out ShotModelData data); if (!data.IsInitialized) { PmxModel.InitShotModelData(data); } return(data); }
internal void Export() { EntityList.ForEach(e => e.OnDeath()); PmxModel.FinalizeModel(); KeyFrames.Finish(); KeyFrames.Export(); PmxModel.Export(); OnExport(EventArgs.Empty); }
// Set the bones that appear in the animation file as "key bone" private static void MarkNamedBoneAsKeyBone([NotNull] PmxModel pmx, [NotNull] string name) { var bone = pmx.Bones.Find(b => b.Name == name); if (bone != null) { bone.IsMltdKeyBone = true; } else { Debug.WriteLine($"Warning: trying to mark bone {name} as MLTD key bone but the bone is missing from the model."); } }
public IReadOnlyList <BoneNode> BuildBoneHierarchy([NotNull] PmxModel pmx) { var boneList = new List <BoneNode>(); for (var i = 0; i < pmx.Bones.Count; i++) { var pmxBone = pmx.Bones[i]; var parent = pmxBone.ParentIndex >= 0 ? boneList[pmxBone.ParentIndex] : null; var mltdBoneName = _boneNameMap.SingleOrDefault(kv => kv.Value == pmx.Name).Key; var path = mltdBoneName ?? pmxBone.Name; Vector3 t; if (parent != null) { t = pmxBone.InitialPosition - parent.InitialPosition; } else { t = pmxBone.InitialPosition; } var bone = new BoneNode(parent, i, path, t, Quaternion.Identity); boneList.Add(bone); } foreach (var bone in boneList) { var level = 0; var parent = bone.Parent; while (parent != null) { ++level; parent = parent.Parent; } bone.Level = level; } foreach (var bone in boneList) { bone.Initialize(); } return(boneList); }
public void TestPmxHeader() { using (var stream = File.OpenRead(Path.Combine(TestContext.CurrentContext.TestDirectory, "Mockups", "Model.pmx"))) { var model = new PmxModel(stream); Assert.AreEqual(2, model.Header.Version); Assert.IsNotNull(model.ModelInfo.CharacterName); Assert.IsNotNull(model.ModelInfo.UniversalCharacterName); Assert.IsNotNull(model.ModelInfo.Comment); Assert.IsNotNull(model.ModelInfo.UniversalComment); Assert.IsTrue(model.VertexData.Vertices.Length > 0); Assert.IsTrue(model.FaceData.Indices.All(i => i < model.VertexData.Vertices.Length)); } }
private void WritePmxModel([NotNull] PmxModel model) { var textureNames = BuildTextureNameMap(model); WriteString(model.Name); WriteString(model.NameEnglish); WriteString(model.Comment); WriteString(model.CommentEnglish); WriteVertexInfo(model); WriteFaceInfo(model); WriteTextureInfo(textureNames); WriteMaterialInfo(model, textureNames); WriteBoneInfo(model); WriteMorphInfo(model); WriteNodeInfo(model); WriteRigidBodyInfo(model); WriteJointInfo(model); WriteSoftBodyInfo(model); }
private void WriteSoftBodyInfo([NotNull] PmxModel model) { if (DetailedVersion < 2.1f) { return; } if (model.SoftBodies != null) { _writer.Write(model.SoftBodies.Length); foreach (var body in model.SoftBodies) { WritePmxSoftBody(body); } } else { _writer.Write(0); } }
public void InitializeContents([NotNull] PmxModel pmxModel, [NotNull] VmdMotion vmdMotion) { _pmxModel = pmxModel; _vmdMotion = vmdMotion; foreach (var boneFrame in vmdMotion.BoneFrames) { if (!_lastBoneFrames.ContainsKey(boneFrame.Name)) { _lastBoneFrames[boneFrame.Name] = boneFrame; } List <VmdBoneFrame> cachedBoneFrames; if (!_boneFrameCache.ContainsKey(boneFrame.Name)) { cachedBoneFrames = new List <VmdBoneFrame>(); _boneFrameCache[boneFrame.Name] = cachedBoneFrames; } else { cachedBoneFrames = _boneFrameCache[boneFrame.Name]; } cachedBoneFrames.Add(boneFrame); } _boneFrameNames = _lastBoneFrames.Keys.ToArray(); #if DEBUG Debug.Print("VMD bone list:"); foreach (var boneFrameName in _boneFrameNames) { Debug.Print(boneFrameName); } #endif }
private void WriteElementFormats([NotNull] PmxModel model) { byte[] elementSizes; byte elementSizeEntryCount; switch (MajorVersion) { case PmxFormatVersion.Version1: elementSizeEntryCount = 5; elementSizes = new byte[elementSizeEntryCount]; elementSizes[0] = (byte)VertexElementSize; elementSizes[1] = (byte)BoneElementSize; elementSizes[2] = (byte)MorphElementSize; elementSizes[3] = (byte)MaterialElementSize; elementSizes[4] = (byte)RigidBodyElementSize; break; case PmxFormatVersion.Version2: elementSizeEntryCount = 8; elementSizes = new byte[elementSizeEntryCount]; elementSizes[0] = (byte)StringEncoding; elementSizes[1] = (byte)model.UvaCount; elementSizes[2] = (byte)VertexElementSize; elementSizes[3] = (byte)TexElementSize; elementSizes[4] = (byte)MaterialElementSize; elementSizes[5] = (byte)BoneElementSize; elementSizes[6] = (byte)MorphElementSize; elementSizes[7] = (byte)RigidBodyElementSize; break; default: throw new ArgumentOutOfRangeException(); } _writer.Write(elementSizeEntryCount); _writer.Write(elementSizes); }
public static void RecalculateAllBoneInfo([NotNull] this PmxModel pmxModel) { for (var i = 0; i < pmxModel.Bones.Count; i++) { var bone = pmxModel.Bones[i]; bone.IsTransformCalculated = false; } for (var i = 0; i < pmxModel.Bones.Count; i++) { var bone = pmxModel.Bones[i]; // VMD controlled pose bone.SetToVmdPose(); // Binding pose //bone.SetToBindingPose(); } for (var i = 0; i < pmxModel.Bones.Count; i++) { var bone = pmxModel.Bones[i]; bone.UpdateSkinMatrix(); } }
public void InitializeContents([NotNull] PmxModel pmxModel, [NotNull] Camera camera, [NotNull] IReadOnlyDictionary <string, Texture2D> textureMap) { _pmxModel = pmxModel; _camera = camera; _textureMap = textureMap; var graphicsDevice = GraphicsDevice; var pmxMaterials = pmxModel.Materials; var faceTriangles = pmxModel.FaceTriangles; var pmxVertices = pmxModel.Vertices; #region Vertex buffer var vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, pmxVertices.Count, BufferUsage.WriteOnly); var vertices = new VertexPositionNormalTexture[pmxVertices.Count]; for (var i = 0; i < pmxVertices.Count; ++i) { var v = pmxVertices[i]; vertices[i] = new VertexPositionNormalTexture(v.Position, v.Normal, v.UV); } vertexBuffer.SetData(vertices); _vertices = vertices; _vertexBuffer = vertexBuffer; #endregion #region Index buffer var indexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.ThirtyTwoBits, faceTriangles.Count, BufferUsage.WriteOnly); var indices = new int[faceTriangles.Count]; for (var i = 0; i < faceTriangles.Count; ++i) { indices[i] = faceTriangles[i]; } indexBuffer.SetData(indices); _indices = indices; _indexBuffer = indexBuffer; #endregion var currentFaceStartIndex = 0; for (var index = 0; index < pmxMaterials.Count; index++) { var pmxMaterial = pmxMaterials[index]; var effect = new BasicEffect(graphicsDevice); // A white pixel texture is set with key = string.Empty. var textureKey = textureMap.ContainsKey(pmxMaterial.TextureFileName) ? pmxMaterial.TextureFileName : string.Empty; effect.AmbientLightColor = pmxMaterial.Ambient; effect.DiffuseColor = pmxMaterial.Diffuse.XYZ(); effect.Alpha = pmxMaterial.Diffuse.W; effect.SpecularColor = pmxMaterial.Specular; effect.SpecularPower = pmxMaterial.SpecularPower; effect.TextureEnabled = true; effect.Texture = textureMap[textureKey]; var meshPart = new MeshPart(); meshPart.Effect = effect; meshPart.VertexBuffer = vertexBuffer; meshPart.VertexStart = 0; meshPart.IndexBuffer = indexBuffer; meshPart.IndexStart = currentFaceStartIndex; meshPart.TriangleCount = pmxMaterial.AppliedFaceVertexCount / 3; _meshParts.Add(meshPart); currentFaceStartIndex += pmxMaterial.AppliedFaceVertexCount; } Debug.Assert(currentFaceStartIndex == pmxModel.FaceTriangles.Count, "currentFaceStartIndex == pmxModel.FaceTriangles.Count"); #if DEBUG Debug.Print("PMX bone list:"); foreach (var pmxBone in pmxModel.Bones) { Debug.Print(pmxBone.ToString()); } #endif }
private IReadOnlyList <VmdBoneFrame> CreateBoneFrames([NotNull] IBodyAnimationSource bodyMotionSource, [NotNull] PrettyAvatar avatar, [NotNull] PmxModel pmx) { var boneLookup = new BoneLookup(_conversionConfig); var mltdHierarchy = boneLookup.BuildBoneHierarchy(avatar); var pmxHierarchy = boneLookup.BuildBoneHierarchy(pmx); if (_conversionConfig.AppendIKBones || _conversionConfig.AppendEyeBones) { throw new NotSupportedException("Character motion frames generation (from MLTD) is not supported when appending bones (eyes and/or IK) is enabled."); } else { Debug.Assert(mltdHierarchy.Count == pmxHierarchy.Count, "Hierarchy number should be equal between MLTD and MMD."); } foreach (var mltdBone in mltdHierarchy) { mltdBone.Initialize(); } foreach (var pmxBone in pmxHierarchy) { pmxBone.Initialize(); } var animation = bodyMotionSource.Convert(); var boneCount = mltdHierarchy.Count; var animatedBoneCount = animation.BoneCount; var keyFrameCount = animation.KeyFrames.Count; { void MarkNamedBone(string name) { var bone = pmx.Bones.FirstOrDefault(b => b.Name == name); if (bone != null) { bone.IsMltdKeyBone = true; } else { Debug.Print("Warning: trying to mark bone {0} as MLTD key bone but the bone is missing from the model.", name); } } var names1 = animation.KeyFrames.Take(animatedBoneCount) .Select(kf => kf.Path).ToArray(); var names = names1.Select(boneLookup.GetVmdBoneNameFromBonePath).ToArray(); // Mark MLTD key bones. foreach (var name in names) { MarkNamedBone(name); } // Special cases MarkNamedBone("KUBI"); MarkNamedBone("頭"); } Debug.Assert(keyFrameCount % animatedBoneCount == 0, "keyFrameCount % animatedBoneCount == 0"); var iterationTimes = keyFrameCount / animatedBoneCount; var boneFrameList = new List <VmdBoneFrame>(); // Reduce memory pressure of allocating new delegates (see mltdHierarchy.FirstOrDefault(...)) var boneMatchPredicateCache = new Func <PmxBone, bool> [boneCount]; for (var j = 0; j < boneCount; j += 1) { var refBone = pmx.Bones[j]; boneMatchPredicateCache[j] = bone => bone.Name == refBone.Name; } // Cache `mltdBoneName`s so we don't have to compute them all in every iteration var boneNameCache = new Dictionary <string, string>(); // OK, now perform iterations for (var i = 0; i < iterationTimes; ++i) { if (_conversionConfig.Transform60FpsTo30Fps) { if (i % 2 == 1) { continue; } } var keyFrameIndexStart = i * animatedBoneCount; for (var j = 0; j < animatedBoneCount; ++j) { var keyFrame = animation.KeyFrames[keyFrameIndexStart + j]; string mltdBoneName; if (boneNameCache.ContainsKey(keyFrame.Path)) { mltdBoneName = boneNameCache[keyFrame.Path]; } else { if (keyFrame.Path.Contains("BODY_SCALE/")) { mltdBoneName = keyFrame.Path.Replace("BODY_SCALE/", string.Empty); } else { mltdBoneName = keyFrame.Path; } boneNameCache.Add(keyFrame.Path, mltdBoneName); } var targetBone = mltdHierarchy.SingleOrDefault(bone => bone.Name == mltdBoneName); if (targetBone == null) { //throw new ArgumentException("Bone not found."); continue; // Shika doesn't have the "POSITION" bone. } BoneNode transferredBone = null; foreach (var kv in BoneAttachmentMap) { if (kv.Key == mltdBoneName) { transferredBone = mltdHierarchy.SingleOrDefault(bone => bone.Name == kv.Value); if (transferredBone == null) { throw new ArgumentException(); } break; } } if (keyFrame.HasPositions) { // ReSharper disable once PossibleInvalidOperationException var x = keyFrame.PositionX.Value; // ReSharper disable once PossibleInvalidOperationException var y = keyFrame.PositionY.Value; // ReSharper disable once PossibleInvalidOperationException var z = keyFrame.PositionZ.Value; var t = new Vector3(x, y, z); t = t.FixUnityToOpenTK(); if (_conversionConfig.ScaleToVmdSize) { t = t * _scalingConfig.ScaleUnityToPmx; } targetBone.LocalPosition = t; //if (transferredBone != null) { // transferredBone.LocalPosition = t; //} } if (keyFrame.HasRotations) { // ReSharper disable once PossibleInvalidOperationException var x = keyFrame.AngleX.Value; // ReSharper disable once PossibleInvalidOperationException var y = keyFrame.AngleY.Value; // ReSharper disable once PossibleInvalidOperationException var z = keyFrame.AngleZ.Value; var q = UnityRotation.EulerDeg(x, y, z); q = q.FixUnityToOpenTK(); targetBone.LocalRotation = q; if (transferredBone != null) { transferredBone.LocalRotation = q; } } } foreach (var mltdBone in mltdHierarchy) { mltdBone.UpdateTransform(); } for (var j = 0; j < boneCount; ++j) { var pmxBone = pmxHierarchy[j]; var mltdBone = mltdHierarchy[j]; { var predicate = boneMatchPredicateCache[j]; var pb = pmx.Bones.FirstOrDefault(predicate); #if DEBUG if (pb == null) { // Lazy evaluation of the assertion message Debug.Assert(pb != null, $"PMX bone with the name \"{pmxBone.Name}\" should exist."); } #endif if (!pb.IsMltdKeyBone) { continue; } } var skinMatrix = mltdBone.SkinMatrix; var mPmxBindingPose = pmxBone.BindingPose; var mWorld = pmxBone.Parent?.WorldMatrix ?? Matrix4.Identity; // skinMatrix == inv(mPmxBindingPose) x mLocal x mWorld var mLocal = mPmxBindingPose * skinMatrix * mWorld.Inverted(); // Here, translation is in... world coords? WTF? var t = mLocal.ExtractTranslation(); var q = mLocal.ExtractRotation(); if (pmxBone.Parent != null) { t = t - (pmxBone.InitialPosition - pmxBone.Parent.InitialPosition); } int frameIndex; if (_conversionConfig.Transform60FpsTo30Fps) { frameIndex = i / 2; } else { frameIndex = i; } var vmdBoneName = boneLookup.GetVmdBoneNameFromBoneName(mltdBone.Path); var boneFrame = new VmdBoneFrame(frameIndex, vmdBoneName); boneFrame.Position = t; boneFrame.Rotation = q; boneFrameList.Add(boneFrame); pmxBone.LocalPosition = t; pmxBone.LocalRotation = q; pmxBone.UpdateTransform(); } } return(boneFrameList); }
/// <summary> /// pmxモデルを追加 /// </summary> public void Load(meshio.Pmx.Model pmx) { var model=new PmxModel(pmx); _drawables.Add(model); _resourceManager.Add(model); }
private PmxModel ReadPmxModel() { var model = new PmxModel(); model.Name = ReadString() ?? string.Empty; model.NameEnglish = ReadString() ?? string.Empty; model.Comment = ReadString() ?? string.Empty; model.CommentEnglish = ReadString() ?? string.Empty; ReadVertexInfo(); ReadFaceInfo(); ReadTextureInfo(); ReadMaterialInfo(); ReadBoneInfo(); ReadMorphInfo(); ReadNodeInfo(); ReadRigidBodyInfo(); ReadJointInfo(); ReadSoftBodyInfo(); return(model); void ReadVertexInfo() { var vertexCount = _reader.ReadInt32(); var vertices = new PmxVertex[vertexCount]; for (var i = 0; i < vertexCount; ++i) { vertices[i] = ReadPmxVertex(); } model.Vertices = vertices; } void ReadFaceInfo() { var faceCount = _reader.ReadInt32(); var faceIndices = new int[faceCount]; for (var i = 0; i < faceCount; ++i) { faceIndices[i] = _reader.ReadVarLenIntAsInt32(VertexElementSize, true); } model.FaceTriangles = faceIndices; } void ReadTextureInfo() { var textureCount = _reader.ReadInt32(); var textureNameMap = new Dictionary <int, string>(); var textureIndexLookup = new Dictionary <string, int>(); for (var i = 0; i < textureCount; ++i) { var textureName = ReadString() ?? string.Empty; textureNameMap[i] = textureName; textureIndexLookup[textureName] = i; } textureNameMap[-1] = string.Empty; TextureNameMap = textureNameMap; TextureIndexLookup = textureIndexLookup; } void ReadMaterialInfo() { var materialCount = _reader.ReadInt32(); var materials = new PmxMaterial[materialCount]; for (var i = 0; i < materialCount; ++i) { materials[i] = ReadPmxMaterial(); } model.Materials = materials; } void ReadBoneInfo() { var boneCount = _reader.ReadInt32(); var bones = new PmxBone[boneCount]; for (var i = 0; i < boneCount; ++i) { bones[i] = ReadPmxBone(); bones[i].BoneIndex = i; } model.Bones = bones; model.BonesDictionary = bones.ToDictionary(bone => bone.Name); var rootBoneIndexList = new List <int>(); for (var i = 0; i < bones.Length; ++i) { var bone = bones[i]; if (bone.ParentIndex < 0) { rootBoneIndexList.Add(i); } else { bone.Parent = bones[bone.ParentIndex]; } if (bone.AppendParentIndex >= 0) { bone.AppendParent = bones[bone.AppendParentIndex]; } if (bone.ExternalParentIndex >= 0) { bone.ExternalParent = bones[bone.ExternalParentIndex]; } if (bone.HasFlag(BoneFlags.IK)) { var ik = bone.IK; Debug.Assert(ik != null, nameof(ik) + " != null"); ik.TargetBone = bones[ik.TargetBoneIndex]; foreach (var link in ik.Links) { if (link.BoneIndex >= 0) { link.Bone = bones[link.BoneIndex]; } } } } model.RootBoneIndices = rootBoneIndexList.ToArray(); foreach (var bone in bones) { bone.SetToBindingPose(); } } void ReadMorphInfo() { var morphCount = _reader.ReadInt32(); var morphs = new PmxMorph[morphCount]; for (var i = 0; i < morphCount; ++i) { morphs[i] = ReadPmxMorph(); } model.Morphs = morphs; } void ReadNodeInfo() { var nodeCount = _reader.ReadInt32(); var nodes = new PmxNode[nodeCount]; for (var i = 0; i < nodeCount; ++i) { var node = ReadPmxNode(); nodes[i] = node; if (node.IsSystemNode) { if (node.Name == "Root") { model.RootNodeIndex = i; } else if (node.Name == "表情") { model.FacialExpressionNodeIndex = i; } } } model.Nodes = nodes; } void ReadRigidBodyInfo() { var bodyCount = _reader.ReadInt32(); var bodies = new PmxRigidBody[bodyCount]; for (var i = 0; i < bodyCount; ++i) { bodies[i] = ReadPmxRigidBody(); } model.RigidBodies = bodies; } void ReadJointInfo() { var jointCount = _reader.ReadInt32(); var joints = new PmxJoint[jointCount]; for (var i = 0; i < jointCount; ++i) { joints[i] = ReadPmxJoint(); } model.Joints = joints; } void ReadSoftBodyInfo() { if (DetailedVersion < 2.1f) { return; } var bodyCount = _reader.ReadInt32(); var bodies = new PmxSoftBody[bodyCount]; for (var i = 0; i < bodyCount; ++i) { bodies[i] = ReadPmxSoftBody(); } model.SoftBodies = bodies; } }