public bool mNeedsUpdate = false;
public bool mNeedsMeshRebuild = true;
+
public struct binBVHJointState
{
public float currenttime_rot;
public int nextkeyframe_pos;
public int loopinframe;
- public int loopoutframe;
+ public int loopoutframe;\r
+\r
+ public bool finished;
}
{
Bone b;
if (mBones.TryGetValue(bonename, out b))
- {
+ {\r
return (b.getTotalOffset());
}
else
state.currenttime_pos = 0;
state.loopinframe = 0;
- state.loopoutframe = joint.rotationkeys.Length - 1;
+ state.loopoutframe = joint.rotationkeys.Length - 1;\r
+\r
+ state.finished = false;
+
+
if (b.Loop == true)
{
{
av.glavatar.skel.mAnimations.Add(b);
}
+ }\r
+\r
+ public void animate(float lastframetime)\r
+ {\r
+ \r
+ lock (mAnimations)\r
+ {\r
+ foreach (BinBVHAnimationReader b in mAnimations)\r
+ {\r
+ if (b == null)\r
+ continue;\r
+\r
+ int jpos = 0;\r
+ foreach (binBVHJoint joint in b.joints)\r
+ {\r
+ //warning struct copy non reference\r
+ binBVHJointState state = (binBVHJointState)b.joints[jpos].Tag;\r
+\r
+ int prio = 0;\r
+ //Quick hack to stack animations in the correct order\r
+ //TODO we need to do this per joint as they all have their own priorities as well ;-(\r
+ if (mPriority.TryGetValue(joint.Name, out prio))\r
+ {\r
+ if (prio > (b.Priority + joint.Priority))\r
+ continue;\r
+ }\r
+\r
+ mPriority[joint.Name] = b.Priority+joint.Priority;\r
+\r
+ if (state.finished == true)\r
+ continue;\r
+\r
+ Vector3 poslerp = Vector3.Zero;\r
+ Quaternion rotlerp = Quaternion.Identity;\r
+\r
+ // Position\r
+\r
+ if ( b.joints[jpos].positionkeys.Length >= 2 && joint.Name == "mPelvis")\r
+ {\r
+\r
+ //Console.WriteLine("Animate time " + state.currenttime_pos.ToString());\r
+\r
+ state.currenttime_pos += lastframetime;\r
+\r
+ float currentime = state.currenttime_pos;\r
+ bool overrun = false;\r
+\r
+ if (state.currenttime_pos > b.OutPoint)\r
+ {\r
+ //overrun state\r
+ int itterations = (int)(state.currenttime_pos / b.OutPoint) + 1;\r
+ state.currenttime_pos = currentime = (b.OutPoint - b.InPoint) - (((b.OutPoint - b.InPoint) * itterations) - state.currenttime_pos);\r
+ overrun = true;\r
+ }\r
+\r
+ binBVHJointKey pos_next = b.joints[jpos].positionkeys[state.nextkeyframe_pos];\r
+ binBVHJointKey pos_last = b.joints[jpos].positionkeys[state.lastkeyframe_pos];\r
+\r
+ // if the current time > than next key frame time we move keyframes\r
+ if (currentime >= pos_next.time || overrun)\r
+ {\r
+\r
+ //Console.WriteLine("bump");\r
+ state.lastkeyframe_pos++;\r
+ state.nextkeyframe_pos++;\r
+\r
+ if (b.Loop)\r
+ {\r
+ if (state.nextkeyframe_pos > state.loopoutframe)\r
+ state.nextkeyframe_pos = state.loopinframe;\r
+\r
+ if (state.lastkeyframe_pos > state.loopoutframe)\r
+ state.lastkeyframe_pos = state.loopinframe;\r
+\r
+\r
+ if (state.nextkeyframe_pos >= b.joints[jpos].positionkeys.Length)\r
+ state.nextkeyframe_pos = state.loopinframe;\r
+\r
+ if (state.lastkeyframe_pos >= b.joints[jpos].positionkeys.Length)\r
+ state.lastkeyframe_pos = state.loopinframe;\r
+\r
+ }\r
+ else\r
+ {\r
+ if(state.nextkeyframe_pos >= b.joints[jpos].positionkeys.Length)\r
+ state.nextkeyframe_pos = b.joints[jpos].positionkeys.Length-1;\r
+\r
+ if (state.lastkeyframe_pos >= b.joints[jpos].positionkeys.Length)\r
+ {\r
+ state.lastkeyframe_pos = b.joints[jpos].positionkeys.Length - 1;\r
+ state.finished = true;\r
+ //animation over\r
+ }\r
+ }\r
+ }\r
+\r
+ if (pos_next.time == pos_last.time)\r
+ {\r
+ state.finished = true;\r
+ }\r
+\r
+ // update the pointers incase they have been moved\r
+ pos_next = b.joints[jpos].positionkeys[state.nextkeyframe_pos];\r
+ pos_last = b.joints[jpos].positionkeys[state.lastkeyframe_pos];\r
+\r
+ float delta = state.currenttime_pos - pos_last.time / (pos_next.time - pos_last.time);\r
+\r
+ delta = Utils.Clamp(delta, 0f, 1f);\r
+\r
+ poslerp = Vector3.Lerp(pos_last.key_element, pos_next.key_element, delta);\r
+\r
+ //Console.WriteLine(string.Format("Time {0} {1} {2} {3} {4}", state.currenttime_pos, delta, poslerp.ToString(), state.lastkeyframe_pos, state.nextkeyframe_pos));\r
+\r
+ }\r
+\r
+ // end of position\r
+\r
+ //rotation\r
+ \r
+ if ( b.joints[jpos].rotationkeys.Length >= 2)\r
+ {\r
+\r
+ state.currenttime_rot += lastframetime;\r
+\r
+ float currentime = state.currenttime_rot;\r
+ bool overrun = false;\r
+\r
+ if (state.currenttime_rot > b.OutPoint)\r
+ {\r
+ //overrun state\r
+ int itterations = (int)(state.currenttime_rot / b.OutPoint) + 1;\r
+ state.currenttime_rot = currentime = (b.OutPoint - b.InPoint) - (((b.OutPoint - b.InPoint) * itterations) - state.currenttime_rot);\r
+ overrun = true;\r
+ }\r
+\r
+ binBVHJointKey rot_next = b.joints[jpos].rotationkeys[state.nextkeyframe_rot];\r
+ binBVHJointKey rot_last = b.joints[jpos].rotationkeys[state.lastkeyframe_rot];\r
+\r
+ // if the current time > than next key frame time we move keyframes\r
+ if (currentime >= rot_next.time || overrun)\r
+ {\r
+\r
+ state.lastkeyframe_rot++;\r
+ state.nextkeyframe_rot++;\r
+\r
+ if (b.Loop)\r
+ {\r
+ if (state.nextkeyframe_rot > state.loopoutframe)\r
+ state.nextkeyframe_rot = state.loopinframe;\r
+\r
+ if (state.lastkeyframe_rot > state.loopoutframe)\r
+ state.lastkeyframe_rot = state.loopinframe;\r
+\r
+ }\r
+ else\r
+ {\r
+ if (state.nextkeyframe_rot >= b.joints[jpos].rotationkeys.Length)\r
+ state.nextkeyframe_rot = b.joints[jpos].rotationkeys.Length - 1;\r
+\r
+ if (state.lastkeyframe_rot >= b.joints[jpos].rotationkeys.Length)\r
+ {\r
+ state.lastkeyframe_rot = b.joints[jpos].rotationkeys.Length - 1;\r
+ state.finished = true;\r
+ //animation over\r
+ }\r
+ }\r
+ }\r
+\r
+ if (rot_next.time == rot_last.time)\r
+ {\r
+ state.finished = true;\r
+ }\r
+\r
+ // update the pointers incase they have been moved\r
+ rot_next = b.joints[jpos].rotationkeys[state.nextkeyframe_rot];\r
+ rot_last = b.joints[jpos].rotationkeys[state.lastkeyframe_rot];\r
+\r
+ float delta = state.currenttime_rot - rot_last.time / (rot_next.time - rot_last.time);\r
+ delta = Utils.Clamp(delta, 0f, 1f);\r
+\r
+ Vector3 rotlerpv = Vector3.Lerp(rot_last.key_element, rot_next.key_element, delta);\r
+ rotlerp = new Quaternion(rotlerpv.X, rotlerpv.Y, rotlerpv.Z);\r
+ \r
+ }\r
+ \r
+\r
+ //end of rotation\r
+\r
+ deformbone(joint.Name, poslerp, rotlerp);\r
+ mNeedsMeshRebuild = true;\r
+\r
+ //warning struct copy non reference\r
+ b.joints[jpos].Tag = state;\r
+\r
+ jpos++;\r
+ }\r
+ }\r
+ }\r
+\r
}
- public void animate(float lastframetime)
+ public void animateold(float lastframetime)
{
try
Vector3 poslerp = Vector3.Zero;\r
\r
- //if (joint.Name == "mPelvis")\r
+ if ( joint.Name == "mPelvis")\r
{\r
\r
if (b.joints[jpos].positionkeys.Length > 2)\r
if (state.currenttime_pos != ((pos.time - b.joints[jpos].positionkeys[0].time)))\r
{\r
\r
- float delta = (pos2.time - pos.time) / ((state.currenttime_pos) - (pos.time - b.joints[jpos].positionkeys[0].time));\r
+ float delta = (pos2.time - pos.time) / ((state.currenttime_pos) - (pos.time - b.joints[jpos].positionkeys[0].time)) ;\r
\r
if (delta < 0)\r
delta = 0;\r
b.joints[jpos].Tag = (object)state;
- deformbone(joint.Name, poslerp, new Quaternion(rotlerp.X, rotlerp.Y, rotlerp.Z));\r
+ deformbone(joint.Name, poslerp*40, new Quaternion(rotlerp.X, rotlerp.Y, rotlerp.Z));\r
jpos++;
public class Bone
{
- public string name;
- public Vector3 pos;
+ public string name;\r
+ private Vector3 pos;
public Quaternion rot;
public Vector3 scale;
public Vector3 piviot;
public Vector3 orig_scale;
public Vector3 orig_piviot;
- Matrix4 mDeformMatrix = Matrix4.Identity;
+ Matrix4 mDeformMatrix = Matrix4.Identity;\r
+\r
+ public Vector3 animation_offset;
public Bone parent;
}
- public void deformbone(Vector3 pos, Quaternion rot)
+ public void deformbone(Vector3 dpos, Quaternion rot)
{
//float[] deform = Math3D.CreateSRTMatrix(scale, rot, this.orig_pos);
//mDeformMatrix = new Matrix4(deform[0], deform[1], deform[2], deform[3], deform[4], deform[5], deform[6], deform[7], deform[8], deform[9], deform[10], deform[11], deform[12], deform[13], deform[14], deform[15]);\r
\r
- this.offset_pos += pos;
- //this.pos = Bone.mBones[name].offset_pos + pos;
+ //this.offset_pos += pos;\r
+ //this.pos = pos;\r
+ // this.offset_pos = pos;\r
+\r
+ animation_offset = dpos;
+
+ //this.pos = Bone.mBones[name].offset_pos + dpos;
this.rot = Bone.mBones[name].orig_rot * rot;
markdirty();
public void scalebone(Vector3 scale)
{
- // this.scale = Bone.mBones[name].orig_scale * scale;
this.scale *= scale;
markdirty();
}
if (parent != null)
{
Quaternion totalrot = getParentRot(); // we don't want this joints rotation included
- Vector3 parento = parent.getOffset();
- mTotalPos = parento + pos * parent.scale * totalrot;
+ Vector3 parento = parent.getOffset();\r
+ mTotalPos = parento + pos * parent.scale * totalrot;
Vector3 orig = getOrigOffset();
mDeltaPos = mTotalPos - orig;
{
Vector3 orig = getOrigOffset();
//mTotalPos = (pos * scale)+offset_pos;
- //mTotalPos = (pos) + offset_pos;
- mTotalPos = pos;
+ //mTotalPos = (pos) + offset_pos;\r
+ mTotalPos = animation_offset + pos;
mDeltaPos = mTotalPos - orig;
posdirty = false;
return mTotalPos;