public override BoneMotion BoneMotionAt(RenderBone b, float frame) { if (Bone.ContainsKey (b.bone.name)) { var bones = Bone [b.bone.name]; var m0 = from x in bones where x.frame_no >= frame select x; var m1 = from x in bones where x.frame_no <= frame select x; if (m0.Count () == 0) { if (m1.Count () == 0) { return null; } else { return m1.Last (); } } else { var b0 = m0.First (); if (m1.Count () == 0) { return b0; } else { var b1 = m1.Last (); if (b0.Equals (b1)) { return b0; } else { // interpolate int dif = b1.frame_no - b0.frame_no; float a0 = frame - b0.frame_no; float ratio = a0 / dif; var m = new BoneMotion (); m.location = new float[3]; m.rotation = new float[4]; double t = bazier(b0.interp, 0, 1, ratio); m.location[0] = (float) (b0.location[0] + (b1.location[0] - b0.location[0]) * t); t = bazier(b0.interp, 1, 1, ratio); m.location[1] = (float) (b0.location[1] + (b1.location[1] - b0.location[1]) * t); t = bazier(b0.interp, 2, 1, ratio); m.location[2] = (float) (b0.location[2] + (b1.location[2] - b0.location[2]) * t); slerp(m.rotation, b0.rotation, b1.rotation, 0, 0, bazier(b0.interp, 3, 1, ratio)); return m; } } } } else { return null; } }
private void clearUpdateFlags(RenderBone root, RenderBone b) { while (root != b) { b.updated = false; if (b.bone.parent != -1) { b = Surface.RenderBones[b.bone.parent]; } else { return; } } root.updated = false; }
private void setBoneMatrix(RenderBone b, float idx) { var m = Motions [CurrentMotion].BoneMotionAt(b, idx); if (m != null) { b.quaternion[0] = m.rotation[0]; b.quaternion[1] = m.rotation[1]; b.quaternion[2] = m.rotation[2]; b.quaternion[3] = m.rotation[3]; Quaternion.toMatrix(b.matrix_current, m.rotation); if (b.bone.parent == -1) { b.matrix_current[12] = m.location[0] + b.bone.head_pos[0]; b.matrix_current[13] = m.location[1] + b.bone.head_pos[1]; b.matrix_current[14] = m.location[2] + b.bone.head_pos[2]; } else { var p = Surface.RenderBones[b.bone.parent]; b.matrix_current[12] = m.location[0] + (b.bone.head_pos[0] - p.bone.head_pos[0]); b.matrix_current[13] = m.location[1] + (b.bone.head_pos[1] - p.bone.head_pos[1]); b.matrix_current[14] = m.location[2] + (b.bone.head_pos[2] - p.bone.head_pos[2]); } } else { // no VMD info so assume that no rotation and translation are specified Matrix.SetIdentityM(b.matrix_current, 0); Quaternion.setIndentity(b.quaternion); if (b.bone.parent == -1) { Matrix.TranslateM(b.matrix_current, 0, b.bone.head_pos[0], b.bone.head_pos[1], b.bone.head_pos[2]); } else { var p = Surface.RenderBones[b.bone.parent]; Matrix.TranslateM(b.matrix_current, 0, b.bone.head_pos[0], b.bone.head_pos[1], b.bone.head_pos[2]); Matrix.TranslateM(b.matrix_current, 0, -p.bone.head_pos[0], -p.bone.head_pos[1], -p.bone.head_pos[2]); } } }
private void updateBoneMatrix(RenderBone b) { if (b.updated == false) { if (b.bone.parent != -1) { var p = Surface.RenderBones[b.bone.parent]; updateBoneMatrix(p); Matrix.MultiplyMM(b.matrix, 0, p.matrix, 0, b.matrix_current, 0); } else { for (int i = 0; i < 16; i++) { b.matrix[i] = b.matrix_current[i]; } } b.updated = true; } }
public override BoneMotion BoneMotionAt(RenderBone b, float frame) { if (Bone.ContainsKey(b.bone.name)) { var bones = Bone [b.bone.name]; var m0 = from x in bones where x.frame_no >= frame select x; var m1 = from x in bones where x.frame_no <= frame select x; if (m0.Count() == 0) { if (m1.Count() == 0) { return(null); } else { return(m1.Last()); } } else { var b0 = m0.First(); if (m1.Count() == 0) { return(b0); } else { var b1 = m1.Last(); if (b0.Equals(b1)) { return(b0); } else // interpolate { int dif = b1.frame_no - b0.frame_no; float a0 = frame - b0.frame_no; float ratio = a0 / dif; var m = new BoneMotion(); m.location = new float[3]; m.rotation = new float[4]; double t = bazier(b0.interp, 0, 1, ratio); m.location[0] = (float)(b0.location[0] + (b1.location[0] - b0.location[0]) * t); t = bazier(b0.interp, 1, 1, ratio); m.location[1] = (float)(b0.location[1] + (b1.location[1] - b0.location[1]) * t); t = bazier(b0.interp, 2, 1, ratio); m.location[2] = (float)(b0.location[2] + (b1.location[2] - b0.location[2]) * t); slerp(m.rotation, b0.rotation, b1.rotation, 0, 0, bazier(b0.interp, 3, 1, ratio)); return(m); } } } } else { return(null); } }
public abstract BoneMotion BoneMotionAt(RenderBone b, float time);
private void setBoneMatrix(RenderBone b, float idx) { var m = Motions [CurrentMotion].BoneMotionAt (b, idx); if (m != null) { b.quaternion[0] = m.rotation[0]; b.quaternion[1] = m.rotation[1]; b.quaternion[2] = m.rotation[2]; b.quaternion[3] = m.rotation[3]; Quaternion.toMatrix(b.matrix_current, m.rotation); if (b.bone.parent == -1) { b.matrix_current[12] = m.location[0] + b.bone.head_pos[0]; b.matrix_current[13] = m.location[1] + b.bone.head_pos[1]; b.matrix_current[14] = m.location[2] + b.bone.head_pos[2]; } else { var p = Surface.RenderBones[b.bone.parent]; b.matrix_current[12] = m.location[0] + (b.bone.head_pos[0] - p.bone.head_pos[0]); b.matrix_current[13] = m.location[1] + (b.bone.head_pos[1] - p.bone.head_pos[1]); b.matrix_current[14] = m.location[2] + (b.bone.head_pos[2] - p.bone.head_pos[2]); } } else { // no VMD info so assume that no rotation and translation are specified Matrix.SetIdentityM(b.matrix_current, 0); Quaternion.setIndentity(b.quaternion); if (b.bone.parent == -1) { Matrix.TranslateM(b.matrix_current, 0, b.bone.head_pos[0], b.bone.head_pos[1], b.bone.head_pos[2]); } else { var p = Surface.RenderBones[b.bone.parent]; Matrix.TranslateM(b.matrix_current, 0, b.bone.head_pos[0], b.bone.head_pos[1], b.bone.head_pos[2]); Matrix.TranslateM(b.matrix_current, 0, -p.bone.head_pos[0], -p.bone.head_pos[1], -p.bone.head_pos[2]); } } }
private void getCurrentPosition(float[] v, RenderBone b) { float[] current = getCurrentMatrix(b); Array.Copy(current, 12, v, 0, 3); v[3] = 1; }
private float[] getCurrentMatrix(RenderBone b) { updateBoneMatrix(b); return b.matrix; }
private float[] getCurrentMatrix(RenderBone b) { updateBoneMatrix(b); return(b.matrix); }