示例#1
0
 internal void OnKeyFrameReached(CompositeKeyFrame keyFrame)
 {
     if (KeyFrameReached != null)
     {
         KeyFrameReached(keyFrame, EventArgs.Empty);
     }
 }
示例#2
0
        public void LerpKeyFrameWith(CompositeKeyFrame nextFrame, float currentLife)
        {
            float amount = MathHelper.Clamp(currentLife / this._duration, 0, 1);

            //Console.WriteLine("--- Lerping frame with amount: " + amount);
            if (Parent.Parent.RootBone != null)
            {
                // call the LerpBone on the root, and it will spread to all child bones using Recursivity
                CompositeBoneTransform boneTransform = GetBoneTransformFromKeyFrame(this, Parent.Parent.RootBone.Name);
                LerpBone(boneTransform, nextFrame, amount);
            }
        }
示例#3
0
 public CompositeBoneTransform GetBoneTransformFromKeyFrame(CompositeKeyFrame keyFrame, String boneReference)
 {
     foreach (CompositeBoneTransform boneTrans in keyFrame.BoneTransforms)
     {
         if (boneTrans.BoneReference == boneReference)
         {
             return(boneTrans);
         }
     }
     throw new Exception("BoneReference \"" + boneReference
                         + "\" not found in keyframe \"" + keyFrame.Name + "\"");
 }
示例#4
0
 /// <summary>
 /// Removes a children from this bone
 /// </summary>
 public void RemoveChildBone(CompositeBone childBone)
 {
     // sync transforms
     for (int i = 0; i < Parent.Animations.Count; i++)
     {
         // loop through every keyframe to sync them
         for (int j = 0; j < Parent.Animations[i].KeyFrames.Count; j++)
         {
             CompositeKeyFrame keyframe = Parent.Animations[i].KeyFrames[j];
             // remove the entry AND its children entries
             RemoveBoneTransformEntry(keyframe.BoneTransforms, childBone);
         }
     }
     // remove the bone
     this.ChildBones.Remove(childBone);
 }
示例#5
0
 public void CopyValuesTo(CompositeBoneTransform target, CompositeKeyFrame newParent)
 {
     target.Parent            = newParent;
     target.SceneItem         = this.SceneItem;
     target.SubItem           = this.SubItem;
     target.Position          = this.Position;
     target.Scale             = this.Scale;
     target.Rotation          = this.Rotation;
     target.Opacity           = this.Opacity;
     target.FlipHorizontal    = this.FlipHorizontal;
     target.FlipVertical      = this.FlipVertical;
     target.IsVisible         = this.IsVisible;
     target.BoneReference     = this.BoneReference;
     target.InheritPosition   = this.InheritPosition;
     target.InheritRotation   = this.InheritRotation;
     target.InheritScale      = this.InheritScale;
     target.InheritVisibility = this.InheritVisibility;
 }
示例#6
0
        public void LerpBone(CompositeBoneTransform boneTransform, CompositeKeyFrame nextFrame, float amount)
        {
            CompositeBoneTransform nextTransform;

            if (boneTransform.Bone.Interpolate == true)
            {
                nextTransform = GetBoneTransformFromKeyFrame(nextFrame, boneTransform.BoneReference);
            }
            else
            {
                nextTransform = GetBoneTransformFromKeyFrame(
                    this.Parent.Parent.Animations[0].KeyFrames[0], boneTransform.BoneReference);
            }
            boneTransform.LerpSceneItemWith(nextTransform, amount, !boneTransform.Bone.Interpolate);
            foreach (CompositeBone bone in boneTransform.Bone.ChildBones)
            {
                CompositeBoneTransform childBoneTransform = GetBoneTransformFromKeyFrame(this, bone.Name);
                LerpBone(childBoneTransform, nextFrame, amount);
            }
        }
示例#7
0
 public void CopyValuesTo(CompositeKeyFrame target, CompositeAnimation newParent)
 {
     target.Parent   = newParent;
     target.Name     = this.Name;
     target.Duration = this.Duration;
     // copy CompositeBoneTransforms
     for (int i = 0; i < this.BoneTransforms.Count; i++)
     {
         // if no transform is available
         if (target.BoneTransforms.Count <= i)
         {
             target.BoneTransforms.Add(new CompositeBoneTransform());
         }
         this.BoneTransforms[i].CopyValuesTo(target.BoneTransforms[i], target);
     }
     // Remove remaining types (can cause garbage!)
     for (int i = target.BoneTransforms.Count; i > this.BoneTransforms.Count; i--)
     {
         target.BoneTransforms.RemoveAt(i - 1);
     }
 }
