private void InitSkinInfo(AiMesh mesh, AssimpSceneContainer container) { var boneIDs = new uvec4[mesh.Vertexes.Length]; var boneWeights = new vec4[mesh.Vertexes.Length]; AllBoneInfos allBones = container.GetAllBoneInfos(); Dictionary <string, uint> nameIndexDict = allBones.nameIndexDict; for (int i = 0; i < mesh.BoneCount; i++) { AiBone bone = mesh.Bones[i]; // bones that influence this mesh. uint boneIndex = nameIndexDict[bone.Name]; for (int j = 0; j < bone.VertexWeightCount; j++) { AiVertexWeight vertexWeight = bone.VertexWeights[j]; uint vertexID = vertexWeight.VertexID; for (int t = 0; t < 4; t++) { if (boneWeights[vertexID][t] == 0.0f) // fill in x y z w. { boneIDs[vertexID][t] = boneIndex; boneWeights[vertexID][t] = vertexWeight.Weight; break; } } } } this.boneIDs = boneIDs; this.boneWeights = boneWeights; }
public AllBoneInfos GetAllBoneInfos() { if (this.allBoneInfos == null) { this.allBoneInfos = InitBonesInfo(aiScene); } return(this.allBoneInfos); }
private static void ReadNodeHeirarchy(float animationTime, AiNode node, AiAnimation animation, mat4 parentTransform, AllBoneInfos allBoneInfos) { string nodeName = node.Name; mat4 nodeTransform = node.Transform.ToMat4(); AiNodeAnimationChannel nodeAnim = FineNodeAnim(animation, nodeName); if (nodeAnim != null) { mat4 mat = mat4.identity(); // Interpolate scaling and generate scaling transformation matrix vec3 scaling = CalcInterpolatedScaling(animationTime, nodeAnim); mat4 scalingMat = glm.scale(mat, new vec3(scaling.X, scaling.Y, scaling.Z)); // Interpolate rotation and generate rotation transformation matrix Quaternion rotation = CalcInterpolatedRotation(animationTime, nodeAnim); mat4 rotationMat = new AiMatrix4x4(rotation.GetMatrix()).ToMat4(); // Interpolate translation and generate translation transformation matrix vec3 translation = CalcInterpolatedPosition(animationTime, nodeAnim); mat4 translationMat = glm.translate(mat4.identity(), new vec3(translation.X, translation.Y, translation.Z)); // Combine the above transformations nodeTransform = translationMat * rotationMat * scalingMat; } mat4 globalTransformation = parentTransform * nodeTransform; if (allBoneInfos.nameIndexDict.ContainsKey(nodeName)) { uint BoneIndex = allBoneInfos.nameIndexDict[nodeName]; allBoneInfos.boneInfos[BoneIndex].finalTransformation = globalTransformation * allBoneInfos.boneInfos[BoneIndex].bone.OffsetMatrix.ToMat4(); } for (int i = 0; i < node.ChildCount; i++) { ReadNodeHeirarchy(animationTime, node.Children[i], animation, globalTransformation, allBoneInfos); } }
/// <summary> /// /// </summary> /// <param name="aiScene"></param> /// <param name="TimeInSeconds"></param> /// <returns></returns> public static mat4[] GetBoneMatrixes(this AiScene aiScene, float TimeInSeconds, AllBoneInfos allBones) { if (!aiScene.HasAnimations) { return(null); } double ticksPerSecond = aiScene.Animations[0].TicksPerSecond; if (ticksPerSecond == 0) { ticksPerSecond = 25.0; } double timeInTicks = TimeInSeconds * ticksPerSecond; float animationTime = (float)(timeInTicks % aiScene.Animations[0].DurationInTicks); AiMatrix4x4 transform = aiScene.RootNode.Transform; transform.Inverse(); ReadNodeHeirarchy(animationTime, aiScene.RootNode, aiScene.Animations[0], transform.ToMat4(), allBones); int boneCount = allBones.boneInfos.Length; var result = new mat4[boneCount]; for (int i = 0; i < boneCount; i++) { result[i] = allBones.boneInfos[i].finalTransformation; } return(result); }