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 setAnimation(int n) { if (n >= 0 && n < cant_animations) { cur_anim = n; smd_animation p_anim = anim[cur_anim]; if (p_anim == null) { return; } updateSkeleton(); } }
public void Draw(GraphicsDevice graphicsDevice, Effect Effect, Matrix World, Matrix View, Matrix Proj, int L = 0) { graphicsDevice.SetVertexBuffer(VertexBuffer); Effect.Parameters["World"].SetValue(World); Effect.Parameters["View"].SetValue(View); Effect.Parameters["Projection"].SetValue(Proj); smd_animation p_anim = anim[cur_anim]; if (p_anim != null) { // modelo animado updateMeshVertices(); Effect.Parameters["bonesMatWorldArray"].SetValue(matBoneSpace); } var AlphaTestReference = Effect.Parameters["AlphaTestReference"]; // L ==0 opacos , ==1 traslucidos for (var i = 0; i < cant_subsets; i++) { var cant_items = subset[i].cant_items; if (cant_items > 0 && subset[i].traslucido == (L == 1)) { var pos = subset[i].pos; if (texture[i] != null) { Effect.Parameters["ModelTexture"].SetValue(texture[i]); } if (AlphaTestReference != null) { AlphaTestReference.SetValue(subset[i].alphaTestReference); } foreach (var pass in Effect.CurrentTechnique.Passes) { pass.Apply(); graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, pos, cant_items); } } } /* * Vector3 s = new Vector3(1, 1, 1) * 0.1f; * if (debugEffect != null) * for (int i = 0; i < cant_bones; ++i) * { * var p0 = Vector3.Transform(bones[i].Position, invMetric); * debug_box.Draw(device, p0 - s, p0 + s, debugEffect, World, View, Proj); * int k = bones[i].parent; * if (k != -1) * { * var p1 = Vector3.Transform(bones[k].Position, invMetric); * CDebugLine.Draw(graphicsDevice, p0, p1, debugEffect, World, View, Proj); * } * } */ /* * if (debugEffect != null) * { * Vector3 s = new Vector3(1, 1, 1) * 20; * int cant_hit_points = 2; * int[] hit_pt = { 0, 12 }; * for (int i = 0; i < cant_hit_points; ++i) * { * var p0 = Vector3.Transform(bones[hit_pt[i]].Position, invMetric); * debug_box.Draw(device, p0 - s, p0 + s, debugEffect, World, View, Proj); * } * }*/ }
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(); }