示例#8
0
        /// <summary>
        /// Insert a children bone at specific index
        /// </summary>
        public void InsertChildBone(int index, CompositeBone childBone)
        {
            index = IceMath.Clamp(index, 0, _childBones.Count);
            _childBones.Insert(index, childBone);
            childBone.ParentBone = this;
            childBone.Parent     = this.Parent;
            CompositeBone precedingBone;

            if (index == 0)
            {
                precedingBone = this;
            }
            else
            {
                precedingBone = this.ChildBones[index - 1];
            }
            // sync transforms
            for (int i = 0; i < Parent.Animations.Count; i++)
            {
                // loop through every keyframe to sync them
                for (int j = 0; j < Parent.Animations[i].KeyFrames.Count; j++)
                {
                    CompositeKeyFrame keyframe = Parent.Animations[i].KeyFrames[j];
                    // loop to find the previous bone
                    for (int k = 0; k < keyframe.BoneTransforms.Count; k++)
                    {
                        CompositeBoneTransform transform = keyframe.BoneTransforms[k];
                        if (transform.Bone.Equals(precedingBone))
                        {
                            CompositeBoneTransform newTransform = new CompositeBoneTransform();
                            newTransform.Parent        = keyframe;
                            newTransform.BoneReference = childBone.Name;
                            // insert the new bone just after the preceding bone
                            keyframe.BoneTransforms.Insert(k + 1, newTransform);
                        }
                    }
                }
            }
        }
示例#9
0
 internal void OnKeyFrameReached(CompositeKeyFrame keyFrame)
 {
     if (KeyFrameReached != null)
     {
         KeyFrameReached(keyFrame, EventArgs.Empty);
     }
 }
示例#10
0
 public void CopyValuesTo(CompositeBoneTransform target, CompositeKeyFrame newParent)
 {
     target.Parent = newParent;
     target.SceneItem = this.SceneItem;
     target.SubItem = this.SubItem;
     target.Position = this.Position;
     target.Scale = this.Scale;
     target.Rotation = this.Rotation;
     target.Opacity = this.Opacity;
     target.FlipHorizontal = this.FlipHorizontal;
     target.FlipVertical = this.FlipVertical;
     target.IsVisible = this.IsVisible;
     target.BoneReference = this.BoneReference;
     target.InheritPosition = this.InheritPosition;
     target.InheritRotation = this.InheritRotation;
     target.InheritScale = this.InheritScale;
     target.InheritVisibility = this.InheritVisibility;            
 }
 private void toolStripButtonKeyFramePaste_Click(object sender, EventArgs e)
 {
     CompositeAnimation anim = SelectedCompositeAnimation;
     int insertIndex = -1;
     int[] selectedIndicies = tableKeyFrames.SelectedIndicies;
     if (anim.KeyFrames.Count > 0 && selectedIndicies.Length > 0)
     {
         insertIndex = selectedIndicies[0];
     }
     CompositeKeyFrame newInstance = new CompositeKeyFrame();
     CompositeKeyFrameClipBoard.CopyValuesTo(newInstance, anim);
     anim.KeyFrames.Insert(insertIndex + 1, newInstance);   
     RefreshListKeyFrames();
 }
示例#12
0
 public void CopyValuesTo(CompositeKeyFrame target, CompositeAnimation newParent)
 {
     target.Parent = newParent;
     target.Name = this.Name;
     target.Duration = this.Duration;
     // copy CompositeBoneTransforms            
     for (int i = 0; i < this.BoneTransforms.Count; i++)
     {
         // if no transform is available
         if (target.BoneTransforms.Count <= i)
         {
             target.BoneTransforms.Add(new CompositeBoneTransform());
         }
         this.BoneTransforms[i].CopyValuesTo(target.BoneTransforms[i], target);
     }
     // Remove remaining types (can cause garbage!)
     for (int i = target.BoneTransforms.Count; i > this.BoneTransforms.Count; i--)
     {
         target.BoneTransforms.RemoveAt(i - 1);
     }
 }
 public void DrawKeyFrame(CompositeKeyFrame keyFrame)
 {
     if (keyFrame != null)
     {
         CompositeAnimation anim = keyFrame.Parent;                
         anim.ResetToKeyFrame(ParentEditor.tableKeyFrames.SelectedIndicies[0]);
         CompositeEntity.Update(1 / 60f);
         CompositeEntity.Draw(1 / 60f);
     }
 }
