private void _LoadBone(BlendTypeRepository repository, BlendValueCapsule bone, int parentBoneIndex, ref List <DrawSystem.BoneData> outList) { if (bone != null) { // make bone data var name = bone.GetMember("name").GetAllValueAsString(); float length = bone.GetMember("length").GetRawValue <float>(); var offset = new Vector3() { X = bone.GetMember("head").GetAt(0).GetRawValue <float>(), Y = bone.GetMember("head").GetAt(1).GetRawValue <float>(), Z = bone.GetMember("head").GetAt(2).GetRawValue <float>(), }; offset = BlenderUtil.ChangeCoordsSystem(offset); var elements = new float[16]; for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { elements[i * 4 + j] = bone.GetMember("arm_mat").GetAt(i, j).GetRawValue <float>(); } } var modelTrans = new Matrix(elements); modelTrans = BlenderUtil.ChangeCoordsSystem(modelTrans); var result = new DrawSystem.BoneData() { Name = name, Parent = parentBoneIndex, BoneTransform = modelTrans, // convert local bone transformation after BoneOffset = Matrix.Invert(modelTrans), Length = length, }; outList.Add(result); parentBoneIndex = outList.Count() - 1; //Console.WriteLine(" found bone : " + name); // call for children var childBone = bone.GetMember("childbase").GetMember("first").GetRawValue <BlendAddress>().DereferenceOne(); while (childBone != null) { _LoadBone(repository, childBone, parentBoneIndex, ref outList); childBone = childBone.GetMember("next").GetRawValue <BlendAddress>().DereferenceOne(); } } }
private bool _LoadArmature(BlendTypeRepository repository, BlendValueCapsule meshObj, out DrawSystem.BoneData[] outBoneArray, out int[] outDeformGroupIndex2BoneIndex, out AnimType.AnimationData outAnimData) { BlendValueCapsule bArmature = null; BlendValueCapsule bAnimData = null; // find blend value { var mod = meshObj.GetMember("modifiers").GetMember("first").GetRawValue <BlendAddress>().DereferenceOne(); while (mod != null) { if (mod.Type.Equals(repository.Find("ArmatureModifierData"))) { // animation modifier var armatureObj = mod.GetMember("object").GetRawValue <BlendAddress>().DereferenceOne(); if (armatureObj != null) { bArmature = armatureObj.GetMember("data").GetRawValue <BlendAddress>().DereferenceOne(); bAnimData = armatureObj.GetMember("adt").GetRawValue <BlendAddress>().DereferenceOne(); break; } } mod = mod.GetMember("modifier").GetMember("next").GetRawValue <BlendAddress>().DereferenceOne(); } } // build boneList from armature var boneList = new List <DrawSystem.BoneData>(); if (bArmature != null) { var firstBone = bArmature.GetMember("bonebase").GetMember("first").GetRawValue <BlendAddress>().DereferenceOne(); var tmpBoneList = new List <DrawSystem.BoneData>(); _LoadBone(repository, firstBone, -1, ref tmpBoneList); // compute local bone matrix for (int boneIndex = 0; boneIndex < tmpBoneList.Count(); ++boneIndex) { var tmp = tmpBoneList[boneIndex]; if (!tmp.IsMasterBone()) { tmp.BoneTransform = tmp.BoneTransform * Matrix.Invert(tmpBoneList[tmp.Parent].BoneTransform); } boneList.Add(tmp); } } // build anime data from animAction var animActionList = new List <AnimType.ActionData>(); if (bAnimData != null) { var bAnimAction = bAnimData.GetMember("action").GetRawValue <BlendAddress>().DereferenceOne(); // seek the top of action while (bAnimAction != null) { var bTmpAnimAction = bAnimAction.GetMember("id").GetMember("prev").GetRawValue <BlendAddress>().DereferenceOne(); if (bTmpAnimAction == null) { break; } bAnimAction = bTmpAnimAction; } // load action while (bAnimAction != null) { _LoadAction(repository, bAnimAction, ref animActionList); bAnimAction = bAnimAction.GetMember("id").GetMember("next").GetRawValue <BlendAddress>().DereferenceOne(); } } var deformGroupNameList = new List <string>(); var deformGroup = meshObj.GetMember("defbase").GetMember("first").GetRawValue <BlendAddress>().DereferenceOne(); while (deformGroup != null) { var groupName = deformGroup.GetMember("name").GetAllValueAsString(); //Console.WriteLine(" found deform group : " + groupName); deformGroupNameList.Add(groupName); deformGroup = deformGroup.GetMember("next").GetRawValue <BlendAddress>().DereferenceOne(); } if (deformGroupNameList.Count != 0 && boneList.Count != 0) { // sort boneArray by deform group outDeformGroupIndex2BoneIndex = new int[boneList.Count()]; int nextIndex = 0; foreach (var defName in deformGroupNameList) { var bone = boneList.Select((n, index) => new { n, index }).FirstOrDefault(ni => ni.n.Name == defName); if (bone != null) { outDeformGroupIndex2BoneIndex[nextIndex] = bone.index; } nextIndex++; } outBoneArray = boneList.ToArray(); if (animActionList.Count == 0) { outAnimData = new AnimType.AnimationData(); } else { outAnimData = new AnimType.AnimationData(); outAnimData.Actions = animActionList.ToArray(); } return(true); } else { outDeformGroupIndex2BoneIndex = new int[0]; outBoneArray = new DrawSystem.BoneData[0]; outAnimData = new AnimType.AnimationData(); return(false); } }