public void updateSkeleton( ) { smd_animation p_anim = anim[cur_anim]; if (p_anim == null) { return; } float currentFrameF = currentTime * p_anim.frameRate; float resto = currentFrameF - MathF.Floor(currentFrameF); int frame1 = (int)MathF.Floor(currentFrameF); int frame2 = frame1 + 1; p_anim.finished = false; if (p_anim.loop) { frame1 = frame1 % p_anim.cant_frames; frame2 = frame2 % p_anim.cant_frames; } else { if (frame1 > p_anim.cant_frames - 1) { frame1 = p_anim.cant_frames - 1; p_anim.finished = true; } if (frame2 > p_anim.cant_frames - 1) { frame2 = p_anim.cant_frames - 1; } } for (int i = 0; i < cant_bones; ++i) { smd_bone_anim p_bone_anim1 = p_anim.frames[frame1].bone_animations[i]; smd_bone_anim p_bone_anim2 = p_anim.frames[frame2].bone_animations[i]; Vector3 Position = i == 0 && p_anim.in_site ? p_anim.frames[0].bone_animations[0].Position : p_bone_anim1.Position * (1 - resto) + p_bone_anim2.Position * resto; Quaternion q1 = toQuaternion(p_bone_anim1.Rotation); Quaternion q2 = toQuaternion(p_bone_anim2.Rotation); Quaternion q = Quaternion.Lerp(q1, q2, resto); Matrix T = traslation(Position) * toMatrix(q); int k = bones[i].parent; if (k != -1) { T = bones[k].Transform * T; } bones[i].Transform = T; bones[i].Position = transform(Vector3.Zero, T); } }
public void cargar_ani(String ani_folder, String ani_name) { smd_animation p_anim = anim[cur_anim = cant_animations++] = new smd_animation(); p_anim.name = ani_name; p_anim.cant_frames = 0; var fp = new System.IO.StreamReader(folder + ani_folder + "\\" + ani_name + ".smd"); fp.ReadLine().TrimStart(); // version 1 fp.ReadLine().TrimStart(); // nodes var buffer = fp.ReadLine().TrimStart(); while (!buffer.StartsWith("skeleton")) { buffer = fp.ReadLine().TrimStart(); } fp.ReadLine().TrimStart(); // time 0 smd_frame frame = p_anim.frames[p_anim.cant_frames++] = new smd_frame(); buffer = fp.ReadLine().TrimStart(); // primer item while (!buffer.StartsWith("end")) { string[] tokens = buffer.Split(' '); int id = int.Parse(tokens[0]); if (id >= 0 && id < cant_bones) { smd_bone_anim bone_anim = frame.bone_animations[id] = new smd_bone_anim(); bone_anim.Position.X = atof(tokens[1]); bone_anim.Position.Y = atof(tokens[2]); bone_anim.Position.Z = atof(tokens[3]); bone_anim.Rotation.X = atof(tokens[4]); bone_anim.Rotation.Y = atof(tokens[5]); bone_anim.Rotation.Z = atof(tokens[6]); } buffer = fp.ReadLine().TrimStart(); if (buffer.StartsWith("time")) { // creo el nuevo frame frame = p_anim.frames[p_anim.cant_frames++] = new smd_frame(); buffer = fp.ReadLine().TrimStart(); } } // completo los frames que faltan (si fue creado con el crawbar no faltara ninguno) // para ello hereda los frame anterior // de paso computo la distancia total para aprximar la velocidad float dm = 0; for (var f = 0; f < p_anim.cant_frames; ++f) { for (var i = 0; i < cant_bones; ++i) { if (p_anim.frames[f].bone_animations[i] == null) { smd_bone_anim bone_anim = p_anim.frames[f].bone_animations[i] = new smd_bone_anim(); if (f > 0) { // heredo del anterior bone_anim.Position = p_anim.frames[f - 1].bone_animations[i].Position; bone_anim.Rotation = p_anim.frames[f - 1].bone_animations[i].Rotation; } else { // cero x defecto bone_anim.Position = Vector3.Zero; bone_anim.Rotation = Vector3.Zero; } } } float dist = (p_anim.frames[0].bone_animations[0].Position - p_anim.frames[f].bone_animations[0].Position).Length(); if (dist > dm) { dm = dist; } } float time = p_anim.cant_frames / p_anim.frameRate; speed = dm / time; fp.Close(); }