示例#14
0
 public void LerpBone(CompositeBoneTransform boneTransform, CompositeKeyFrame nextFrame, float amount)
 {
     CompositeBoneTransform nextTransform;
     if (boneTransform.Bone.Interpolate == true)
     {
         nextTransform = GetBoneTransformFromKeyFrame(nextFrame, boneTransform.BoneReference);
     }
     else
     {
         nextTransform = GetBoneTransformFromKeyFrame(
             this.Parent.Parent.Animations[0].KeyFrames[0], boneTransform.BoneReference);
     }            
     boneTransform.LerpSceneItemWith(nextTransform, amount, !boneTransform.Bone.Interpolate);
     foreach (CompositeBone bone in boneTransform.Bone.ChildBones)
     {
         CompositeBoneTransform childBoneTransform = GetBoneTransformFromKeyFrame(this, bone.Name);
         LerpBone(childBoneTransform, nextFrame, amount);
     }
 }
示例#15
0
 public void LerpKeyFrameWith(CompositeKeyFrame nextFrame, float currentLife)
 {
     float amount = MathHelper.Clamp(currentLife / this._duration, 0, 1);            
     //Console.WriteLine("--- Lerping frame with amount: " + amount);
     if (Parent.Parent.RootBone != null)
     {
         // call the LerpBone on the root, and it will spread to all child bones using Recursivity
         CompositeBoneTransform boneTransform = GetBoneTransformFromKeyFrame(this, Parent.Parent.RootBone.Name);
         LerpBone(boneTransform, nextFrame, amount);
     }
 }
 private void toolStripButtonKeyFrameCopy_Click(object sender, EventArgs e)
 {
     CompositeAnimation anim = SelectedCompositeAnimation;
     CompositeKeyFrameClipBoard = new CompositeKeyFrame();
     SelectedCompositeKeyFrame.CopyValuesTo(CompositeKeyFrameClipBoard, anim);
     toolStripButtonKeyFramePaste.Enabled = true;
 }
示例#17
0
        public void Update(float elapsed)
        {
            if (Parent == null)
            {
                throw new Exception("The Parent of this animation isn't set");
            }
            int lastFrameIndex = _currentKeyFrameIndex;

            if (_keyFrames.Count > 0 && this.IsPlaying == true)
            {
                // Get the current frame index
                int _lifeAccumulator = 0;
                for (int i = 0; i < _keyFrames.Count; i++)
                {
                    _currentKeyFrameIndex = i;
                    int duration = _keyFrames[i].Duration;
                    if (duration < 1)
                    {
                        duration = 1;
                    }
                    _lifeAccumulator += duration;
                    if (_lifeAccumulator > _currentLife)
                    {
                        break;
                    }
                    // if we went over the maxium
                    else if (i == _keyFrames.Count - 1)
                    {
                        _currentLife = _lifeAccumulator;
                        break;
                    }
                }
                CompositeKeyFrame currentKeyFrame = _keyFrames[_currentKeyFrameIndex];
                if (_currentKeyFrameIndex != lastFrameIndex)
                {
                    this.Parent.OnKeyFrameReached(currentKeyFrame);
                }
                CompositeKeyFrame nextKeyFrame = null;
                // get the next key frame
                if (_currentKeyFrameIndex < _keyFrames.Count - 1)
                {
                    nextKeyFrame = _keyFrames[_currentKeyFrameIndex + 1];
                }
                // if we've reached the last frame
                else if (_currentKeyFrameIndex == _keyFrames.Count - 1)
                {
                    if (this.LerpLastFrameWithFirst == true)
                    {
                        nextKeyFrame = _keyFrames[0];
                    }
                    else
                    {
                        nextKeyFrame = currentKeyFrame;
                    }
                }
                int currentKeyFrameDuration = currentKeyFrame.Duration;
                if (currentKeyFrameDuration < 1)
                {
                    currentKeyFrameDuration = 1;
                }
                float life = _currentLife - (_lifeAccumulator - currentKeyFrameDuration);
                //if (Parent.CurrentAnimationID == 1)
                //{
                //    Console.WriteLine(Parent.CurrentAnimation.Name + "] Update key: "
                //        + _currentKeyFrameIndex + "] life: " + life + "/" + currentKeyFrameDuration);
                //}
                currentKeyFrame.LerpKeyFrameWith(nextKeyFrame, life);
                currentKeyFrame.Update(elapsed);

                _currentLife += _speed;
                // if we reach the end of the last keyframe, we need to loop
                if (_currentKeyFrameIndex == _keyFrames.Count - 1 && _lifeAccumulator <= _currentLife)
                {
                    if (_loopMax > 0 && _loopCounter >= _loopMax - 1)
                    {
                        EndAnim();
                    }
                    else
                    {
                        _loopCounter++;
                        _currentLife = 0;
                    }
                    this.Parent.OnEndOfAnimLoopReached(this);
                }
            }
        }
