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); }