/// <summary>
        /// Call twice; before and after changes
        /// </summary>
        public void VertexChange(List<Vertex3> vertices)
        {
            SaveState state = new SaveState();
            state._vertices = vertices;
            state._targetModel = TargetModel;
            state._translation = (Vector3)VertexLoc;

            if (before)
                AddUndo(state);
            else
                AddRedo(state);

            before = !before;
        }
        /// <summary>
        /// Call before and after making a modification to a bone's framestate.
        /// </summary>
        /// <param name="bone"></param>
        public void BoneChange(MDL0BoneNode bone)
        {
            SaveState state = new SaveState();
            state._bone = bone;
            state._frameState = bone._frameState;
            state._animation = SelectedCHR0;
            state._frameIndex = CurrentFrame;

            if (before)
                AddUndo(state);
            else
                AddRedo(state);

            before = !before;
        }
        private void CreateUndo()
        {
            CheckSaveIndex();
            if (undoSaves.Count > saveIndex)
            {
                undoSaves.RemoveRange(saveIndex, undoSaves.Count - saveIndex);
                redoSaves.Clear();
            }

            save = new SaveState();
            save._collisionLinks = new List<CollisionLink>();
            save._linkVectors = new List<Vector2>();

            foreach (CollisionLink l in _selectedLinks)
            { save._collisionLinks.Add(l); save._linkVectors.Add(l.Value); }

            undoSaves.Add(save);
            btnUndo.Enabled = true;
            saveIndex++;
            save = null;
        }
        private void Undo(object sender, EventArgs e)
        {
            _selectedLinks.Clear();

            save = new SaveState();

            if (undoSaves[saveIndex - 1]._linkVectors != null)     //XY Positions changed.
            {
                save._collisionLinks = new List<CollisionLink>();
                save._linkVectors = new List<Vector2>();

                for (int i = 0; i < undoSaves[saveIndex - 1]._collisionLinks.Count; i++)
                {
                    _selectedLinks.Add(undoSaves[saveIndex - 1]._collisionLinks[i]);
                    save._collisionLinks.Add(undoSaves[saveIndex - 1]._collisionLinks[i]);
                    save._linkVectors.Add(undoSaves[saveIndex - 1]._collisionLinks[i].Value);
                    _selectedLinks[i].Value = undoSaves[saveIndex - 1]._linkVectors[i];
                }
            }

            saveIndex--;
            CheckSaveIndex();

            if (saveIndex == 0)
            { btnUndo.Enabled = false; }
            btnRedo.Enabled = true;

            redoSaves.Add(save);
            save = null;

            _modelPanel.Invalidate();
            UpdatePropPanels();
        }
        private void AddUndo(SaveState save)
        {
            int i = _saveIndex + 1;
            if (_undoSaves.Count > i)
            {
                _undoSaves.RemoveRange(i, _undoSaves.Count - i);
                _redoSaves.RemoveRange(i, _redoSaves.Count - i);
            }

            _undoSaves.Add(save);
            _undoing = true;

            if (_undoSaves.Count > _allowedUndos)
            {
                _undoSaves.RemoveAt(0);
                _redoSaves.RemoveAt(0);
                _saveIndex--;
            }
        }
 private void AddRedo(SaveState save)
 {
     _redoSaves.Add(save);
     _saveIndex++;
     UpdateUndoButtons();
 }
 private void Apply(SaveState s)
 {
     if (s._frameState != null)
     {
         SelectedCHR0 = s._animation;
         CurrentFrame = s._frameIndex;
         SelectedBone = s._bone;
         chr0Editor.ApplyState(s);
     }
 }
        private void Apply(SaveState s)
        {
            if (s._frameState != null)
            {
                SelectedCHR0 = s._animation;
                CurrentFrame = s._frameIndex;
                SelectedBone = s._bone;
                chr0Editor.ApplyState(s);
            }
            else if (s._vertices != null)
            {
                if (TargetModel != s._targetModel)
                    TargetModel = s._targetModel;

                Vector3 diff = _redoSaves[_saveIndex]._translation - _undoSaves[_saveIndex]._translation;
                if (!_undoing) diff = -diff;
                foreach (Vertex3 v in s._vertices)
                {
                    v._weightedPosition -= diff;
                    v.Unweight();
                }
                UpdateModel();
            }
        }