private bool _LoadMesh(BlendTypeRepository repository, BlendValueCapsule meshObj) { var mesh = meshObj.GetMember("data").GetRawValue <BlendAddress>().DereferenceOne(); string meshName = meshObj.GetMember("id").GetMember("name").GetAllValueAsString(); int mtlCount = meshObj.GetMember("totcol").GetRawValue <int>(); // Build Armature DrawSystem.BoneData[] boneArray = null; int[] deformGroupIndex2BoneIndex = null; AnimType.AnimationData animData; if (!_LoadArmature(repository, meshObj, out boneArray, out deformGroupIndex2BoneIndex, out animData)) { // igrnore } // Build original vertices var originVertices = _CreateOriginalVertices(repository, mesh, deformGroupIndex2BoneIndex); // Build materials var pmtlType = new BlendPointerType(repository.Find("Material")); var mtls = mesh.GetMember("mat").GetRawValue <BlendAddress>().DereferenceAll(pmtlType); Debug.Assert(mtls.Count == mtlCount, "material count is unmatched"); for (int mtlIndex = 0; mtlIndex < mtlCount; ++mtlIndex) { // Build a vertex buffer(s) var vertices = originVertices .Where(v => v.MaterialIndex == mtlIndex) .ToArray(); var bMaterial = mtls[mtlIndex].GetRawValue <BlendAddress>().DereferenceOne(); if (bMaterial != null) { Dictionary <DrawSystem.TextureTypes, TextureInfo> textureInfos = null; MaterialBase material; if (!_LoadMaterial(repository, bMaterial, out textureInfos, out material)) { continue; } var node = new SceneNode() { Name = meshName, Vertics = vertices, MaterialData = material, TextureInfos = textureInfos, BoneArray = mtlIndex == 0 ? boneArray : null, // set boneArray for the first node Animation = animData.Actions != null ? (AnimType.AnimationData?)animData : null, }; m_nodeList.Add(node); } } return(m_nodeList.Count != 0); }
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); } }