private void WritePmxBone([NotNull] PmxBone bone) { WriteString(bone.Name); WriteString(bone.NameEnglish); _writer.Write(bone.InitialPosition); _writer.WriteInt32AsVarLenInt(bone.ParentIndex, BoneElementSize); _writer.Write(bone.Level); _writer.Write((ushort)bone.Flags); if (bone.HasFlag(BoneFlags.ToBone)) { _writer.WriteInt32AsVarLenInt(bone.To_Bone, BoneElementSize); } else { _writer.Write(bone.To_Offset); } if (bone.HasFlag(BoneFlags.AppendRotation) || bone.HasFlag(BoneFlags.AppendTranslation)) { _writer.WriteInt32AsVarLenInt(bone.AppendParentIndex, BoneElementSize); _writer.Write(bone.AppendRatio); } if (bone.HasFlag(BoneFlags.FixedAxis)) { _writer.Write(bone.Axis); } if (bone.HasFlag(BoneFlags.LocalFrame)) { var rotation = bone.InitialRotation; var mat = Matrix4.CreateFromQuaternion(rotation); var localX = mat.Row0.Xyz; var localZ = mat.Row2.Xyz; localX.Normalize(); localZ.Normalize(); _writer.Write(localX); _writer.Write(localZ); } if (bone.HasFlag(BoneFlags.ExternalParent)) { _writer.Write(bone.ExternalParentIndex); } if (bone.HasFlag(BoneFlags.IK) && bone.IK != null) { WritePmxIK(bone.IK); } }
private PmxBone ReadPmxBone() { var bone = new PmxBone(); bone.Name = ReadString() ?? string.Empty; bone.NameEnglish = ReadString() ?? string.Empty; bone.InitialPosition = _reader.ReadVector3(); bone.CurrentPosition = bone.InitialPosition; bone.ParentIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize); bone.Level = _reader.ReadInt32(); bone.Flags = (BoneFlags)_reader.ReadUInt16(); if (bone.HasFlag(BoneFlags.ToBone)) { bone.To_Bone = _reader.ReadVarLenIntAsInt32(BoneElementSize); } else { bone.To_Offset = _reader.ReadVector3(); } if (bone.HasFlag(BoneFlags.AppendRotation) || bone.HasFlag(BoneFlags.AppendTranslation)) { bone.AppendParentIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize); bone.AppendRatio = _reader.ReadSingle(); } if (bone.HasFlag(BoneFlags.FixedAxis)) { bone.Axis = _reader.ReadVector3(); } if (bone.HasFlag(BoneFlags.LocalFrame)) { var localX = _reader.ReadVector3(); var localZ = _reader.ReadVector3(); localX.Normalize(); localZ.Normalize(); var localY = Vector3.Cross(localZ, localX); localZ = Vector3.Cross(localX, localY); localY.Normalize(); localZ.Normalize(); bone.SetInitialRotationFromRotationAxes(localX, localY, localZ); } else { bone.InitialRotation = Quaternion.Identity; bone.CurrentRotation = Quaternion.Identity; } if (bone.HasFlag(BoneFlags.ExternalParent)) { bone.ExternalParentIndex = _reader.ReadInt32(); } if (bone.HasFlag(BoneFlags.IK)) { bone.IK = ReadPmxIK(); } return(bone); }