示例#18
0
        private static void SetProperty(string p, object targetObject, XmlNode node, object defaultValue)
        {
            if (targetObject is SceneItem)
            {
                TraceLogger.TraceVerbose("Setting Property " + p + " On SceneItem - " + ((SceneItem)targetObject).Name);
            }
            else
            {
                TraceLogger.TraceVerbose("Setting Property " + p + " On Object - " + targetObject.GetType().Name);
            }

            PropertyInfo _prop = targetObject.GetType().GetProperty(p);
            if (_prop == null)
            {
                return;
            }         
            XmlNode _newNode = node.SelectSingleNode(_prop.Name);
            if (_newNode == null)
            {
                if (defaultValue != null)
                {
                    _prop.SetValue(targetObject, defaultValue, null);
                    return;
                }
                if (_prop.PropertyType == typeof(bool))
                {
                    _prop.SetValue(targetObject, false, null);
                }
                else if (_prop.PropertyType == typeof(bool?))
                {
                    _prop.SetValue(targetObject, null, null);
                }
                else if (_prop.PropertyType == typeof(int))
                {
                    _prop.SetValue(targetObject, 0, null);
                }
                else if (_prop.PropertyType == typeof(String))
                {
                    _prop.SetValue(targetObject, String.Empty, null);
                }
                else if (_prop.PropertyType == typeof(Vector2))
                {
                    _prop.SetValue(targetObject, Vector2.Zero, null);
                }
                else if (_prop.PropertyType == typeof(Point))
                {
                    _prop.SetValue(targetObject, Point.Zero, null);
                }
                return;
            }
            TraceLogger.TraceVerbose("Property Type [" + _prop.PropertyType.Name + "]");

            if (_prop.PropertyType == typeof(Vector2))
            {
                _prop.SetValue(targetObject, ParseVector(_newNode), null);
            }
            else if (_prop.PropertyType == typeof(List<Vector2>))
            {
                
                List<Vector2> list = new List<Vector2>();
                foreach (XmlNode vecnode in _newNode.ChildNodes)
                {
                    list.Add(ParseVector(vecnode));
                }
                _prop.SetValue(targetObject, list, null);
            }
            /* FARSEER tile polygone serialization
            else if (_prop.PropertyType == typeof(List<Polygon>))
            {                
                List<Polygon> list = new List<Polygon>();
                foreach (XmlNode vecnode in _newNode.ChildNodes)
                {
                    list.Add(Polygon.FromString(vecnode.InnerText));
                }
                _prop.SetValue(targetObject, list, null);
            }*/
            else if (_prop.PropertyType == typeof(Rectangle?))
            {
                if (_newNode.Attributes.Count == 4)
                {
                    _prop.SetValue(targetObject, ParseRectangleNullable(_newNode), null);
                }
                else
                {
                    _prop.SetValue(targetObject, null, null);
                }
                
            }
            else if (_prop.PropertyType == typeof(Rectangle))
            {
                if (_newNode.Attributes.Count == 4)
                    {
                        _prop.SetValue(targetObject, ParseRectangle(_newNode), null);
                    }                
            }
            else if (_prop.PropertyType == typeof(Point))
            {
                Point _point = new Point(
                    int.Parse(node.SelectSingleNode(_prop.Name + "/X").InnerText, CultureInfo.InvariantCulture),
                    int.Parse(node.SelectSingleNode(_prop.Name + "/Y").InnerText, CultureInfo.InvariantCulture));
                _prop.SetValue(targetObject, _point, null);
            }
            else if (_prop.PropertyType == typeof(float))
            {
                _prop.SetValue(targetObject, Single.Parse(_newNode.InnerText,
                    CultureInfo.InvariantCulture), null);
            }
            else if (_prop.PropertyType == typeof(Color))
            {
                Color newColor = (Color)ParseToColor(_newNode.InnerText);
                    _prop.SetValue(targetObject, newColor, null);
               
            }
            else if (_prop.PropertyType == typeof(bool))
            { 
                _prop.SetValue(targetObject, bool.Parse(_newNode.InnerText), null);
            }
            else if (_prop.PropertyType == typeof(bool?))
            {
                if (String.IsNullOrEmpty(_newNode.InnerText) == false)
                {
                    _prop.SetValue(targetObject, bool.Parse(_newNode.InnerText), null);
                }
                else
                {
                    _prop.SetValue(targetObject, null, null);
                }
            }
            else if (_prop.PropertyType == typeof(byte))
            {
#if(WINDOWS)
                _prop.SetValue(targetObject, byte.Parse(_newNode.InnerText,
                    CultureInfo.InvariantCulture), null);
#else
                byte b = (byte)int.Parse(_newNode.InnerText);
                _prop.SetValue(targetObject, b, null);
#endif
            }
            else if (_prop.PropertyType == typeof(byte?))
            {
                if (String.IsNullOrEmpty(_newNode.InnerText) == false)
                {
#if(WINDOWS)
                    _prop.SetValue(targetObject, byte.Parse(_newNode.InnerText, CultureInfo.InvariantCulture), null);
#else
                    byte b = (byte)int.Parse(_newNode.InnerText);
                    _prop.SetValue(targetObject, b, null);
#endif
                }
            }
            else if (_prop.PropertyType == typeof(int))
            {
                _prop.SetValue(targetObject, int.Parse(_newNode.InnerText, CultureInfo.InvariantCulture), null);
            }
            else if (_prop.PropertyType == typeof(string))
            {
                _prop.SetValue(targetObject, _newNode.InnerText, null);
            }
            else if (_prop.PropertyType.BaseType == typeof(Enum))
            {
#if(WINDOWS)
                Enum val = (Enum)Enum.Parse(_prop.PropertyType, _newNode.InnerText);
                _prop.SetValue(targetObject, Convert.ChangeType(val, _prop.PropertyType), null);
#else

                Enum val = (Enum)Enum.Parse(_prop.PropertyType, _newNode.InnerText, true);
                _prop.SetValue(targetObject, Convert.ChangeType(val, _prop.PropertyType, null), null);
#endif
            }
            else if (_prop.PropertyType == typeof(CompositeBone))
            {
                CompositeBone bone = GetCompositeBone(_newNode);
                _prop.SetValue(targetObject, bone, null);
            }
            else if (_prop.PropertyType == typeof(List<CompositeBone>))
            {
                CompositeBone parent = targetObject as CompositeBone;
                foreach (XmlNode vecnode in _newNode.ChildNodes)
                {
                    CompositeBone anim = GetCompositeBone(vecnode);
                    anim.ParentBone = parent;
                    parent.ChildBones.Add(anim);
                }
            }            
            else if (_prop.PropertyType == typeof(Dictionary<string, SceneItem>))
            {

                Dictionary<string, SceneItem> dict = new Dictionary<string, SceneItem>();
                foreach (XmlNode vecnode in _newNode.ChildNodes)
                {
                    string type = vecnode.Attributes[0].InnerText;
                    XmlNode _itemNode = vecnode.ChildNodes[0];
                    SceneItem item = LoadSceneItem(_itemNode, _storedScene);
                    dict.Add(type, item);
                }
                _prop.SetValue(targetObject, dict, null);
            }
            else if (_prop.PropertyType == typeof(List<CompositeAnimation>))
            {
                List<CompositeAnimation> list = new List<CompositeAnimation>();
                foreach (XmlNode vecnode in _newNode.ChildNodes)
                {
                    CompositeAnimation anim = new CompositeAnimation();
                    anim.Parent = targetObject as CompositeEntity;
                    anim.Name = vecnode.Attributes["Name"].Value;
                    SetProperty("LerpLastFrameWithFirst", anim, vecnode);
                    SetProperty("Speed", anim, vecnode);
                    SetProperty("KeyFrames", anim, vecnode);
                    SetIAnimationProperties(vecnode, anim as IAnimation);
                    list.Add(anim);
                }

                _prop.SetValue(targetObject, list, null);
            }
            else if (_prop.PropertyType == typeof(List<CompositeKeyFrame>))
            {

                List<CompositeKeyFrame> list = new List<CompositeKeyFrame>();
                foreach (XmlNode vecnode in _newNode.ChildNodes)
                {
                    CompositeKeyFrame animKeyFrame = new CompositeKeyFrame();
                    animKeyFrame.Parent = targetObject as CompositeAnimation;
                    animKeyFrame.Name = vecnode.Attributes["Name"].Value;
                    animKeyFrame.Duration = int.Parse(vecnode.Attributes["Duration"].Value, CultureInfo.InvariantCulture);
                    //Bone transforms
                    XmlNode _boneTransNode = vecnode.SelectSingleNode("BoneTransforms");
                    foreach (XmlNode transNode in _boneTransNode.ChildNodes)
                    {
                        CompositeBoneTransform boneTransform = new CompositeBoneTransform();
                        boneTransform.Parent = animKeyFrame;
                        SetProperty("BoneReference", boneTransform, transNode);
                        SetProperty("SceneItem", boneTransform, transNode);
                        SetProperty("SubItem", boneTransform, transNode);
                        SetProperty("IsVisible", boneTransform, transNode, true);
                        SetProperty("Position", boneTransform, transNode, Vector2.Zero);
                        SetProperty("Rotation", boneTransform, transNode, 0);
                        SetProperty("Opacity", boneTransform, transNode);
                        SetProperty("Scale", boneTransform, transNode, Vector2.One);
                        SetProperty("InheritPosition", boneTransform, transNode);
                        SetProperty("InheritRotation", boneTransform, transNode);
                        SetProperty("InheritScale", boneTransform, transNode);
                        SetProperty("InheritVisibility", boneTransform, transNode);
                        SetProperty("FlipHorizontal", boneTransform, transNode);
                        SetProperty("FlipVertical", boneTransform, transNode);
                        animKeyFrame.AddCompositeBoneTransform(boneTransform);
                    }
                    list.Add(animKeyFrame);
                }

                _prop.SetValue(targetObject, list, null);
            }
            else if (_prop.PropertyType == typeof(List<AnimationFrame>))
            {

                List<AnimationFrame> listFrames = new List<AnimationFrame>();
                foreach (XmlNode vecnode in _newNode.ChildNodes)
                {
                    AnimationFrame frame = new AnimationFrame();
                    frame.Area = vecnode.Attributes["Area"].Value;
                    frame.Duration = int.Parse(vecnode.Attributes["Duration"].Value,
                        CultureInfo.InvariantCulture);
                    listFrames.Add(frame);
                }
                _prop.SetValue(targetObject, listFrames, null);
            }
            else if (_prop.PropertyType == typeof(LinearProperty))
            {
                LinearProperty lin = (LinearProperty)_prop.GetValue(targetObject, null);
                lin.Description = _newNode.SelectSingleNode("Description").InnerText;
                lin.LowerBound = int.Parse(_newNode.SelectSingleNode("LowerBound").InnerText, CultureInfo.InvariantCulture);
                lin.UpperBound = int.Parse(_newNode.SelectSingleNode("UpperBound").InnerText, CultureInfo.InvariantCulture);

                foreach (XmlNode item in _newNode.SelectSingleNode("Values").ChildNodes)
                {
                    lin.Values.Add(new Vector2(
                        float.Parse(item.SelectSingleNode("X").InnerText, CultureInfo.InvariantCulture),
                        float.Parse(item.SelectSingleNode("Y").InnerText, CultureInfo.InvariantCulture)));
                }
            }
            else
            {
                TraceLogger.TraceWarning("Not Set By SetProperty - " + p);
            }
        }
示例#19
0
 public CompositeBoneTransform GetBoneTransformFromKeyFrame(CompositeKeyFrame keyFrame, String boneReference)
 {
     foreach (CompositeBoneTransform boneTrans in keyFrame.BoneTransforms)
     {
         if (boneTrans.BoneReference == boneReference)
         {
             return boneTrans;
         }
     }
     throw new Exception("BoneReference \"" + boneReference
         + "\" not found in keyframe \"" + keyFrame.Name + "\"");
 }
 private void toolStripButtonAddKeyFrame_Click(object sender, EventArgs e)
 {
     CompositeAnimation anim = SelectedCompositeAnimation;
     CompositeKeyFrame newFrame = new CompositeKeyFrame(anim);
     if (SelectedCompositeKeyFrame != null)
     {
         SelectedCompositeKeyFrame.CopyValuesTo(newFrame, SelectedCompositeKeyFrame.Parent);
     }
     else
     {
         newFrame.GenerateDefaultBoneTransformsList();
     }
     anim.KeyFrames.Add(newFrame);
     RefreshListKeyFrames();
 }