public static void Perform(Node node, bool select = true) { if (node.Parent != Document.Current.Container) { throw new InvalidOperationException(); } if (select) { if (node is Bone && (node as Bone).Index != 0) { var bone = Document.Current.Container.Nodes.GetBone(((Bone)node).BaseIndex); while (bone != null) { SetProperty.Perform(bone.EditorState(), nameof(NodeEditorState.ChildrenExpanded), true); bone = Document.Current.Container.Nodes.GetBone(bone.BaseIndex); } } var rootFolder = Document.Current.Container.EditorState().RootFolder; var folder = rootFolder.Find(node).Folder; while (folder != null) { if (!folder.Expanded) { SetProperty.Perform(folder, nameof(Folder.Expanded), true); } folder = rootFolder.Find(folder).Folder; } } var row = Document.Current.GetRowForObject(node); SelectRow.Perform(row, select); }
public static void Perform(Node container, Marker marker, bool removeDependencies) { var previousMarker = container.Markers.GetByFrame(marker.Frame); DocumentHistory.Current.Perform(new SetMarker(container, marker, removeDependencies)); if (removeDependencies) { // Detect if a previous marker id is unique then rename it in triggers and markers. if (previousMarker != null && previousMarker.Id != marker.Id && container.Markers.All(markerEl => markerEl.Id != previousMarker.Id)) { foreach (var markerEl in container.Markers.ToList()) { if (markerEl.Action == MarkerAction.Jump && markerEl.JumpTo == previousMarker.Id) { SetProperty.Perform(markerEl, nameof(markerEl.JumpTo), marker.Id); } } ProcessAnimableProperty.Perform(container, nameof(Node.Trigger), (string value, out string newValue) => { return(TriggersValidation.TryRenameMarkerInTrigger( previousMarker.Id, marker.Id, value, out newValue )); } ); } } }
public static void Perform() { var doc = Document.Current; if (doc.Container == doc.RootNode) { var path = doc.SceneNavigatedFrom; if (path != null) { var document = Project.Current.Documents.FirstOrDefault(i => i.Path == path); if (document == null) { document = Project.Current.OpenDocument(path); } document.MakeCurrent(); } } else { var container = doc.Container; SetProperty.Perform(container, nameof(Node.TangerineFlags), container.TangerineFlags & ~TangerineFlags.DisplayContent, isChangingDocument: false); EnterNode.Perform(container.Parent, false); SelectNode.Perform(container, true); } }
public static void Perform(object @object, string propertyPath, object value, bool createAnimatorIfNeeded = false, bool createInitialKeyframeForNewAnimator = true, int atFrame = -1) { IAnimator animator; var animationHost = @object as IAnimationHost; object owner = @object; int index = -1; AnimationUtils.PropertyData propertyData = AnimationUtils.PropertyData.Empty; if (animationHost != null) { (propertyData, owner, index) = AnimationUtils.GetPropertyByPath(animationHost, propertyPath); } if (index == -1) { SetProperty.Perform(owner, propertyData.Info?.Name ?? propertyPath, value); } else { SetIndexedProperty.Perform(owner, propertyData.Info?.Name ?? propertyPath, index, value); } if (animationHost != null && (animationHost.Animators.TryFind(propertyPath, out animator, Document.Current.AnimationId) || createAnimatorIfNeeded)) { if (animator == null && createInitialKeyframeForNewAnimator) { var propertyValue = propertyData.Info.GetValue(owner); Perform(animationHost, propertyPath, propertyValue, true, false, 0); } int savedFrame = -1; if (atFrame >= 0 && Document.Current.AnimationFrame != atFrame) { savedFrame = Document.Current.AnimationFrame; Document.Current.AnimationFrame = atFrame; } try { var type = propertyData.Info.PropertyType; var key = animator?.ReadonlyKeys.GetByFrame(Document.Current.AnimationFrame)?.Clone() ?? Keyframe.CreateForType(type); key.Frame = Document.Current.AnimationFrame; key.Function = animator?.Keys.LastOrDefault(k => k.Frame <= key.Frame)?.Function ?? KeyFunction.Linear; key.Value = value; SetKeyframe.Perform(animationHost, propertyPath, Document.Current.AnimationId, key); } finally { if (savedFrame >= 0) { Document.Current.AnimationFrame = savedFrame; } } } }
public static void Perform(object obj, string propertyName, object value) { var animable = obj as IAnimable; IAnimator animator; if (animable != null && animable.Animators.TryFind(propertyName, out animator, Document.Current.AnimationId) && animator.ReadonlyKeys.Count > 0) { SetAnimableProperty.Perform(obj, propertyName, value); } else { SetProperty.Perform(obj, propertyName, value); } }
public static bool Perform(Node container, bool selectFirstNode = true) { if (!NodeCompositionValidator.CanHaveChildren(container.GetType())) { return(false); } if (!string.IsNullOrEmpty(container.ContentsPath) && Project.Current.DocumentExists(container.ContentsPath)) { OpenExternalScene(container.ContentsPath); } else { ChangeContainer(container, selectFirstNode); SetProperty.Perform(container, nameof(Node.TangerineFlags), container.TangerineFlags | TangerineFlags.DisplayContent, isChangingDocument: false); } return(true); }
public static void Perform(IEnumerable <Bone> bones, IEnumerable <Widget> widgets) { var boneList = bones.ToList(); if (!widgets.Any() || !bones.Any()) { return; } if (!CheckConsistency(bones, widgets)) { throw new InvalidOperationException("Not all bones and widgets have the same parent"); } foreach (var widget in widgets) { if (widget is DistortionMesh) { var mesh = widget as DistortionMesh; foreach (PointObject point in mesh.Nodes) { if (!CanApplyBone(point.SkinningWeights)) { throw new TieWidgetsWithBonesException(point); } SetProperty.Perform(point, nameof(PointObject.SkinningWeights), CalcSkinningWeight(point.SkinningWeights, point.CalcPositionInSpaceOf(widget.ParentWidget), boneList)); } } else { if (!CanApplyBone(widget.SkinningWeights)) { throw new TieWidgetsWithBonesException(widget); } SetProperty.Perform(widget, nameof(Widget.SkinningWeights), CalcSkinningWeight(widget.SkinningWeights, widget.Position, boneList)); } } foreach (var bone in bones) { var entry = bone.Parent.AsWidget.BoneArray[bone.Index]; SetAnimableProperty.Perform(bone, nameof(Bone.RefPosition), entry.Joint, CoreUserPreferences.Instance.AutoKeyframes); SetAnimableProperty.Perform(bone, nameof(Bone.RefLength), entry.Length, CoreUserPreferences.Instance.AutoKeyframes); SetAnimableProperty.Perform(bone, nameof(Bone.RefRotation), entry.Rotation, CoreUserPreferences.Instance.AutoKeyframes); } }
public static void Perform(object @object, string propertyName, object value) { SetProperty.Perform(@object, propertyName, value); IAnimator animator; var animable = @object as IAnimable; if (animable != null && animable.Animators.TryFind(propertyName, out animator, Document.Current.AnimationId)) { var type = animable.GetType().GetProperty(propertyName).PropertyType; var key = animator.ReadonlyKeys.FirstOrDefault(i => i.Frame == Document.Current.AnimationFrame)?.Clone() ?? Keyframe.CreateForType(type); key.Frame = Document.Current.AnimationFrame; key.Function = animator.Keys.LastOrDefault(k => k.Frame < key.Frame)?.Function ?? KeyFunction.Linear; key.Value = value; SetKeyframe.Perform(animable, propertyName, Document.Current.AnimationId, key); } }
private static void UntieBonesFromNode(Node node, string skinningPropertyName, IEnumerable <Bone> bones) { var property = node.GetType().GetProperty(skinningPropertyName); var originSkinningWeights = (SkinningWeights)property.GetValue(node); var boneIndices = new List <int>(); for (int i = 0; i < 4; i++) { if (bones.Any(b => b.Index == originSkinningWeights[i].Index)) { boneIndices.Add(i); } } if (boneIndices.Count != 0) { var skinningWeights = ResetSkinningWeights(boneIndices, originSkinningWeights); BakeSkinningTransform(skinningWeights, node); SetProperty.Perform(node, skinningPropertyName, skinningWeights); } }
public static void Perform <T>(object @object, string propertyPath, AnimablePropertyProcessor <T> propertyProcessor) { var propertyInfo = @object.GetType().GetProperty(propertyPath); if (propertyInfo != null) { var value = propertyInfo.GetValue(@object); if (value is T) { T processedValue; if (propertyProcessor((T)value, out processedValue)) { SetProperty.Perform(@object, propertyPath, processedValue); } } } IAnimator animator; var animable = @object as IAnimationHost; if (animable != null && animable.Animators.TryFind(propertyPath, out animator, Document.Current.AnimationId)) { foreach (var keyframe in animator.ReadonlyKeys.ToList()) { if (!(keyframe.Value is T)) { continue; } T processedValue; if (propertyProcessor((T)keyframe.Value, out processedValue)) { var keyframeClone = keyframe.Clone(); keyframeClone.Value = processedValue; SetKeyframe.Perform(animator, keyframeClone); } } } }
public static bool Perform(string data, RowLocation location) { if (!CanPaste(data, location)) { return(false); } Frame frame; try { var stream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(data)); frame = Serialization.ReadObject <Frame>(Document.Current.Path, stream); } catch (System.Exception e) { Debug.Write(e); return(false); } FolderItemLocation folderLocation; if (location.ParentRow.Rows.Count > 0) { folderLocation = Row.GetFolderItemLocation(location.ParentRow.Rows[location.Index]); folderLocation.Index++; } else { folderLocation = new FolderItemLocation { Index = 0, Folder = location.ParentRow.Components.Get <FolderRow>().Folder }; } if (!folderLocation.Folder.Expanded) { SetProperty.Perform(folderLocation.Folder, nameof(Folder.Expanded), true); } var items = frame.RootFolder().Items.ToList(); foreach (var n in items.OfType <Node>()) { Document.Current.Decorate(n); } frame.RootFolder().Items.Clear(); frame.RootFolder().SyncDescriptorsAndNodes(frame); ClearRowSelection.Perform(); while (items.Count > 0) { var item = items.First(); var bone = item as Bone; if (bone != null) { if (bone.BaseIndex != 0) { continue; } var newIndex = Document.Current.Container.Nodes.OfType <Bone>().Max(b => b.Index) + 1; var children = BoneUtils.FindBoneDescendats(bone, items.OfType <Bone>()).ToList(); var map = new Dictionary <int, int>(); map.Add(bone.Index, newIndex); bone.BaseIndex = location.ParentRow.Components.Get <BoneRow>()?.Bone.Index ?? 0; bone.Index = newIndex; InsertFolderItem.Perform( Document.Current.Container, folderLocation, bone); folderLocation.Index++; foreach (var b in children) { b.BaseIndex = map[b.BaseIndex]; map.Add(b.Index, b.Index = ++newIndex); InsertFolderItem.Perform( Document.Current.Container, folderLocation, b); folderLocation.Index++; items.Remove(b); } Document.Current.Container.RootFolder().SyncDescriptorsAndNodes(Document.Current.Container); SortBonesInChain.Perform(bone); SelectRow.Perform(Document.Current.GetRowForObject(item)); } else { if (!location.ParentRow.Components.Contains <BoneRow>()) { InsertFolderItem.Perform( Document.Current.Container, folderLocation, item); folderLocation.Index++; SelectRow.Perform(Document.Current.GetRowForObject(item)); } } items.Remove(item); } return(true); }
public static bool PasteNodes(string data, RowLocation location, Vector2?mousePosition) { bool CanPaste() { // We are support only paste into folders for now. return(location.ParentRow.Components.Contains <FolderRow>() || location.ParentRow.Components.Contains <BoneRow>()); } if (!CanPaste()) { return(false); } Frame frame; try { var stream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(data)); frame = TangerinePersistence.Instance.ReadObject <Frame>(Document.Current.Path, stream); } catch (System.Exception e) { Debug.Write(e); return(false); } var animators = frame.Animators; var items = frame.RootFolder().Items.Where(item => NodeCompositionValidator.IsCopyPasteAllowed(item.GetType())).ToList(); if (items.Count == 0) { if (animators.Count != 0) { foreach (var row in Document.Current.TopLevelSelectedRows().ToList()) { if (!(row.Components.Get <NodeRow>()?.Node is IAnimationHost animable)) { continue; } Document.Current.History.DoTransaction(() => { foreach (var animator in animators) { if (animable.GetType().GetProperty(animator.TargetPropertyPath) == null) { continue; } foreach (var keyframe in animator.Keys) { SetKeyframe.Perform(animable, animator.TargetPropertyPath, animator.AnimationId, keyframe); } } }); } } return(true); } var folderLocation = location.ParentRow.Rows.Count > 0 ? Row.GetFolderItemLocation(location.ParentRow.Rows[location.Index]) : new FolderItemLocation { Index = 0, Folder = location.ParentRow.Components.Get <FolderRow>().Folder }; if (!folderLocation.Folder.Expanded) { SetProperty.Perform(folderLocation.Folder, nameof(Folder.Expanded), true); } mousePosition *= Document.Current.Container.AsWidget?.LocalToWorldTransform.CalcInversed(); var shift = mousePosition - items.OfType <Widget>().FirstOrDefault()?.Position; foreach (var n in items.OfType <Node>()) { Document.Current.Decorate(n); } if (shift.HasValue) { foreach (var w in items.OfType <Widget>()) { w.Position += shift.Value; } } frame.RootFolder().Items.Clear(); frame.RootFolder().SyncDescriptorsAndNodes(frame); ClearRowSelection.Perform(); while (items.Count > 0) { var item = items.First(); if (item is Bone bone) { if (bone.BaseIndex != 0) { continue; } var newIndex = 1; var bones = Document.Current.Container.Nodes.OfType <Bone>(); if (bones.Any()) { newIndex = bones.Max(b => b.Index) + 1; } var children = BoneUtils.FindBoneDescendats(bone, items.OfType <Bone>()).ToList(); var map = new Dictionary <int, int> { { bone.Index, newIndex } }; bone.BaseIndex = location.ParentRow.Components.Get <BoneRow>()?.Bone.Index ?? 0; bone.Index = newIndex; InsertFolderItem.Perform( Document.Current.Container, folderLocation, bone); folderLocation.Index++; foreach (var b in children) { b.BaseIndex = map[b.BaseIndex]; map.Add(b.Index, b.Index = ++newIndex); InsertFolderItem.Perform( Document.Current.Container, folderLocation, b); folderLocation.Index++; items.Remove(b); } Document.Current.Container.RootFolder().SyncDescriptorsAndNodes(Document.Current.Container); SortBonesInChain.Perform(bone); SelectRow.Perform(Document.Current.GetRowForObject(item)); } else { if (!location.ParentRow.Components.Contains <BoneRow>()) { InsertFolderItem.Perform( Document.Current.Container, folderLocation, item); folderLocation.Index++; SelectRow.Perform(Document.Current.GetRowForObject(item)); } } items.Remove(item); } return(true); }