{\r
foreach (Animation anim in e.Animations)\r
{\r
- if (av.glavatar.skel.addplayinganimation(anim))\r
+ UUID tid = UUID.Random();\r
+ skeleton.mAnimationTransactions.Add(tid, av);\r
+\r
+ BinBVHAnimationReader bvh;\r
+ if(skeleton.mAnimationCache.TryGetValue(anim.AnimationID,out bvh))\r
{\r
- Logger.Log("Requesting new animation asset " + anim.AnimationID.ToString(), Helpers.LogLevel.Info);\r
- Client.Assets.RequestAsset(anim.AnimationID, AssetType.Animation, false, animRecievedCallback);\r
+ skeleton.addanimation(null, tid, bvh);\r
+ break;\r
}\r
+\r
+ Logger.Log("Requesting new animation asset " + anim.AnimationID.ToString(), Helpers.LogLevel.Info);\r
+ \r
+ Client.Assets.RequestAsset(anim.AnimationID, AssetType.Animation, false,SourceType.Asset,tid, animRecievedCallback); \r
}\r
break;\r
}\r
void animRecievedCallback(AssetDownload transfer, Asset asset)\r
{\r
if (transfer.Success)\r
- {\r
- skeleton.addanimation(asset);\r
+ { \r
+ skeleton.addanimation(asset,transfer.ID, null);\r
}\r
}\r
\r
\r
attachment_point apoint = GLAvatar.attachment_points[attachment_index];\r
Vector3 point = parentav.glavatar.skel.getOffset(apoint.joint) + apoint.position;\r
- Quaternion qrot = parentav.glavatar.skel.getRotation(apoint.joint) * apoint.rotation;\r
+ Quaternion qrot = apoint.rotation * parentav.glavatar.skel.getRotation(apoint.joint);\r
\r
pos = parentPos + point * parentRot + prim.InterpolatedPosition * (parentRot * qrot);\r
rot = qrot * parentRot * prim.InterpolatedRotation;\r
\r
// Prim roation and position\r
Vector3 pos = av.avatar.Position;\r
- pos.X += 1;\r
+ pos.X += 1; \r
\r
GL.MultMatrix(Math3D.CreateSRTMatrix(new Vector3(1, 1, 1), av.avatar.Rotation, pos));\r
\r
av.glavatar.skel.mNeedsMeshRebuild = false;\r
}\r
\r
+ av.glavatar.skel.animate(lastFrameTime);\r
+\r
avatarNr++;\r
\r
if (av.glavatar._meshes.Count > 0)\r
if (jointname == "")\r
{\r
//Don't yet handle this, its a split joint to two children\r
- continue;\r
+ ba = av.skel.mBones[jointname2];\r
+ bb = null;\r
+\r
+ //continue;\r
}\r
else\r
{\r
if (VisualParamEx.allParams.TryGetValue(param, out vpx))\r
{\r
\r
- Logger.Log(string.Format("Applying visual parameter {0} id {1} value {2}", vpx.Name, vpx.ParamID, weight), Helpers.LogLevel.Info);\r
+ //Logger.Log(string.Format("Applying visual parameter {0} id {1} value {2}", vpx.Name, vpx.ParamID, weight), Helpers.LogLevel.Info);\r
\r
//weight = weight * 2.0f;\r
//weight=weight-1.0f;\r
\r
+ if (weight < 0)\r
+ weight = 0;\r
+\r
+ if (weight > 1.0)\r
+ weight = 1;\r
+\r
float value = vpx.MinValue + ((vpx.MaxValue - vpx.MinValue) * weight);\r
\r
if (vpx.pType == VisualParamEx.ParamType.TYPE_MORPH)\r
public static Dictionary<int, string> mLowerMeshMapping = new Dictionary<int, string>();\r
public static Dictionary<int, string> mHeadMeshMapping = new Dictionary<int, string>();\r
\r
- public static Dictionary<UUID, BinBVHAnimationReader> mKnownAnimations = new Dictionary<UUID, BinBVHAnimationReader>();\r
- public Dictionary<UUID, Animation> animlist = new Dictionary<UUID, Animation>();\r
+ public BinBVHAnimationReader[] mPlayingAnimations = new BinBVHAnimationReader[6];\r
+\r
+ public static Dictionary<UUID, RenderAvatar> mAnimationTransactions = new Dictionary<UUID, RenderAvatar>();\r
+\r
+ public static Dictionary<UUID, BinBVHAnimationReader> mAnimationCache = new Dictionary<UUID, BinBVHAnimationReader>();\r
\r
public bool mNeedsUpdate = false;\r
public bool mNeedsMeshRebuild = false;\r
public Bone mLeftEye = null;\r
public Bone mRightEye = null;\r
\r
+ public struct binBVHJointState\r
+ {\r
+ public float currenttime_rot;\r
+ public int lastkeyframe_rot;\r
+ public int nextkeyframe_rot;\r
+\r
+ public float currenttime_pos;\r
+ public int lastkeyframe_pos;\r
+ public int nextkeyframe_pos;\r
+ }\r
+\r
+\r
public skeleton()\r
{\r
\r
+ \r
+\r
mBones = new Dictionary<string, Bone>();\r
\r
foreach (Bone src in Bone.mBones.Values)\r
\r
// Add animations to the global decoded list\r
// TODO garbage collect unused animations somehow\r
- public static void addanimation(OpenMetaverse.Assets.Asset asset)\r
+ public static void addanimation(OpenMetaverse.Assets.Asset asset,UUID tid, BinBVHAnimationReader b)\r
{\r
- BinBVHAnimationReader b = new BinBVHAnimationReader(asset.AssetData);\r
- if (!mKnownAnimations.ContainsKey(asset.AssetID))\r
+ RenderAvatar av;\r
+ mAnimationTransactions.TryGetValue(tid, out av);\r
+ if (av == null)\r
+ return;\r
+\r
+ mAnimationTransactions.Remove(tid);\r
+\r
+ if (asset != null)\r
{\r
+ b = new BinBVHAnimationReader(asset.AssetData);\r
+ mAnimationCache[asset.AssetID] = b;\r
Logger.Log("Adding new decoded animaton known animations " + asset.AssetID.ToString(), Helpers.LogLevel.Info);\r
- mKnownAnimations.Add(asset.AssetID, b);\r
}\r
- }\r
+ \r
+ int pos=0;\r
+ foreach (binBVHJoint joint in b.joints)\r
+ {\r
+ binBVHJointState state;\r
\r
- public bool addplayinganimation(Animation anim)\r
- {\r
+ state.lastkeyframe_rot = 0;\r
+ state.nextkeyframe_rot = 1;\r
\r
- if (!animlist.ContainsKey(anim.AnimationID))\r
- {\r
- Logger.Log("Adding new playing animaton " + anim.AnimationID.ToString(), Helpers.LogLevel.Info);\r
- animlist.Add(anim.AnimationID, anim);\r
- }\r
+ state.lastkeyframe_pos = 0;\r
+ state.nextkeyframe_pos = 1;\r
\r
- mNeedsUpdate = true;\r
+ state.currenttime_rot = 0;\r
+ state.currenttime_pos = 0;\r
\r
- if (skeleton.mKnownAnimations.ContainsKey(anim.AnimationID))\r
- {\r
- return false;\r
+ b.joints[pos].Tag = state;\r
+ pos++;\r
}\r
\r
- return true;\r
-\r
+ if (b.Priority >= 0 && b.Priority <= 5)\r
+ av.glavatar.skel.mPlayingAnimations[b.Priority] = b;\r
}\r
\r
- public void firstkeyframe()\r
+ public void animate(float lastframetime)\r
{\r
- if (mNeedsUpdate == false)\r
- return;\r
\r
- foreach (Animation anim in this.animlist.Values) // TODO priority sort\r
- {\r
- BinBVHAnimationReader b;\r
- if (skeleton.mKnownAnimations.TryGetValue(anim.AnimationID, out b))\r
+ foreach (BinBVHAnimationReader b in mPlayingAnimations) // TODO priority sort\r
{\r
- foreach (binBVHJoint joint in b.joints)\r
- {\r
- //actually get the last for a pose the last frame is probably the static one once\r
- //we have reached position\r
- binBVHJointKey rot = joint.rotationkeys[joint.rotationkeys.Length - 1];\r
+ if (b == null)\r
+ continue;\r
\r
- Vector3 pos = new Vector3(0, 0, 0);\r
- //binBVHJointKey pos = joint.positionkeys[0];\r
+ int jpos = 0;\r
+ foreach (binBVHJoint joint in b.joints)\r
+ {\r
\r
- deformbone(joint.Name, new Vector3(0, 0, 0), pos, new Quaternion(rot.key_element.X, rot.key_element.Y, rot.key_element.Z));\r
\r
- }\r
+ binBVHJointState state = (binBVHJointState) b.joints[jpos].Tag;\r
\r
- mNeedsMeshRebuild = true;\r
- }\r
- }\r
+ state.currenttime_rot += lastframetime;\r
+ state.currenttime_pos += lastframetime;\r
+\r
+ //fudge\r
+ if (b.joints[jpos].rotationkeys.Length == 1)\r
+ {\r
+ state.nextkeyframe_rot = 0;\r
+ }\r
+\r
+ Vector3 poslerp = Vector3.Zero;\r
+\r
+ if (b.joints[jpos].positionkeys.Length > 2)\r
+ {\r
+ binBVHJointKey pos2 = b.joints[jpos].positionkeys[state.nextkeyframe_pos];\r
+\r
+\r
+ if (state.currenttime_pos > pos2.time)\r
+ {\r
+ state.lastkeyframe_pos++;\r
+ state.nextkeyframe_pos++;\r
+\r
+ if (state.nextkeyframe_pos >= b.joints[jpos].positionkeys.Length)\r
+ {\r
+ if (b.Loop == true)\r
+ {\r
+ state.nextkeyframe_pos = 0;\r
+ state.currenttime_pos = 0;\r
+ }\r
+ else\r
+ {\r
+ state.nextkeyframe_pos = joint.positionkeys.Length - 1;\r
+ }\r
+ }\r
+\r
+ if (state.lastkeyframe_pos >= b.joints[jpos].positionkeys.Length)\r
+ {\r
+ if (b.Loop == true)\r
+ {\r
+ state.lastkeyframe_pos = 0;\r
+ state.currenttime_pos = 0;\r
+\r
+ }\r
+ else\r
+ {\r
+ state.lastkeyframe_pos = joint.positionkeys.Length - 1;\r
+ }\r
+ }\r
+ }\r
+\r
+ binBVHJointKey pos = b.joints[jpos].positionkeys[state.lastkeyframe_pos];\r
+\r
+\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
+\r
+ if (delta > 1)\r
+ delta = 1;\r
+\r
+ poslerp = Vector3.Lerp(pos.key_element, pos2.key_element, delta) *-1;\r
+\r
+ }\r
+\r
+\r
+ Vector3 rotlerp = Vector3.Zero;\r
+ if (b.joints[jpos].rotationkeys.Length > 0)\r
+ {\r
+ binBVHJointKey rot2 = b.joints[jpos].rotationkeys[state.nextkeyframe_rot];\r
+\r
+ if (state.currenttime_rot > rot2.time)\r
+ {\r
+ state.lastkeyframe_rot++;\r
+ state.nextkeyframe_rot++;\r
+\r
+ if (state.nextkeyframe_rot >= b.joints[jpos].rotationkeys.Length)\r
+ {\r
+ if (b.Loop == true)\r
+ {\r
+ state.nextkeyframe_rot = 0;\r
+ state.currenttime_rot = 0;\r
+ }\r
+ else\r
+ {\r
+ state.nextkeyframe_rot = joint.rotationkeys.Length - 1;\r
+ }\r
+ }\r
+\r
+ if (state.lastkeyframe_rot >= b.joints[jpos].rotationkeys.Length)\r
+ {\r
+ if (b.Loop == true)\r
+ {\r
+ state.lastkeyframe_rot = 0;\r
+ state.currenttime_rot = 0;\r
+\r
+ }\r
+ else\r
+ {\r
+ state.lastkeyframe_rot = joint.rotationkeys.Length - 1;\r
+ }\r
+ }\r
+ }\r
+ \r
+ binBVHJointKey rot = b.joints[jpos].rotationkeys[state.lastkeyframe_rot];\r
+ rot2 = b.joints[jpos].rotationkeys[state.nextkeyframe_rot];\r
+\r
+ float deltarot = (rot2.time - rot.time) / ((state.currenttime_rot) - (rot.time - b.joints[jpos].rotationkeys[0].time));\r
+\r
+ \r
+ if (deltarot < 0)\r
+ deltarot = 0;\r
+\r
+ if (deltarot > 1)\r
+ deltarot = 1;\r
+\r
+ rotlerp = Vector3.Lerp(rot.key_element, rot2.key_element, deltarot);\r
+\r
+ }\r
+\r
+ b.joints[jpos].Tag = (object)state;\r
+ \r
+ deformbone(joint.Name, poslerp, new Vector3(0, 0, 0), new Quaternion(rotlerp.X, rotlerp.Y, rotlerp.Z));\r
+\r
+ jpos++;\r
+ }\r
+\r
+ mNeedsMeshRebuild = true;\r
+ }\r
\r
mNeedsUpdate = false;\r
}\r
\r
public void deformbone(Vector3 pos, Vector3 scale, Quaternion rot)\r
{\r
- float[] deform = Math3D.CreateSRTMatrix(scale, rot, this.orig_pos);\r
- 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
+ //float[] deform = Math3D.CreateSRTMatrix(scale, rot, this.orig_pos);\r
+ //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
this.pos = Bone.mBones[name].orig_pos + pos;\r
this.scale = Bone.mBones[name].orig_scale + scale;\r
this.rot = Bone.mBones[name].orig_rot * rot;\r
Vector3 mepre = pos * scale;\r
mepre = mepre * totalrot;\r
mTotalPos = parento + mepre;\r
- posdirty = false;\r
-\r
+ \r
Vector3 orig = getOrigOffset();\r
mDeltaPos = mTotalPos - orig;\r
\r
+ posdirty = false;\r
+\r
return mTotalPos;\r
}\r
else\r
{\r
- return (pos * scale) * getRotation();\r
+ Vector3 orig = getOrigOffset();\r
+ mTotalPos = (pos * scale);\r
+ mDeltaPos = mTotalPos - orig;\r
+ posdirty = false;\r
+ return mTotalPos;\r
+ \r
}\r
}\r
\r
{\r
if (parent != null)\r
{\r
- return (parent.getOrigOffset()) + orig_pos;\r
+ return (parent.getOrigOffset() + orig_pos);\r
}\r
else\r
{\r