private void SelectCopiedElements(VFXView view, VFXGroupNodeController groupNode) { view.ClearSelection(); var elements = view.graphElements.ToList(); newNodesUI.Clear(); newContextUIs.Clear(); FindContextUIsAndSelect(view, elements); FindOperatorsUIsAndSelect(view, elements); FindParameterUIsAndSelect(view, elements); SelectEdges(view, elements); //Select all groups that are new SelectGroupNodes(view, elements); // Add all copied element that are not in a copied groupNode to the potentially selected groupnode if (groupNode != null) { foreach (var newSlotContainerUI in newNodesUI) { groupNode.AddNode(newSlotContainerUI.controller); } } SelectStickyNotes(view, elements); }
public void CopyPasteBlock() { var initContextDesc = VFXLibrary.GetContexts().Where(t => t.name == "Initialize").First(); var newContext = m_ViewController.AddVFXContext(new Vector2(100, 100), initContextDesc); m_ViewController.ApplyChanges(); Assert.AreEqual(m_ViewController.allChildren.Where(t => t is VFXContextController).Count(), 1); var contextController = m_ViewController.allChildren.OfType <VFXContextController>().First(); Assert.AreEqual(contextController.model, newContext); var flipBookBlockDesc = VFXLibrary.GetBlocks().First(t => t.name == "Set Tex Index "); contextController.AddBlock(0, flipBookBlockDesc.CreateInstance()); var newBlock = contextController.model.children.First(); m_ViewController.ApplyChanges(); VFXViewWindow window = EditorWindow.GetWindow <VFXViewWindow>(); VFXView view = window.graphView; view.controller = m_ViewController; view.ClearSelection(); foreach (var element in view.Query().OfType <VFXBlockUI>().ToList().OfType <ISelectable>()) { view.AddToSelection(element); } VFXBlock flipBookBlock = m_ViewController.contexts.First().blockControllers.First().model; VFXSlot minValueSlot = flipBookBlock.GetInputSlot(0); float originalMinValue = 123.456f; minValueSlot.value = originalMinValue; view.CopySelectionCallback(); minValueSlot.value = 789f; view.PasteCallback(); view.controller.ApplyChanges(); var elements = view.Query().OfType <VFXBlockUI>().ToList(); var copyBlock = elements.Select(t => t.controller).First(t => t.model != newBlock).model; var copyMinSlot = copyBlock.GetInputSlot(0); Assert.AreEqual((float)copyMinSlot.value, originalMinValue); }
public void CopyPasteOperator() { var crossOperatorDesc = VFXLibrary.GetOperators().Where(t => t.name == "Cross Product").First(); var newOperator = m_ViewController.AddVFXOperator(new Vector2(100, 100), crossOperatorDesc); m_ViewController.ApplyChanges(); var operatorController = m_ViewController.allChildren.OfType <VFXOperatorController>().First(); Assert.AreEqual(operatorController.model, newOperator); VFXViewWindow window = EditorWindow.GetWindow <VFXViewWindow>(); VFXView view = window.graphView; view.controller = m_ViewController; view.ClearSelection(); foreach (var element in view.Query().OfType <GraphElement>().ToList().OfType <ISelectable>()) { view.AddToSelection(element); } VFXSlot aSlot = newOperator.GetInputSlot(0); Vector3 originalA = Vector3.one * 123; aSlot.value = originalA; view.CopySelectionCallback(); aSlot.value = Vector3.one * 456; view.PasteCallback(); var elements = view.Query().OfType <GraphElement>().ToList(); var copyOperator = elements.OfType <VFXOperatorUI>().First(t => t.controller.model != newOperator); var copaASlot = copyOperator.controller.model.GetInputSlot(0); Assert.AreEqual((Vector3)copaASlot.value, originalA); Assert.AreNotEqual(copyOperator.controller.model.position, newOperator.position); view.PasteCallback(); elements = view.Query().OfType <GraphElement>().ToList(); var copy2Operator = elements.OfType <VFXOperatorUI>().First(t => t.controller.model != newOperator && t != copyOperator); Assert.AreNotEqual(copy2Operator.controller.model.position, newOperator.position); Assert.AreNotEqual(copy2Operator.controller.model.position, copyOperator.controller.model.position); }
void PasteBlocks(VFXView view, ref SerializableGraph serializableGraph, List <VFXNodeController> nodesInTheSameOrder) { var selectedContexts = view.selection.OfType <VFXContextUI>(); var selectedBlocks = view.selection.OfType <VFXBlockUI>(); VFXBlockUI targetBlock = null; VFXContextUI targetContext = null; if (selectedBlocks.Count() > 0) { targetBlock = selectedBlocks.OrderByDescending(t => t.context.controller.model.GetIndex(t.controller.model)).First(); targetContext = targetBlock.context; } else if (selectedContexts.Count() == 1) { targetContext = selectedContexts.First(); } else { Debug.LogError(m_BlockPasteError.text); return; } VFXContext targetModelContext = targetContext.controller.model; int targetIndex = -1; if (targetBlock != null) { targetIndex = targetModelContext.GetIndex(targetBlock.controller.model) + 1; } List <VFXBlockController> blockControllers = nodesInTheSameOrder != null ? new List <VFXBlockController>() : null; targetIndex = PasteBlocks(view.controller, serializableGraph.operators, targetModelContext, targetIndex, blockControllers); if (nodesInTheSameOrder != null) { nodesInTheSameOrder.AddRange(blockControllers.Cast <VFXNodeController>()); } targetModelContext.Invalidate(VFXModel.InvalidationCause.kStructureChanged); if (view != null) { view.ClearSelection(); foreach (var uiBlock in targetContext.Query().OfType <VFXBlockUI>().Where(t => m_NodesInTheSameOrder.Any(u => u.model == t.controller.model)).ToList()) { view.AddToSelection(uiBlock); } } }
public void CopyPasteSpacableOperator() { var inlineOperatorDesc = VFXLibrary.GetOperators().Where(t => t.modelType == typeof(VFXInlineOperator)).First(); var newOperator = m_ViewController.AddVFXOperator(new Vector2(100, 100), inlineOperatorDesc); newOperator.SetSettingValue("m_Type", new SerializableType(typeof(DirectionType))); m_ViewController.ApplyChanges(); var operatorController = m_ViewController.allChildren.OfType <VFXOperatorController>().First(); Assert.AreEqual(operatorController.model, newOperator); VFXViewWindow window = EditorWindow.GetWindow <VFXViewWindow>(); VFXView view = window.graphView; view.controller = m_ViewController; view.ClearSelection(); foreach (var element in view.Query().OfType <GraphElement>().ToList().OfType <ISelectable>()) { view.AddToSelection(element); } VFXSlot aSlot = newOperator.GetInputSlot(0); Assert.IsTrue(aSlot.spaceable); aSlot.space = VFXCoordinateSpace.World; string copyData = view.SerializeElements(view.selection.OfType <GraphElement>()); aSlot.space = VFXCoordinateSpace.Local; view.UnserializeAndPasteElements("paste", copyData); var elements = view.Query().OfType <GraphElement>().ToList(); var copyOperator = elements.OfType <VFXOperatorUI>().First(t => t.controller.model != newOperator); var copyASlot = copyOperator.controller.model.GetInputSlot(0); Assert.AreEqual(VFXCoordinateSpace.World, copyASlot.space); }
public void PasteSystems() { VFXViewWindow window = EditorWindow.GetWindow <VFXViewWindow>(); VFXView view = window.graphView; view.controller = m_ViewController; // Create a bunch of systems const int spawnerCount = 4, GPUSystemsCount = 4; var spawners = VFXTestCommon.CreateSpawners(view, m_ViewController, spawnerCount); VFXTestCommon.CreateSystems(view, m_ViewController, GPUSystemsCount, 0); // Copy paste them view.ClearSelection(); foreach (var element in view.Query().OfType <GraphElement>().ToList().OfType <ISelectable>()) { view.AddToSelection(element); } view.CopySelectionCallback(); view.PasteCallback(); // Query unique names var systemNames = view.controller.graph.systemNames; var uniqueNames = new List <string>(); foreach (var system in spawners) { uniqueNames.Add(systemNames.GetUniqueSystemName(system)); } var GPUSystems = VFXTestCommon.GetFieldValue <VFXView, List <VFXSystemBorder> >(view, "m_Systems"); uniqueNames = uniqueNames.Concat(GPUSystems.Select(system => system.controller.title)).ToList(); // Remove null or empty names, and duplicates uniqueNames = uniqueNames.Where(name => !string.IsNullOrEmpty(name)).Distinct().ToList(); // Assert all names are unique, and the expected number of elements was obtained Assert.IsTrue(uniqueNames.Count() == spawnerCount + GPUSystemsCount, "Some systems have the same name or are null or empty."); }
public IEnumerator CopyPast_Context_And_Relink([ValueSource("cutBeforeSource")] CutBefore cutBeforeEncapsultor) { VFXTaskType curBeforeSource = cutBeforeEncapsultor.taskType; EditorApplication.ExecuteMenuItem("Window/General/Game"); var graph = MakeTemporaryGraph(); var spawnerContext = ScriptableObject.CreateInstance <VFXBasicSpawner>(); var basicInitialize = ScriptableObject.CreateInstance <VFXBasicInitialize>(); var basicUpdate = ScriptableObject.CreateInstance <VFXBasicUpdate>(); var quadOutput = ScriptableObject.CreateInstance <VFXQuadOutput>(); var arrayOfContext = new VFXContext[] { spawnerContext, basicInitialize, basicUpdate, quadOutput }; quadOutput.SetSettingValue("blendMode", VFXAbstractParticleOutput.BlendMode.Additive); var setPosition = ScriptableObject.CreateInstance <SetAttribute>(); //only needed to allocate a minimal attributeBuffer setPosition.SetSettingValue("attribute", "position"); basicInitialize.AddChild(setPosition); var capacity = 2u; //(basicInitialize.GetData() as VFXDataParticle).capacity = capacity; //voluntary overflow in case of capacity is not correctly copied basicInitialize.SetSettingValue("capacity", 2u); // pass through regular way to change capacity to have initialize and data up to date var spawnerBurst = ScriptableObject.CreateInstance <VFXSpawnerBurst>(); spawnerBurst.inputSlots[0].value = 4.0f; spawnerContext.AddChild(spawnerBurst); graph.AddChild(spawnerContext); graph.AddChild(basicInitialize); graph.AddChild(basicUpdate); graph.AddChild(quadOutput); basicInitialize.LinkFrom(spawnerContext); basicUpdate.LinkFrom(basicInitialize); quadOutput.LinkFrom(basicUpdate); m_ViewController.NotifyUpdate(); Assert.AreEqual(4, m_View.GetAllContexts().Count()); //Copy partially in two passes var indexOffset = cutBeforeSource.Select((o, i) => new { o = o, i = i }).Where(o => o.o.taskType == curBeforeSource).Select(o => o.i).First(); var contextToCopy_A = arrayOfContext.Skip(indexOffset).Select(o => m_View.GetAllContexts().Where(u => u.controller.model == o).First() as UnityEditor.Experimental.GraphView.GraphElement); foreach (var graphElement in contextToCopy_A) { m_View.AddToSelection(graphElement); } m_View.DuplicateSelectionCallback(); m_View.ClearSelection(); m_ViewController.NotifyUpdate(); if (indexOffset > 0) { var contextToCopy_B = arrayOfContext.Take(indexOffset).Select(o => m_View.GetAllContexts().Where(u => u.controller.model == o).First() as UnityEditor.Experimental.GraphView.GraphElement); foreach (var graphElement in contextToCopy_B) { m_View.AddToSelection(graphElement); } m_View.DuplicateSelectionCallback(); m_View.ClearSelection(); } m_ViewController.NotifyUpdate(); Assert.AreEqual(8, m_View.GetAllContexts().Count()); //Restore missing link var allContext = m_View.GetAllContexts().Select(o => o.controller.model).ToArray(); if (indexOffset > 0) { var from = allContext.Last(); var to = allContext[4]; to.LinkFrom(from); } VFXBasicInitialize[] initializes = graph.children.OfType <VFXBasicInitialize>().ToArray(); Assert.AreEqual(2, initializes.Length); Assert.AreEqual(2, (initializes[0].GetData() as VFXDataParticle).capacity); Assert.AreEqual(2, (initializes[1].GetData() as VFXDataParticle).capacity); Assert.AreEqual(2, initializes[0].GetType().GetField("capacity", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(initializes[0])); Assert.AreEqual(2, initializes[1].GetType().GetField("capacity", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(initializes[1])); graph.RecompileIfNeeded(); var gameObj = new GameObject("CreateAssetAndComponentToCopyPastPerfomedWell"); var vfxComponent = gameObj.AddComponent <VisualEffect>(); vfxComponent.visualEffectAsset = graph.visualEffectResource.asset; var cameraObj = new GameObject("CreateAssetAndComponentToCopyPastPerfomedWell_Camera"); var camera = cameraObj.AddComponent <Camera>(); camera.transform.localPosition = Vector3.one; camera.transform.LookAt(vfxComponent.transform); int maxFrame = 512; while (vfxComponent.culled && --maxFrame > 0) { yield return(null); } Assert.IsTrue(maxFrame > 0); yield return(null); //wait for exactly one more update if visible Assert.AreEqual(capacity * 2, vfxComponent.aliveParticleCount); //Excepted to have two viable equivalent particles system UnityEngine.Object.DestroyImmediate(vfxComponent); UnityEngine.Object.DestroyImmediate(cameraObj); }
static void PasteNodes(VFXViewController viewController, Vector2 center, Data copyData, ScriptableObject[] allSerializedObjects, VFXView view, VFXGroupNodeController groupNode) { var graph = viewController.graph; Vector2 pasteOffset = (copyData.bounds.width > 0 && copyData.bounds.height > 0) ? center - copyData.bounds.center : Vector2.zero; // look if pasting there will result in the first element beeing exactly on top of other while (true) { bool foundSamePosition = false; if (copyData.contexts != null && copyData.contexts.Length > 0) { VFXContext firstContext = copyData.contexts[0]; foreach (var existingContext in viewController.graph.children.OfType <VFXContext>()) { if ((firstContext.position + pasteOffset - existingContext.position).sqrMagnitude < 1) { foundSamePosition = true; break; } } } else if (copyData.slotContainers != null && copyData.slotContainers.Length > 0) { VFXModel firstContainer = copyData.slotContainers[0]; foreach (var existingSlotContainer in viewController.graph.children.Where(t => t is IVFXSlotContainer)) { if ((firstContainer.position + pasteOffset - existingSlotContainer.position).sqrMagnitude < 1) { foundSamePosition = true; break; } } } else { VFXUI ui = allSerializedObjects.OfType <VFXUI>().First(); if (ui != null) { if (ui.stickyNoteInfos != null && ui.stickyNoteInfos.Length > 0) { foreach (var stickyNote in viewController.stickyNotes) { if ((ui.stickyNoteInfos[0].position.position + pasteOffset - stickyNote.position.position).sqrMagnitude < 1) { foundSamePosition = true; break; } } } else if (ui.groupInfos != null && ui.groupInfos.Length > 0) { foreach (var gn in viewController.groupNodes) { if ((ui.groupInfos[0].position.position + pasteOffset - gn.position.position).sqrMagnitude < 1) { foundSamePosition = true; break; } } } } } if (foundSamePosition) { pasteOffset += Vector2.one * 30; } else { break; } } if (copyData.contexts != null) { foreach (var slotContainer in copyData.contexts) { var newContext = slotContainer; newContext.position += pasteOffset; ClearLinks(newContext); } } if (copyData.slotContainers != null) { foreach (var slotContainer in copyData.slotContainers) { var newSlotContainer = slotContainer; newSlotContainer.position += pasteOffset; ClearLinks(newSlotContainer as IVFXSlotContainer); } } for (int i = 0; i < allSerializedObjects.Length; ++i) { ScriptableObject obj = allSerializedObjects[i]; if (obj is VFXContext || obj is VFXOperator) { graph.AddChild(obj as VFXModel); } else if (obj is VFXParameter) { int paramIndex = System.Array.FindIndex(copyData.parameters, t => t.index == i); VFXParameter existingParameter = graph.children.OfType <VFXParameter>().FirstOrDefault(t => t.GetInstanceID() == copyData.parameters[paramIndex].originalInstanceID); if (existingParameter != null) { // The original parameter is from the current graph, add the nodes to the original copyData.parameters[paramIndex].parameter = existingParameter; copyData.parameters[paramIndex].copiedParameter = obj as VFXParameter; copyData.parameters[paramIndex].infoIndexOffset = existingParameter.nodes.Count; foreach (var info in copyData.parameters[paramIndex].infos) { info.position += pasteOffset; } var oldIDs = copyData.parameters[paramIndex].infos.ToDictionary(t => t, t => t.id); existingParameter.AddNodeRange(copyData.parameters[paramIndex].infos); //keep track of new ids for groupnodes copyData.parameters[paramIndex].idMap = copyData.parameters[paramIndex].infos.ToDictionary(t => oldIDs[t], t => t.id); } else { // The original parameter is from another graph : create the parameter in the other graph, but replace the infos with only the ones copied. copyData.parameters[paramIndex].parameter = obj as VFXParameter; copyData.parameters[paramIndex].parameter.SetNodes(copyData.parameters[paramIndex].infos); graph.AddChild(obj as VFXModel); } } } VFXUI copiedUI = allSerializedObjects.OfType <VFXUI>().FirstOrDefault(); int firstCopiedGroup = -1; int firstCopiedStickyNote = -1; if (copiedUI != null) { VFXUI ui = viewController.graph.UIInfos; firstCopiedStickyNote = ui.stickyNoteInfos != null ? ui.stickyNoteInfos.Length : 0; if (copiedUI.groupInfos != null && copiedUI.groupInfos.Length > 0) { if (ui.groupInfos == null) { ui.groupInfos = new VFXUI.GroupInfo[0]; } firstCopiedGroup = ui.groupInfos.Length; foreach (var groupInfos in copiedUI.groupInfos) { for (int i = 0; i < groupInfos.contents.Length; ++i) { // if we link the parameter node to an existing parameter instead of the copied parameter we have to patch the groupnode content to point the that parameter with the correct id. if (groupInfos.contents[i].model is VFXParameter) { VFXParameter parameter = groupInfos.contents[i].model as VFXParameter; var paramInfo = copyData.parameters.FirstOrDefault(t => t.copiedParameter == parameter); if (paramInfo.parameter != null) // parameter will not be null unless the struct returned is the default. { groupInfos.contents[i].model = paramInfo.parameter; groupInfos.contents[i].id = paramInfo.idMap[groupInfos.contents[i].id]; } } else if (groupInfos.contents[i].isStickyNote) { groupInfos.contents[i].id += firstCopiedStickyNote; } } } ui.groupInfos = ui.groupInfos.Concat(copiedUI.groupInfos.Select(t => new VFXUI.GroupInfo(t) { position = new Rect(t.position.position + pasteOffset, t.position.size) })).ToArray(); } if (copiedUI.stickyNoteInfos != null && copiedUI.stickyNoteInfos.Length > 0) { if (ui.stickyNoteInfos == null) { ui.stickyNoteInfos = new VFXUI.StickyNoteInfo[0]; } ui.stickyNoteInfos = ui.stickyNoteInfos.Concat(copiedUI.stickyNoteInfos.Select(t => new VFXUI.StickyNoteInfo(t) { position = new Rect(t.position.position + pasteOffset, t.position.size) })).ToArray(); } } CopyDataEdges(copyData, allSerializedObjects); if (copyData.flowEdges != null) { foreach (var flowEdge in copyData.flowEdges) { VFXContext inputContext = allSerializedObjects[flowEdge.input.contextIndex] as VFXContext; VFXContext outputContext = allSerializedObjects[flowEdge.output.contextIndex] as VFXContext; inputContext.LinkFrom(outputContext, flowEdge.input.flowIndex, flowEdge.output.flowIndex); } } foreach (var dataAndContexts in copyData.dataAndContexts) { VFXData data = allSerializedObjects[dataAndContexts.dataIndex] as VFXData; foreach (var contextIndex in dataAndContexts.contextsIndexes) { VFXContext context = allSerializedObjects[contextIndex] as VFXContext; data.CopySettings(context.GetData()); } } // Create all ui based on model viewController.LightApplyChanges(); if (view != null) { view.ClearSelection(); var elements = view.graphElements.ToList(); List <VFXNodeUI> newSlotContainerUIs = new List <VFXNodeUI>(); List <VFXContextUI> newContextUIs = new List <VFXContextUI>(); foreach (var slotContainer in allSerializedObjects.OfType <VFXContext>()) { VFXContextUI contextUI = elements.OfType <VFXContextUI>().FirstOrDefault(t => t.controller.model == slotContainer); if (contextUI != null) { newSlotContainerUIs.Add(contextUI); newSlotContainerUIs.AddRange(contextUI.GetAllBlocks().Cast <VFXNodeUI>()); newContextUIs.Add(contextUI); view.AddToSelection(contextUI); } } foreach (var slotContainer in allSerializedObjects.OfType <VFXOperator>()) { VFXOperatorUI slotContainerUI = elements.OfType <VFXOperatorUI>().FirstOrDefault(t => t.controller.model == slotContainer); if (slotContainerUI != null) { newSlotContainerUIs.Add(slotContainerUI); view.AddToSelection(slotContainerUI); } } foreach (var param in copyData.parameters) { foreach (var parameterUI in elements.OfType <VFXParameterUI>().Where(t => t.controller.model == param.parameter && param.parameter.nodes.IndexOf(t.controller.infos) >= param.infoIndexOffset)) { newSlotContainerUIs.Add(parameterUI); view.AddToSelection(parameterUI); } } // Simply selected all data edge with the context or slot container, they can be no other than the copied ones foreach (var dataEdge in elements.OfType <VFXDataEdge>()) { if (newSlotContainerUIs.Contains(dataEdge.input.GetFirstAncestorOfType <VFXNodeUI>())) { view.AddToSelection(dataEdge); } } // Simply selected all data edge with the context or slot container, they can be no other than the copied ones foreach (var flowEdge in elements.OfType <VFXFlowEdge>()) { if (newContextUIs.Contains(flowEdge.input.GetFirstAncestorOfType <VFXContextUI>())) { view.AddToSelection(flowEdge); } } if (groupNode != null) { foreach (var newSlotContainerUI in newSlotContainerUIs) { groupNode.AddNode(newSlotContainerUI.controller); } } //Select all groups that are new if (firstCopiedGroup >= 0) { foreach (var gn in elements.OfType <VFXGroupNode>()) { if (gn.controller.index >= firstCopiedGroup) { view.AddToSelection(gn); } } } //Select all groups that are new if (firstCopiedStickyNote >= 0) { foreach (var gn in elements.OfType <VFXStickyNote>()) { if (gn.controller.index >= firstCopiedStickyNote) { view.AddToSelection(gn); } } } } }
static void PasteBlocks(VFXView view, Data copyData) { var selectedContexts = view.selection.OfType <VFXContextUI>(); var selectedBlocks = view.selection.OfType <VFXBlockUI>(); VFXBlockUI targetBlock = null; VFXContextUI targetContext = null; if (selectedBlocks.Count() > 0) { targetBlock = selectedBlocks.OrderByDescending(t => t.context.controller.model.GetIndex(t.controller.model)).First(); targetContext = targetBlock.context; } else if (selectedContexts.Count() == 1) { targetContext = selectedContexts.First(); } else { Debug.LogError(m_BlockPasteError.text); return; } VFXContext targetModelContext = targetContext.controller.model; int targetIndex = -1; if (targetBlock != null) { targetIndex = targetModelContext.GetIndex(targetBlock.controller.model) + 1; } var newBlocks = new HashSet <VFXBlock>(); foreach (var block in copyData.blocks) { if (targetModelContext.AcceptChild(block, targetIndex)) { newBlocks.Add(block); foreach (var slot in block.inputSlots) { slot.UnlinkAll(true, false); } foreach (var slot in block.outputSlots) { slot.UnlinkAll(true, false); } targetModelContext.AddChild(block, targetIndex, false); // only notify once after all blocks have been added } } targetModelContext.Invalidate(VFXModel.InvalidationCause.kStructureChanged); // Create all ui based on model view.controller.LightApplyChanges(); view.ClearSelection(); foreach (var uiBlock in targetContext.Query().OfType <VFXBlockUI>().Where(t => newBlocks.Contains(t.controller.model)).ToList()) { view.AddToSelection(uiBlock); } }
public void CopyPasteContextWithBlock() { var initContextDesc = VFXLibrary.GetContexts().Where(t => t.name == "Initialize").First(); var newContext = m_ViewController.AddVFXContext(new Vector2(100, 100), initContextDesc); m_ViewController.ApplyChanges(); Assert.AreEqual(m_ViewController.allChildren.Where(t => t is VFXContextController).Count(), 1); var contextController = m_ViewController.allChildren.OfType <VFXContextController>().First(); Assert.AreEqual(contextController.model, newContext); var flipBookBlockDesc = VFXLibrary.GetBlocks().First(t => t.name == "Set Tex Index "); contextController.AddBlock(0, flipBookBlockDesc.CreateInstance()); m_ViewController.ApplyChanges(); VFXViewWindow window = EditorWindow.GetWindow <VFXViewWindow>(); VFXView view = window.graphView; view.controller = m_ViewController; view.ClearSelection(); foreach (var element in view.Query().OfType <GraphElement>().ToList().OfType <ISelectable>()) { view.AddToSelection(element); } VFXSlot boundsSlot = newContext.GetInputSlot(0); AABox originalBounds = new AABox() { center = Vector3.one, size = Vector3.one * 10 }; boundsSlot.value = originalBounds; VFXBlock flipBookBlock = m_ViewController.contexts.First().blockControllers.First().model; VFXSlot minValueSlot = flipBookBlock.GetInputSlot(0); float originalMinValue = 123.456f; minValueSlot.value = originalMinValue; view.CopySelectionCallback(); boundsSlot.value = new AABox() { center = Vector3.zero, size = Vector3.zero }; minValueSlot.value = 789f; view.PasteCallback(); var elements = view.Query().OfType <GraphElement>().ToList(); var contexts = elements.OfType <VFXContextUI>().ToArray(); var copyContext = elements.OfType <VFXContextUI>().Select(t => t.controller).First(t => t.model != newContext).model; var copyBoundsSlot = copyContext.GetInputSlot(0); var copyMinSlot = copyContext[0].GetInputSlot(0); Assert.AreEqual((AABox)copyBoundsSlot.value, originalBounds); Assert.AreEqual((float)copyMinSlot.value, originalMinValue); Assert.AreNotEqual(copyContext.position, newContext.position); view.PasteCallback(); elements = view.Query().OfType <GraphElement>().ToList(); contexts = elements.OfType <VFXContextUI>().ToArray(); var copy2Context = contexts.First(t => t.controller.model != newContext && t.controller.model != copyContext).controller.model; Assert.AreNotEqual(copy2Context.position, newContext.position); Assert.AreNotEqual(copy2Context.position, copyContext.position); }
public void CopyPasteEdges() { VisualEffectAsset asset = AssetDatabase.LoadAssetAtPath <VisualEffectAsset>("Assets/AllTests/Editor/Tests/CopyPasteTest.vfx"); VFXViewController controller = VFXViewController.GetController(asset.GetResource(), true); VFXViewWindow window = EditorWindow.GetWindow <VFXViewWindow>(); VFXView view = window.graphView; view.controller = controller; view.ClearSelection(); var originalElements = view.Query().OfType <GraphElement>().ToList().OfType <ISelectable>().ToArray(); Assert.AreNotEqual(originalElements.Length, 0); foreach (var element in originalElements) { view.AddToSelection(element); } view.CopySelectionCallback(); view.controller = m_ViewController; view.PasteCallback(); m_ViewController.ApplyChanges(); VFXParameterUI[] parameters = view.Query().OfType <VFXParameterUI>().ToList().ToArray(); Assert.AreEqual(parameters.Length, 2); if (parameters[0].title == "Vector3") { var tmp = parameters[0]; parameters[0] = parameters[1]; parameters[1] = tmp; } VFXOperatorUI[] operators = view.Query().OfType <VFXOperatorUI>().ToList().ToArray(); Assert.AreEqual(operators.Length, 2); VFXContextUI[] contexts = view.Query().OfType <VFXContextUI>().ToList().ToArray(); Assert.AreEqual(contexts.Length, 2); if (contexts[0].controller.model is VFXBasicUpdate) { var tmp = contexts[0]; contexts[0] = contexts[1]; contexts[1] = tmp; } VFXDataEdge[] dataEdges = view.Query().OfType <VFXDataEdge>().ToList().ToArray(); Assert.AreEqual(dataEdges.Length, 4); Assert.IsNotNull(dataEdges.Where(t => t.output.GetFirstAncestorOfType <VFXNodeUI>() == parameters[1] && operators.Contains(t.input.GetFirstAncestorOfType <VFXOperatorUI>()) ).FirstOrDefault()); Assert.IsNotNull(dataEdges.Where(t => operators.Contains(t.input.GetFirstAncestorOfType <VFXOperatorUI>()) && operators.Contains(t.output.GetFirstAncestorOfType <VFXOperatorUI>()) && t.output.GetFirstAncestorOfType <VFXNodeUI>() != t.input.GetFirstAncestorOfType <VFXNodeUI>() ).FirstOrDefault()); Assert.IsNotNull(dataEdges.Where(t => t.output.GetFirstAncestorOfType <VFXNodeUI>() == parameters[0] && t.input.GetFirstAncestorOfType <VFXNodeUI>() == contexts[0] ).FirstOrDefault()); Assert.IsNotNull(dataEdges.Where(t => operators.Contains(t.output.GetFirstAncestorOfType <VFXNodeUI>()) && t.input.GetFirstAncestorOfType <VFXNodeUI>() == contexts[0].GetAllBlocks().First() ).FirstOrDefault()); VFXFlowEdge flowEdge = view.Query().OfType <VFXFlowEdge>(); Assert.IsNotNull(flowEdge); Assert.AreEqual(flowEdge.output.GetFirstAncestorOfType <VFXContextUI>(), contexts[1]); Assert.AreEqual(flowEdge.input.GetFirstAncestorOfType <VFXContextUI>(), contexts[0]); }
void SelectAll() { m_View.ClearSelection(); this.Query <BlackboardField>().ForEach(t => m_View.AddToSelection(t)); }
void PasteBlocks(VFXView view, ref SerializableGraph serializableGraph) { var selectedContexts = view.selection.OfType <VFXContextUI>(); var selectedBlocks = view.selection.OfType <VFXBlockUI>(); VFXBlockUI targetBlock = null; VFXContextUI targetContext = null; if (selectedBlocks.Count() > 0) { targetBlock = selectedBlocks.OrderByDescending(t => t.context.controller.model.GetIndex(t.controller.model)).First(); targetContext = targetBlock.context; } else if (selectedContexts.Count() == 1) { targetContext = selectedContexts.First(); } else { Debug.LogError(m_BlockPasteError.text); return; } VFXContext targetModelContext = targetContext.controller.model; int targetIndex = -1; if (targetBlock != null) { targetIndex = targetModelContext.GetIndex(targetBlock.controller.model) + 1; } var newBlocks = new HashSet <VFXBlock>(); newControllers.Clear(); foreach (var block in serializableGraph.operatorsOrBlocks) { Node blk = block; VFXBlock newBlock = PasteAndInitializeNode <VFXBlock>(view.controller, ref blk); if (targetModelContext.AcceptChild(newBlock, targetIndex)) { newBlocks.Add(newBlock); targetModelContext.AddChild(newBlock, targetIndex, false); // only notify once after all blocks have been added targetIndex++; } } targetModelContext.Invalidate(VFXModel.InvalidationCause.kStructureChanged); //TODO fill infos.indexToController for when external links will be optionally copied. view.ClearSelection(); foreach (var uiBlock in targetContext.Query().OfType <VFXBlockUI>().Where(t => newBlocks.Contains(t.controller.model)).ToList()) { view.AddToSelection(uiBlock); } }