public bool Initialize(BoneTransform[] arr, int id) { if (!arr[id].IsIK) return false; IK = arr[id]; BoneIK iK = IK.Bone.IKData; IKLinksBones = new BoneTransform[iK.Links.Length]; _fixAxis = new bool[iK.Links.Length]; IKLinks = new IKLink[iK.Links.Length]; ContainLimit = false; for (int i = 0; i < iK.Links.Length; i++) { if (arr.Length > iK.Links[i].Bone && arr.Length >= 0) { IKLinks[i] = iK.Links[i]; IKLinksBones[i] = arr[iK.Links[i].Bone]; IKLinksBones[i].IsIKLink = true; if (IKLinks[i].IsLimit) { ContainLimit = true; IKLinks[i].NormalizeAngle(); IKLinks[i].NormalizeEulerAxis(); if (IKLinks[i].FixAxis == IKLink.FixAxisType.Fix) _fixAxis[i] = true; } } } LimitOnce = iK.AngleLimit; LoopCount = Math.Min(iK.LoopCount, 256); if (arr.Length > iK.Target && iK.Target >=0) { Target = arr[iK.Target]; IK.IsIK = true; IsEnable = true; return true; } Target = null; return false; }
void ReadBones(Reader reader) { int bonesCount = reader.ReadInt32(); var bones = new Bone[bonesCount]; int maxLevel = 0; for (int i = 0; i < bonesCount; i++) { string name = reader.readString(); string nameEng = reader.readString(); Vector3 Position = reader.readVector3() * multipler; int parentIndex = 0; if (header.GetBoneIndexSize == 2) { parentIndex = unchecked ((short)reader.readVal(header.GetBoneIndexSize)); } else { parentIndex = reader.readVal(header.GetBoneIndexSize); } int Level = reader.ReadInt32(); byte[] flags = reader.ReadBytes(2); Bone bone = new Bone(name, nameEng, Position, parentIndex, flags); bone.Level = Level; if (bone.tail) { reader.readVal(header.GetBoneIndexSize); } else { reader.readVector3(); } if (bone.InheritRotation || bone.InheritTranslation) { bone.ParentInheritIndex = reader.readVal(header.GetBoneIndexSize); bone.ParentInfluence = reader.ReadSingle(); } bone.Parent2Local = Matrix4.Identity; //probably cant be both true if (bone.FixedAxis) { Vector3 X = reader.readVector3(); Vector3 Z = Vector3.Cross(X, new Vector3(0f, 1f, 0f)); Vector3 Y = Vector3.Cross(Z, X); Matrix3 local = new Matrix3(X, Y, Z); local.Normalize(); bone.Parent2Local = new Matrix4(local); } if (bone.LocalCoordinate) { Vector3 X = reader.readVector3(); Vector3 Z = reader.readVector3(); Vector3 Y = Vector3.Cross(Z, X); Matrix3 local = new Matrix3(X, Y, Z); local.Normalize(); bone.Parent2Local = new Matrix4(local); } if (bone.ExternalPdeform) { reader.ReadInt32(); } if (bone.IK) { BoneIK ikBone = new BoneIK(); ikBone.Target = reader.readVal(header.GetBoneIndexSize); ikBone.LoopCount = reader.ReadInt32(); ikBone.AngleLimit = reader.ReadSingle(); int count = reader.ReadInt32(); IKLink[] links = new IKLink[count]; for (int n = 0; n < count; n++) { IKLink link = new IKLink(); link.Bone = reader.readVal(header.GetBoneIndexSize); if (reader.ReadByte() == 1) { link.IsLimit = true; link.LimitMin = -reader.readVector3(); link.LimitMax = -reader.readVector3(); } links[n] = link; } ikBone.Links = links; bone.IKData = ikBone; } if (maxLevel < bone.Level) { maxLevel = bone.Level; } bones[i] = bone; } var reverce = Matrix4.CreateScale(new Vector3(1, 1, -1)); //convert position from model to parent bone for (int i = bones.Length - 1; i > -1; i--) { Bone bone = bones[i]; if (bone.ParentIndex >= 0 && bone.ParentIndex < bones.Length) { bone.Parent2Local = Matrix4.CreateTranslation(bone.Position - bones[bone.ParentIndex].Position); } //Convert left to right coordinates bone.Parent2Local = reverce * bone.Parent2Local * reverce; } boneOrder = new int[bones.Length]; int m = 0; for (int n = 0; n <= maxLevel; n++) { for (int i = 0; i < bones.Length; i++) { if (bones[i].Level == n) { boneOrder[m] = i; m++; } } } boneController = new BoneController(bones, boneOrder); }
void ReadBones(Reader reader) { int bonesCount = reader.ReadUInt16(); bones = new Bone[bonesCount]; var boneTypes = new BoneType[bonesCount]; var temp = new int[bonesCount, 2]; int maxLevel = 0; for (int i = 0; i < bonesCount; i++) { string name = reader.readStringLength(20); int parent = reader.ReadInt16(); int to = reader.ReadInt16(); boneTypes[i] = (BoneType)reader.ReadByte(); int ikNum = reader.ReadInt16(); var position = reader.readVector3() * multipler; Bone bone = new Bone(name, "", position, parent, new byte[16]); bone.tail = true; temp[i, 0] = to; temp[i, 1] = ikNum; bones[i] = bone; } int ikCount = reader.ReadUInt16(); for (int i = 0; i < ikCount; i++) { int bone = reader.ReadUInt16(); BoneIK boneIK = new BoneIK(); boneIK.Target = reader.ReadUInt16(); int linkCount = reader.ReadByte(); boneIK.LoopCount = reader.ReadUInt16(); boneIK.AngleLimit = reader.ReadSingle(); boneIK.Links = new IKLink[linkCount]; for (int n = 0; n < linkCount; n++) { boneIK.Links[n] = new IKLink(); boneIK.Links[n].Bone = reader.ReadUInt16(); //was hardcoded in original if (bones[boneIK.Links[n].Bone].Name == "左ひざ" || bones[boneIK.Links[n].Bone].Name == "右ひざ") { boneIK.Links[n].IsLimit = true; boneIK.Links[n].LimitMin = new Vector3(-(float)Math.PI, 0, 0); boneIK.Links[n].LimitMax = new Vector3(-(float)Math.PI / 180 * 5, 0, 0); } } bones[bone].IKData = boneIK; bones[bone].IK = true; bones[bone].Translatable = true; bones[bone].Level = 1; } for (int i = 0; i < bonesCount; i++) { bones[i].Rotatable = true; bones[i].IsVisible = true; bones[i].Enabled = true; switch (boneTypes[i]) { case BoneType.RotateMove: bones[i].Translatable = true; break; case BoneType.IK: bones[i].IK = true; break; case BoneType.RotateEffect: bones[i].InheritRotation = true; bones[i].ParentInfluence = 1f; bones[i].Level = 2; bones[0].ParentInheritIndex = temp[i, 1]; break; case BoneType.IKTo: bones[i].IsVisible = false; break; case BoneType.Unvisible: bones[i].IsVisible = false; break; case BoneType.Twist: bones[i].FixedAxis = true; break; case BoneType.RotateRatio: bones[i].InheritRotation = true; bones[i].tail = false; bones[i].IsVisible = false; bones[0].ParentInheritIndex = temp[i, 0]; bones[0].ParentInfluence = (float)temp[i, 1] * 0.01f; break; } if (maxLevel < bones[i].Level) { maxLevel = bones[i].Level; } } //convert position from model to parent bone for (int i = bones.Length - 1; i > -1; i--) { Bone bone = bones[i]; if (bone.ParentIndex >= 0 && bone.ParentIndex < bones.Length) { bone.Parent2Local = Matrix4.CreateTranslation(bone.Position - bones[bone.ParentIndex].Position); //Console.WriteLine("{0} {1}", i, bone.Position - bones[bone.ParentIndex].Position); } } boneOrder = new int[bones.Length]; int m = 0; for (int n = 0; n <= maxLevel; n++) { for (int i = 0; i < bones.Length; i++) { if (bones[i].Level == n) { boneOrder[m] = i; m++; } } } }