public override void WillCreateLink(ref VFXSlot myInput, ref VFXSlot otherOutput) { if (!myInput.IsMasterSlot()) { return; } int inputIndex = model.GetSlotIndex(myInput); IVFXOperatorNumericUnifiedConstrained constraintInterface = model as IVFXOperatorNumericUnifiedConstrained; if (!constraintInterface.slotIndicesThatMustHaveSameType.Contains(inputIndex)) { base.WillCreateLink(ref myInput, ref otherOutput); return; } bool scalar = constraintInterface.slotIndicesThatCanBeScalar.Contains(inputIndex); if (scalar) { var bestAffinityType = model.GetBestAffinityType(otherOutput.property.type); VFXSlot otherSlotWithConstraint = model.inputSlots.Where((t, i) => constraintInterface.slotIndicesThatMustHaveSameType.Contains(i)).FirstOrDefault(); if (otherSlotWithConstraint == null || otherSlotWithConstraint.property.type == bestAffinityType) { model.SetOperandType(inputIndex, bestAffinityType); myInput = model.GetInputSlot(inputIndex); } else if (!myInput.CanLink(otherOutput) || !otherOutput.CanLink(myInput)) // if the link is invalid if we don't change the type, change the type to the matching scalar { var bestScalarAffinityType = model.GetBestAffinityType(GetMatchingScalar(otherOutput.property.type)); if (bestScalarAffinityType != null) { model.SetOperandType(inputIndex, bestScalarAffinityType); myInput = model.GetInputSlot(inputIndex); } } return; // never change the type of other constraint if the linked slot is scalar } VFXSlot input = myInput; bool hasLinks = model.inputSlots.Where((t, i) => t != input && t.HasLink(true) && constraintInterface.slotIndicesThatMustHaveSameType.Contains(i) && !constraintInterface.slotIndicesThatCanBeScalar.Contains(i)).Count() > 0; bool linkPossible = myInput.CanLink(otherOutput) && otherOutput.CanLink(myInput); if (!hasLinks || !linkPossible) //Change the type if other type having the same constraint have no link or if the link will fail if we don't { var bestAffinityType = model.GetBestAffinityType(otherOutput.property.type); if (bestAffinityType != null) { foreach (int slotIndex in constraintInterface.slotIndicesThatMustHaveSameType) { if (!constraintInterface.slotIndicesThatCanBeScalar.Contains(slotIndex) || GetMatchingScalar(bestAffinityType) != model.GetInputSlot(slotIndex).property.type) { model.SetOperandType(slotIndex, bestAffinityType); } } myInput = model.GetInputSlot(inputIndex); } } }
public virtual void WillCreateLink(ref VFXSlot myInput, ref VFXSlot otherOutput) { }
public void ExpandRetractAndSetPropertyValue() { CreateTestAsset("TestGUI4"); var initContextDesc = VFXLibrary.GetContexts().Where(t => t.name == "Initialize").First(); var newContext = m_ViewController.AddVFXContext(new Vector2(300, 100), initContextDesc); m_ViewController.ApplyChanges(); Assert.AreEqual(m_ViewController.allChildren.Where(t => t is VFXContextController).Count(), 1); var contextController = m_ViewController.allChildren.Where(t => t is VFXContextController).First() as VFXContextController; Assert.AreEqual(contextController.model, newContext); // Adding every block compatible with an init context var block = VFXLibrary.GetBlocks().Where(t => t.name == "Test").First(); var newBlock = block.CreateInstance(); contextController.AddBlock(0, newBlock); Assert.IsTrue(newBlock is AllType); m_ViewController.ApplyChanges(); Assert.AreEqual(contextController.blockControllers.Where(t => t.model == newBlock).Count(), 1); var blockController = contextController.blockControllers.Where(t => t.model == newBlock).First(); Assert.NotNull(blockController); Assert.NotZero(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).name == "aVector3").Count()); VFXSlot slot = blockController.model.inputSlots.First(t => t.name == "aVector3"); var aVector3Controller = blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).name == "aVector3").First() as VFXContextDataInputAnchorController; Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.x").Count(), 1); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.y").Count(), 1); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.z").Count(), 1); aVector3Controller.ExpandPath(); m_ViewController.ApplyChanges(); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.x").Count(), 1); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.y").Count(), 1); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.z").Count(), 1); aVector3Controller.RetractPath(); m_ViewController.ApplyChanges(); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.x").Count(), 1); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.y").Count(), 1); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.z").Count(), 1); aVector3Controller.SetPropertyValue(new Vector3(1.2f, 3.4f, 5.6f)); Assert.AreEqual(slot.value, new Vector3(1.2f, 3.4f, 5.6f)); aVector3Controller.ExpandPath(); m_ViewController.ApplyChanges(); var vector3yController = blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.y").First() as VFXContextDataInputAnchorController; vector3yController.SetPropertyValue(7.8f); Assert.AreEqual(slot.value, new Vector3(1.2f, 7.8f, 5.6f)); DestroyTestAsset("TestGUI4"); }
void IEdgeConnectorListener.OnDropOutsidePort(Edge edge, Vector2 position) { VFXSlot startSlot = controller.model; VFXView view = this.GetFirstAncestorOfType <VFXView>(); VFXViewController viewController = view.controller; List <VisualElement> picked = new List <VisualElement>(); panel.PickAll(position, picked); VFXNodeUI endNode = null; foreach (var element in picked) { if (element is VFXNodeUI node) { endNode = node; break; } } VFXDataEdge dataEdge = edge as VFXDataEdge; bool exists = false; if (dataEdge.controller != null) { exists = true; view.controller.RemoveElement(dataEdge.controller); } if (endNode != null) { VFXNodeController nodeController = endNode.controller; if (nodeController != null) { IVFXSlotContainer slotContainer = nodeController.slotContainer; if (controller.direction == Direction.Input) { foreach (var output in nodeController.outputPorts.Where(t => t.model == null || t.model.IsMasterSlot())) { if (viewController.CreateLink(controller, output)) { break; } } } else { foreach (var input in nodeController.inputPorts.Where(t => t.model == null || t.model.IsMasterSlot() && !t.model.HasLink(true))) { if (viewController.CreateLink(input, controller)) { break; } } } } } else if (controller.direction == Direction.Input && Event.current.modifiers == EventModifiers.Alt) { VFXModelDescriptorParameters parameterDesc = VFXLibrary.GetParameters().FirstOrDefault(t => t.name == controller.portType.UserFriendlyName()); if (parameterDesc != null) { Vector2 pos = view.contentViewContainer.GlobalToBound(position) - new Vector2(140, 20); VFXParameter parameter = viewController.AddVFXParameter(pos, parameterDesc, false); parameter.SetSettingValue("m_Exposed", true); startSlot.Link(parameter.outputSlots[0]); CopyValueToParameter(parameter); viewController.AddVFXModel(pos, parameter); } } else if (!exists) { if (direction == Direction.Input || viewController.model.visualEffectObject is VisualEffectSubgraphOperator || viewController.model.visualEffectObject is VisualEffectSubgraphBlock) // no context for subgraph operators. { VFXFilterWindow.Show(VFXViewWindow.currentWindow, Event.current.mousePosition, view.ViewToScreenPosition(Event.current.mousePosition), new VFXNodeProvider(viewController, AddLinkedNode, ProviderFilter, new Type[] { typeof(VFXOperator), typeof(VFXParameter) })); } else { VFXFilterWindow.Show(VFXViewWindow.currentWindow, Event.current.mousePosition, view.ViewToScreenPosition(Event.current.mousePosition), new VFXNodeProvider(viewController, AddLinkedNode, ProviderFilter, new Type[] { typeof(VFXOperator), typeof(VFXParameter), typeof(VFXContext) })); } } }
public VFXOutputOperatorAnchorController(VFXSlot model, VFXNodeController sourceNode, bool hidden) : base(model, sourceNode, hidden) { }
public void CopyPasteContextWithBlock() { var initContextDesc = VFXLibrary.GetContexts().Where(t => typeof(VFXBasicInitialize).IsAssignableFrom(t.modelType)).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; string copyData = view.SerializeElements(view.selection.OfType <GraphElement>()); boundsSlot.value = new AABox() { center = Vector3.zero, size = Vector3.zero }; minValueSlot.value = 789f; view.UnserializeAndPasteElements("paste", copyData); 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.UnserializeAndPasteElements("paste", copyData); 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 CascadedAddOperator_Adding_And_Removing_Several_Links() { var one = ScriptableObject.CreateInstance <VFXInlineOperator>(); var add = ScriptableObject.CreateInstance <Operator.Add>(); one.SetSettingValue("m_Type", (SerializableType)typeof(float)); one.inputSlots[0].value = 1.0f; var count = 8.0f; for (int i = 0; i < (int)count; i++) { add.AddOperand(); } for (int i = 0; i < (int)count; i++) { var inputSlots = add.inputSlots.ToArray(); var emptySlot = inputSlots.First(s => !s.HasLink()); emptySlot.Link(one.outputSlots.First()); } var finalExpr = add.outputSlots.First().GetExpression(); var context = new VFXExpression.Context(VFXExpressionContextOption.CPUEvaluation); var result = context.Compile(finalExpr); var eight = result.Get <float>(); Assert.AreEqual(count, eight); //< Process some remove var removeCount = 4.0f; for (int i = 0; i < (int)removeCount; ++i) { var linkedSlots = add.inputSlots.Where(o => o.HasLink()); VFXSlot removeSlot = null; if (i % 2 == 0) { removeSlot = linkedSlots.First(); } else { removeSlot = linkedSlots.Last(); } //Check expected link count var linkCount = add.inputSlots.Where(o => o.HasLink()).Count(); Assert.AreEqual((int)count - i, linkCount); var index = add.inputSlots.IndexOf(removeSlot); add.RemoveOperand(index); //Check expected link count linkCount = add.inputSlots.Where(o => o.HasLink()).Count(); Assert.AreEqual((int)count - i - 1, linkCount); //Check if all input slot are still with a default value foreach (var slot in add.inputSlots.Where(o => o.HasLink())) { Assert.AreEqual(0.0f, slot.value); } //Check computed result finalExpr = add.outputSlots.First().GetExpression(); result = context.Compile(finalExpr); var res = result.Get <float>(); Assert.AreEqual(count - (float)i - 1.0f, res); } }
public VFXParameterOutputDataAnchorController(VFXSlot model, VFXParameterNodeController sourceNode, bool hidden) : base(model, sourceNode, hidden) { }
public override VFXCoordinateSpace GetOutputSpaceFromSlot(VFXSlot outputSlot) { return(VFXCoordinateSpace.World); }
void ConvertContext(VFXNodeProvider.Descriptor d, Vector2 mPos) { VFXView view = GetFirstAncestorOfType <VFXView>(); VFXViewController viewController = controller.viewController; if (view == null) { return; } mPos = view.contentViewContainer.ChangeCoordinatesTo(view, controller.position); var newNodeController = view.AddNode(d, mPos); var newContextController = newNodeController as VFXContextController; //transfer blocks foreach (var block in controller.model.children.ToArray()) // To array needed as the IEnumerable content will change { newContextController.AddBlock(-1, block); } //transfer settings var contextType = controller.model.GetType(); foreach (var setting in newContextController.model.GetSettings(true)) { if ((newContextController.model is VFXPlanarPrimitiveOutput || newContextController.model.GetType().Name == "VFXLitPlanarPrimitiveOutput") && setting.field.Name == "primitiveType") { continue; } if (!setting.valid || setting.field.GetCustomAttributes(typeof(VFXSettingAttribute), true).Length == 0) { continue; } var sourceSetting = controller.model.GetSetting(setting.name); if (!sourceSetting.valid) { continue; } object value; if (VFXConverter.TryConvertTo(sourceSetting.value, setting.field.FieldType, out value)) { newContextController.model.SetSettingValue(setting.field.Name, value); } } //transfer flow edges if (controller.flowInputAnchors.Count == 1) { foreach (var output in controller.flowInputAnchors[0].connections.Select(t => t.output).ToArray()) { newContextController.model.LinkFrom(output.context.model, output.slotIndex); } } // Apply the slot changes that can be the result of settings changes newContextController.ApplyChanges(); VFXSlot firstTextureSlot = null; //transfer master slot values foreach (var slot in newContextController.model.inputSlots) { VFXSlot mySlot = controller.model.inputSlots.FirstOrDefault(t => t.name == slot.name); if (mySlot == null) { if (slot.valueType == VFXValueType.Texture2D && firstTextureSlot == null) { firstTextureSlot = slot; } continue; } object value; if (VFXConverter.TryConvertTo(mySlot.value, slot.property.type, out value)) { slot.value = value; } } //Hack to copy the first texture in the first texture slot if not found by name if (firstTextureSlot != null) { VFXSlot mySlot = controller.model.inputSlots.FirstOrDefault(t => t.valueType == VFXValueType.Texture2D); if (mySlot != null) { firstTextureSlot.value = mySlot.value; } } foreach (var anchor in newContextController.inputPorts) { string path = anchor.path; var myAnchor = controller.inputPorts.FirstOrDefault(t => t.path == path); if (myAnchor == null || !myAnchor.HasLink()) { continue; } //There should be only one var output = myAnchor.connections.First().output; viewController.CreateLink(anchor, output); } // Apply the change so that it won't unlink the blocks links controller.ApplyChanges(); viewController.RemoveElement(controller); }
public VFXParameterNodeController GetParameterForLink(VFXSlot slot) { return(m_Controllers.FirstOrDefault(t => { var infos = t.Value.infos; return infos != null && infos.linkedSlots != null && infos.linkedSlots.Any(u => u.inputSlot == slot); }).Value); }
void ConvertContext(VFXNodeProvider.Descriptor d, Vector2 mPos) { VFXView view = GetFirstAncestorOfType <VFXView>(); VFXViewController viewController = controller.viewController; if (view == null) { return; } mPos = view.contentViewContainer.ChangeCoordinatesTo(view, controller.position); var newNodeController = view.AddNode(d, mPos); var newContextController = newNodeController as VFXContextController; //transfer blocks foreach (var block in controller.model.children.ToArray()) // To array needed as the IEnumerable content will change { newContextController.AddBlock(-1, block); } //transfer settings var contextType = controller.model.GetType(); foreach (var setting in newContextController.model.GetSettings(true)) { FieldInfo myField = contextType.GetField(setting.Name, BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic); if (myField == null || myField.GetCustomAttributes(typeof(VFXSettingAttribute), true).Length == 0) { continue; } object value; if (VFXConverter.TryConvertTo(myField.GetValue(controller.model), setting.FieldType, out value)) { newContextController.model.SetSettingValue(setting.Name, value); } } //transfer flow edges if (controller.flowInputAnchors.Count == 1) { foreach (var output in controller.flowInputAnchors[0].connections.Select(t => t.output).ToArray()) { newContextController.model.LinkFrom(output.context.model, output.slotIndex); } } // Apply the slot changes that can be the result of settings changes newContextController.ApplyChanges(); //transfer master slot values foreach (var slot in newContextController.model.inputSlots) { VFXSlot mySlot = controller.model.inputSlots.FirstOrDefault(t => t.name == slot.name); if (mySlot == null) { continue; } object value; if (VFXConverter.TryConvertTo(mySlot.value, slot.property.type, out value)) { slot.value = value; } } foreach (var anchor in newContextController.inputPorts) { string path = anchor.path; var myAnchor = controller.inputPorts.FirstOrDefault(t => t.path == path); if (myAnchor == null || !myAnchor.HasLink()) { continue; } //There should be only one var output = myAnchor.connections.First().output; viewController.CreateLink(anchor, output); } // Apply the change so that it won't unlink the blocks links controller.ApplyChanges(); viewController.RemoveElement(controller); }
public void ExpandRetractAndSetPropertyValue() { var viewController = StartEditTestAsset(); var initContextDesc = VFXLibrary.GetContexts().Where(t => typeof(VFXBasicInitialize).IsAssignableFrom(t.modelType)).First(); var newContext = viewController.AddVFXContext(new Vector2(300, 100), initContextDesc); viewController.ApplyChanges(); Assert.AreEqual(viewController.allChildren.Where(t => t is VFXContextController).Count(), 1); var contextController = viewController.allChildren.Where(t => t is VFXContextController).First() as VFXContextController; Assert.AreEqual(contextController.model, newContext); // Adding every block compatible with an init context var blockDesc = new VFXModelDescriptor <VFXBlock>(ScriptableObject.CreateInstance <AllType>()); var newBlock = blockDesc.CreateInstance(); contextController.AddBlock(0, newBlock); Assert.IsTrue(newBlock is AllType); viewController.ApplyChanges(); Assert.AreEqual(contextController.blockControllers.Where(t => t.model == newBlock).Count(), 1); var blockController = contextController.blockControllers.Where(t => t.model == newBlock).First(); Assert.NotNull(blockController); Assert.NotZero(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).name == "aVector3").Count()); VFXSlot slot = blockController.model.inputSlots.First(t => t.name == "aVector3"); var aVector3Controller = blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).name == "aVector3").First() as VFXContextDataInputAnchorController; Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.x").Count(), 1); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.y").Count(), 1); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.z").Count(), 1); aVector3Controller.ExpandPath(); viewController.ApplyChanges(); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.x").Count(), 1); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.y").Count(), 1); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.z").Count(), 1); aVector3Controller.RetractPath(); viewController.ApplyChanges(); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.x").Count(), 1); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.y").Count(), 1); Assert.AreEqual(blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.z").Count(), 1); aVector3Controller.SetPropertyValue(new Vector3(1.2f, 3.4f, 5.6f)); Assert.AreEqual(slot.value, new Vector3(1.2f, 3.4f, 5.6f)); aVector3Controller.ExpandPath(); viewController.ApplyChanges(); var vector3yController = blockController.inputPorts.Where(t => t is VFXContextDataInputAnchorController && (t as VFXContextDataInputAnchorController).path == "aVector3.y").First() as VFXContextDataInputAnchorController; vector3yController.SetPropertyValue(7.8f); Assert.AreEqual(slot.value, new Vector3(1.2f, 7.8f, 5.6f)); }
protected abstract VFXDataAnchorController AddDataAnchor(VFXSlot slot, bool input, bool hidden);
void IEdgeConnectorListener.OnDropOutsidePort(Edge edge, Vector2 position) { VFXSlot startSlot = controller.model; VFXView view = this.GetFirstAncestorOfType <VFXView>(); VFXViewController viewController = view.controller; VFXNodeUI endNode = null; foreach (var node in view.GetAllNodes()) { if (node.worldBound.Contains(position)) { endNode = node; } } VFXDataEdge dataEdge = edge as VFXDataEdge; bool exists = false; if (dataEdge.controller != null) { exists = true; view.controller.RemoveElement(dataEdge.controller); } if (endNode != null) { VFXNodeController nodeController = endNode.controller; if (nodeController != null) { IVFXSlotContainer slotContainer = nodeController.slotContainer; if (controller.direction == Direction.Input) { foreach (var output in nodeController.outputPorts.Where(t => t.model == null || t.model.IsMasterSlot())) { if (viewController.CreateLink(controller, output)) { break; } } } else { foreach (var input in nodeController.inputPorts.Where(t => t.model == null || t.model.IsMasterSlot())) { if (viewController.CreateLink(input, controller)) { break; } } } } } else if (controller.direction == Direction.Input && Event.current.modifiers == EventModifiers.Alt) { VFXModelDescriptorParameters parameterDesc = VFXLibrary.GetParameters().FirstOrDefault(t => t.name == controller.portType.UserFriendlyName()); if (parameterDesc != null) { VFXParameter parameter = viewController.AddVFXParameter(view.contentViewContainer.GlobalToBound(position) - new Vector2(360, 0), parameterDesc); startSlot.Link(parameter.outputSlots[0]); CopyValueToParameter(parameter); } } else if (!exists) { VFXFilterWindow.Show(VFXViewWindow.currentWindow, Event.current.mousePosition, view.ViewToScreenPosition(Event.current.mousePosition), new VFXNodeProvider(viewController, AddLinkedNode, ProviderFilter, new Type[] { typeof(VFXOperator), typeof(VFXParameter), typeof(VFXContext) })); } }
public void ConvertToInline() { if (parentController.isOutput) { return; } VFXInlineOperator op = ScriptableObject.CreateInstance <VFXInlineOperator>(); op.SetSettingValue("m_Type", (SerializableType)parentController.model.type); viewController.graph.AddChild(op); op.position = position; if (infos.linkedSlots != null) { foreach (var link in infos.linkedSlots.ToArray()) { var ancestors = new List <VFXSlot>(); ancestors.Add(link.outputSlot); VFXSlot parent = link.outputSlot.GetParent(); while (parent != null) { ancestors.Add(parent); parent = parent.GetParent(); } int index = parentController.model.GetSlotIndex(ancestors.Last()); if (index >= 0 && index < op.GetNbOutputSlots()) { VFXSlot slot = op.outputSlots[index]; for (int i = ancestors.Count() - 2; i >= 0; --i) { int subIndex = ancestors[i + 1].GetIndex(ancestors[i]); if (subIndex >= 0 && subIndex < slot.GetNbChildren()) { slot = slot[subIndex]; } else { slot = null; break; } } if (slot.path != link.outputSlot.path.Substring(1)) // parameters output are still named 0, inline outputs have no name. { Debug.LogError("New inline don't have the same subslot as old parameter"); } else { link.outputSlot.Unlink(link.inputSlot); slot.Link(link.inputSlot); } } } } op.inputSlots[0].value = value; viewController.LightApplyChanges(); viewController.PutInSameGroupNodeAs(viewController.GetNodeController(op, 0), this); viewController.RemoveElement(this); }
public sealed override VFXCoordinateSpace GetOutputSpaceFromSlot(VFXSlot slot) { return(m_targetSpace); }
public IEnumerator CreateComponentWithAllBasicTypeExposed([ValueSource("linkModes")] bool linkMode, [ValueSource("bindingModes")] bool bindingModes) { var commonBaseName = "abcd_"; Func <Type, object> GetValue_A_Type = delegate(Type type) { if (typeof(float) == type) { return(2.0f); } else if (typeof(Vector2) == type) { return(new Vector2(3.0f, 4.0f)); } else if (typeof(Vector3) == type) { return(new Vector3(8.0f, 9.0f, 10.0f)); } else if (typeof(Vector4) == type) { return(new Vector4(11.0f, 12.0f, 13.0f, 14.0f)); } else if (typeof(Color) == type) { return(new Color(0.1f, 0.2f, 0.3f, 0.4f)); } else if (typeof(int) == type) { return(15); } else if (typeof(uint) == type) { return(16u); } else if (typeof(AnimationCurve) == type) { return(new AnimationCurve(new Keyframe(0, 13), new Keyframe(1, 14))); } else if (typeof(Gradient) == type) { return new Gradient() { colorKeys = new GradientColorKey[] { new GradientColorKey(Color.white, 0.2f) } } } ; else if (typeof(Mesh) == type) { return(m_cubeEmpty.GetComponent <MeshFilter>().sharedMesh); } else if (typeof(Texture2D) == type) { return(m_texture2D_A); } else if (typeof(Texture2DArray) == type) { return(m_texture2DArray_A); } else if (typeof(Texture3D) == type) { return(m_texture3D_A); } else if (typeof(Cubemap) == type) { return(m_textureCube_A); } else if (typeof(CubemapArray) == type) { return(m_textureCubeArray_A); } else if (typeof(bool) == type) { return(true); } else if (typeof(Matrix4x4) == type) { return(Matrix4x4.identity); } Assert.Fail(); return(null); }; Func <Type, object> GetValue_B_Type = delegate(Type type) { if (typeof(float) == type) { return(50.0f); } else if (typeof(Vector2) == type) { return(new Vector2(53.0f, 54.0f)); } else if (typeof(Vector3) == type) { return(new Vector3(58.0f, 59.0f, 510.0f)); } else if (typeof(Vector4) == type || typeof(Color) == type)// ValueB_Type is used to set a component value, so return a Vector4 with color values { return(new Vector4(511.0f, 512.0f, 513.0f, 514.0f)); } else if (typeof(int) == type) { return(515); } else if (typeof(uint) == type) { return(516u); } else if (typeof(AnimationCurve) == type) { return(new AnimationCurve(new Keyframe(0, 47), new Keyframe(0.5f, 23), new Keyframe(1.0f, 17))); } else if (typeof(Gradient) == type) { return new Gradient() { colorKeys = new GradientColorKey[] { new GradientColorKey(Color.white, 0.2f), new GradientColorKey(Color.black, 0.6f) } } } ; else if (typeof(Mesh) == type) { return(m_sphereEmpty.GetComponent <MeshFilter>().sharedMesh); } else if (typeof(Texture2D) == type) { return(m_texture2D_B); } else if (typeof(Texture2DArray) == type) { return(m_texture2DArray_B); } else if (typeof(Texture3D) == type) { return(m_texture3D_B); } else if (typeof(Cubemap) == type) { return(m_textureCube_B); } else if (typeof(CubemapArray) == type) { return(m_textureCubeArray_B); } else if (typeof(bool) == type) { return(true); } else if (typeof(Matrix4x4) == type) { return(Matrix4x4.identity); } Assert.Fail(); return(null); }; Func <VFXValueType, VisualEffect, string, bool> fnHas_UsingBindings = delegate(VFXValueType type, VisualEffect vfx, string name) { switch (type) { case VFXValueType.Float: return(vfx.HasFloat(name)); case VFXValueType.Float2: return(vfx.HasVector2(name)); case VFXValueType.Float3: return(vfx.HasVector3(name)); case VFXValueType.Float4: return(vfx.HasVector4(name)); case VFXValueType.Int32: return(vfx.HasInt(name)); case VFXValueType.Uint32: return(vfx.HasUInt(name)); case VFXValueType.Curve: return(vfx.HasAnimationCurve(name)); case VFXValueType.ColorGradient: return(vfx.HasGradient(name)); case VFXValueType.Mesh: return(vfx.HasMesh(name)); case VFXValueType.Texture2D: return(vfx.HasTexture(name) && vfx.GetTextureDimension(name) == TextureDimension.Tex2D); case VFXValueType.Texture2DArray: return(vfx.HasTexture(name) && vfx.GetTextureDimension(name) == TextureDimension.Tex2DArray); case VFXValueType.Texture3D: return(vfx.HasTexture(name) && vfx.GetTextureDimension(name) == TextureDimension.Tex3D); case VFXValueType.TextureCube: return(vfx.HasTexture(name) && vfx.GetTextureDimension(name) == TextureDimension.Cube); case VFXValueType.TextureCubeArray: return(vfx.HasTexture(name) && vfx.GetTextureDimension(name) == TextureDimension.CubeArray); case VFXValueType.Boolean: return(vfx.HasBool(name)); case VFXValueType.Matrix4x4: return(vfx.HasMatrix4x4(name)); } Assert.Fail(); return(false); }; Func <VFXValueType, VisualEffect, string, object> fnGet_UsingBindings = delegate(VFXValueType type, VisualEffect vfx, string name) { switch (type) { case VFXValueType.Float: return(vfx.GetFloat(name)); case VFXValueType.Float2: return(vfx.GetVector2(name)); case VFXValueType.Float3: return(vfx.GetVector3(name)); case VFXValueType.Float4: return(vfx.GetVector4(name)); case VFXValueType.Int32: return(vfx.GetInt(name)); case VFXValueType.Uint32: return(vfx.GetUInt(name)); case VFXValueType.Curve: return(vfx.GetAnimationCurve(name)); case VFXValueType.ColorGradient: return(vfx.GetGradient(name)); case VFXValueType.Mesh: return(vfx.GetMesh(name)); case VFXValueType.Texture2D: case VFXValueType.Texture2DArray: case VFXValueType.Texture3D: case VFXValueType.TextureCube: case VFXValueType.TextureCubeArray: return(vfx.GetTexture(name)); case VFXValueType.Boolean: return(vfx.GetBool(name)); case VFXValueType.Matrix4x4: return(vfx.GetMatrix4x4(name)); } Assert.Fail(); return(null); }; Action <VFXValueType, VisualEffect, string, object> fnSet_UsingBindings = delegate(VFXValueType type, VisualEffect vfx, string name, object value) { switch (type) { case VFXValueType.Float: vfx.SetFloat(name, (float)value); break; case VFXValueType.Float2: vfx.SetVector2(name, (Vector2)value); break; case VFXValueType.Float3: vfx.SetVector3(name, (Vector3)value); break; case VFXValueType.Float4: vfx.SetVector4(name, (Vector4)value); break; case VFXValueType.Int32: vfx.SetInt(name, (int)value); break; case VFXValueType.Uint32: vfx.SetUInt(name, (uint)value); break; case VFXValueType.Curve: vfx.SetAnimationCurve(name, (AnimationCurve)value); break; case VFXValueType.ColorGradient: vfx.SetGradient(name, (Gradient)value); break; case VFXValueType.Mesh: vfx.SetMesh(name, (Mesh)value); break; case VFXValueType.Texture2D: case VFXValueType.Texture2DArray: case VFXValueType.Texture3D: case VFXValueType.TextureCube: case VFXValueType.TextureCubeArray: vfx.SetTexture(name, (Texture)value); break; case VFXValueType.Boolean: vfx.SetBool(name, (bool)value); break; case VFXValueType.Matrix4x4: vfx.SetMatrix4x4(name, (Matrix4x4)value); break; } }; Func <VFXValueType, VisualEffect, string, bool> fnHas_UsingSerializedProperty = delegate(VFXValueType type, VisualEffect vfx, string name) { var editor = Editor.CreateEditor(vfx); try { var propertySheet = editor.serializedObject.FindProperty("m_PropertySheet"); var fieldName = VisualEffectSerializationUtility.GetTypeField(VFXExpression.TypeToType(type)) + ".m_Array"; var vfxField = propertySheet.FindPropertyRelative(fieldName); if (vfxField != null) { for (int i = 0; i < vfxField.arraySize; ++i) { var property = vfxField.GetArrayElementAtIndex(i); var nameProperty = property.FindPropertyRelative("m_Name").stringValue; if (nameProperty == name) { return(true); } } } } finally { GameObject.DestroyImmediate(editor); } return(false); }; Func <SerializedProperty, Matrix4x4> fnMatrixFromSerializedProperty = delegate(SerializedProperty property) { var mat = new Matrix4x4(); mat.m00 = property.FindPropertyRelative("e00").floatValue; mat.m01 = property.FindPropertyRelative("e01").floatValue; mat.m02 = property.FindPropertyRelative("e02").floatValue; mat.m03 = property.FindPropertyRelative("e03").floatValue; mat.m10 = property.FindPropertyRelative("e10").floatValue; mat.m11 = property.FindPropertyRelative("e11").floatValue; mat.m12 = property.FindPropertyRelative("e12").floatValue; mat.m13 = property.FindPropertyRelative("e13").floatValue; mat.m20 = property.FindPropertyRelative("e20").floatValue; mat.m21 = property.FindPropertyRelative("e21").floatValue; mat.m22 = property.FindPropertyRelative("e22").floatValue; mat.m23 = property.FindPropertyRelative("e23").floatValue; mat.m30 = property.FindPropertyRelative("e30").floatValue; mat.m31 = property.FindPropertyRelative("e31").floatValue; mat.m32 = property.FindPropertyRelative("e32").floatValue; mat.m33 = property.FindPropertyRelative("e33").floatValue; return(mat); }; Action <SerializedProperty, Matrix4x4> fnMatrixToSerializedProperty = delegate(SerializedProperty property, Matrix4x4 mat) { property.FindPropertyRelative("e00").floatValue = mat.m00; property.FindPropertyRelative("e01").floatValue = mat.m01; property.FindPropertyRelative("e02").floatValue = mat.m02; property.FindPropertyRelative("e03").floatValue = mat.m03; property.FindPropertyRelative("e10").floatValue = mat.m10; property.FindPropertyRelative("e11").floatValue = mat.m11; property.FindPropertyRelative("e12").floatValue = mat.m12; property.FindPropertyRelative("e13").floatValue = mat.m13; property.FindPropertyRelative("e20").floatValue = mat.m20; property.FindPropertyRelative("e21").floatValue = mat.m21; property.FindPropertyRelative("e22").floatValue = mat.m22; property.FindPropertyRelative("e23").floatValue = mat.m23; property.FindPropertyRelative("e30").floatValue = mat.m30; property.FindPropertyRelative("e31").floatValue = mat.m31; property.FindPropertyRelative("e32").floatValue = mat.m32; property.FindPropertyRelative("e33").floatValue = mat.m33; }; Func <VFXValueType, VisualEffect, string, object> fnGet_UsingSerializedProperty = delegate(VFXValueType type, VisualEffect vfx, string name) { var editor = Editor.CreateEditor(vfx); try { var propertySheet = editor.serializedObject.FindProperty("m_PropertySheet"); editor.serializedObject.Update(); var fieldName = VisualEffectSerializationUtility.GetTypeField(VFXExpression.TypeToType(type)) + ".m_Array"; var vfxField = propertySheet.FindPropertyRelative(fieldName); if (vfxField != null) { for (int i = 0; i < vfxField.arraySize; ++i) { var property = vfxField.GetArrayElementAtIndex(i); var nameProperty = property.FindPropertyRelative("m_Name").stringValue; if (nameProperty == name) { property = property.FindPropertyRelative("m_Value"); switch (type) { case VFXValueType.Float: return(property.floatValue); case VFXValueType.Float2: return(property.vector2Value); case VFXValueType.Float3: return(property.vector3Value); case VFXValueType.Float4: return(property.vector4Value); case VFXValueType.Int32: return(property.intValue); case VFXValueType.Uint32: return(property.intValue); // there isn't uintValue case VFXValueType.Curve: return(property.animationCurveValue); case VFXValueType.ColorGradient: return(property.gradientValue); case VFXValueType.Mesh: return(property.objectReferenceValue); case VFXValueType.Texture2D: case VFXValueType.Texture2DArray: case VFXValueType.Texture3D: case VFXValueType.TextureCube: case VFXValueType.TextureCubeArray: return(property.objectReferenceValue); case VFXValueType.Boolean: return(property.boolValue); case VFXValueType.Matrix4x4: return(fnMatrixFromSerializedProperty(property)); } Assert.Fail(); } } } } finally { GameObject.DestroyImmediate(editor); } return(null); }; Action <VFXValueType, VisualEffect, string, object> fnSet_UsingSerializedProperty = delegate(VFXValueType type, VisualEffect vfx, string name, object value) { var editor = Editor.CreateEditor(vfx); try { editor.serializedObject.Update(); var propertySheet = editor.serializedObject.FindProperty("m_PropertySheet"); var fieldName = VisualEffectSerializationUtility.GetTypeField(VFXExpression.TypeToType(type)) + ".m_Array"; var vfxField = propertySheet.FindPropertyRelative(fieldName); if (vfxField != null) { for (int i = 0; i < vfxField.arraySize; ++i) { var property = vfxField.GetArrayElementAtIndex(i); var propertyName = property.FindPropertyRelative("m_Name").stringValue; if (propertyName == name) { var propertyValue = property.FindPropertyRelative("m_Value"); var propertyOverriden = property.FindPropertyRelative("m_Overridden"); switch (type) { case VFXValueType.Float: propertyValue.floatValue = (float)value; break; case VFXValueType.Float2: propertyValue.vector2Value = (Vector2)value; break; case VFXValueType.Float3: propertyValue.vector3Value = (Vector3)value; break; case VFXValueType.Float4: propertyValue.vector4Value = (Vector4)value; break; case VFXValueType.Int32: propertyValue.intValue = (int)value; break; case VFXValueType.Uint32: propertyValue.intValue = (int)((uint)value); break; // there isn't uintValue case VFXValueType.Curve: propertyValue.animationCurveValue = (AnimationCurve)value; break; case VFXValueType.ColorGradient: propertyValue.gradientValue = (Gradient)value; break; case VFXValueType.Mesh: propertyValue.objectReferenceValue = (UnityEngine.Object)value; break; case VFXValueType.Texture2D: case VFXValueType.Texture2DArray: case VFXValueType.Texture3D: case VFXValueType.TextureCube: case VFXValueType.TextureCubeArray: propertyValue.objectReferenceValue = (UnityEngine.Object)value; break; case VFXValueType.Boolean: propertyValue.boolValue = (bool)value; break; case VFXValueType.Matrix4x4: fnMatrixToSerializedProperty(propertyValue, (Matrix4x4)value); break; } propertyOverriden.boolValue = true; } } } editor.serializedObject.ApplyModifiedProperties(); } finally { GameObject.DestroyImmediate(editor); } }; Func <VFXValueType, VisualEffect, string, bool> fnHas = bindingModes ? fnHas_UsingBindings : fnHas_UsingSerializedProperty; Func <VFXValueType, VisualEffect, string, object> fnGet = bindingModes ? fnGet_UsingBindings : fnGet_UsingSerializedProperty; Action <VFXValueType, VisualEffect, string, object> fnSet = bindingModes ? fnSet_UsingBindings : fnSet_UsingSerializedProperty; EditorApplication.ExecuteMenuItem("Window/General/Game"); var graph = MakeTemporaryGraph(); var contextInitialize = ScriptableObject.CreateInstance <VFXBasicInitialize>(); var allType = ScriptableObject.CreateInstance <AllType>(); contextInitialize.AddChild(allType); graph.AddChild(contextInitialize); // Needs a spawner and output for the system to be valid { var spawner = ScriptableObject.CreateInstance <VFXBasicSpawner>(); spawner.LinkTo(contextInitialize); graph.AddChild(spawner); var output = ScriptableObject.CreateInstance <VFXPointOutput>(); output.LinkFrom(contextInitialize); graph.AddChild(output); } var types = Enum.GetValues(typeof(VFXValueType)).Cast <VFXValueType>() .Where(e => e != VFXValueType.Spline && e != VFXValueType.None).ToArray(); foreach (var parameter in VFXLibrary.GetParameters()) { var newInstance = parameter.CreateInstance(); VFXValueType type = types.FirstOrDefault(e => VFXExpression.GetVFXValueTypeFromType(newInstance.type) == e); if (type != VFXValueType.None) { newInstance.SetSettingValue("m_exposedName", commonBaseName + newInstance.type.UserFriendlyName()); newInstance.SetSettingValue("m_exposed", true); var value = GetValue_A_Type(newInstance.type); Assert.IsNotNull(value); newInstance.value = value; graph.AddChild(newInstance); } } if (linkMode) { foreach (var type in types) { VFXSlot slot = null; for (int i = 0; i < allType.GetNbInputSlots(); ++i) { var currentSlot = allType.GetInputSlot(i); var expression = currentSlot.GetExpression(); if (expression != null && expression.valueType == type) { slot = currentSlot; break; } } Assert.IsNotNull(slot, type.ToString()); var parameter = graph.children.OfType <VFXParameter>().FirstOrDefault(o => { if (o.GetNbOutputSlots() > 0) { var expression = o.outputSlots[0].GetExpression(); if (expression != null && expression.valueType == type) { return(true); } } return(false); }); Assert.IsNotNull(parameter, "parameter with type : " + type.ToString()); slot.Link(parameter.GetOutputSlot(0)); } } graph.RecompileIfNeeded(); while (m_mainObject.GetComponent <VisualEffect>() != null) { UnityEngine.Object.DestroyImmediate(m_mainObject.GetComponent <VisualEffect>()); } var vfxComponent = m_mainObject.AddComponent <VisualEffect>(); vfxComponent.visualEffectAsset = graph.visualEffectResource.asset; yield return(null); Func <AnimationCurve, AnimationCurve, bool> fnCompareCurve = delegate(AnimationCurve left, AnimationCurve right) { return(left.keys.Length == right.keys.Length); }; Func <Gradient, Gradient, bool> fnCompareGradient = delegate(Gradient left, Gradient right) { return(left.colorKeys.Length == right.colorKeys.Length); }; //Check default Value_A & change to Value_B (At this stage, it's useless to access with SerializedProperty) foreach (var parameter in VFXLibrary.GetParameters()) { VFXValueType type = types.FirstOrDefault(e => VFXExpression.GetVFXValueTypeFromType(parameter.model.type) == e); if (type == VFXValueType.None) { continue; } var currentName = commonBaseName + parameter.model.type.UserFriendlyName(); var baseValue = GetValue_A_Type(parameter.model.type); var newValue = GetValue_B_Type(parameter.model.type); Assert.IsTrue(fnHas_UsingBindings(type, vfxComponent, currentName)); var currentValue = fnGet_UsingBindings(type, vfxComponent, currentName); if (type == VFXValueType.ColorGradient) { Assert.IsTrue(fnCompareGradient((Gradient)baseValue, (Gradient)currentValue)); } else if (type == VFXValueType.Curve) { Assert.IsTrue(fnCompareCurve((AnimationCurve)baseValue, (AnimationCurve)currentValue)); } else if (parameter.model.type == typeof(Color)) { Color col = (Color)baseValue; Assert.AreEqual(new Vector4(col.r, col.g, col.b, col.a), currentValue); } else { Assert.AreEqual(baseValue, currentValue); } fnSet_UsingBindings(type, vfxComponent, currentName, newValue); yield return(null); } //Compare new setted values foreach (var parameter in VFXLibrary.GetParameters()) { VFXValueType type = types.FirstOrDefault(e => VFXExpression.GetVFXValueTypeFromType(parameter.model.type) == e); if (type == VFXValueType.None) { continue; } var currentName = commonBaseName + parameter.model.type.UserFriendlyName(); var baseValue = GetValue_B_Type(parameter.model.type); Assert.IsTrue(fnHas(type, vfxComponent, currentName)); var currentValue = fnGet(type, vfxComponent, currentName); if (type == VFXValueType.ColorGradient) { Assert.IsTrue(fnCompareGradient((Gradient)baseValue, (Gradient)currentValue)); } else if (type == VFXValueType.Curve) { Assert.IsTrue(fnCompareCurve((AnimationCurve)baseValue, (AnimationCurve)currentValue)); } else { Assert.AreEqual(baseValue, currentValue); } yield return(null); } //Test ResetOverride function foreach (var parameter in VFXLibrary.GetParameters()) { VFXValueType type = types.FirstOrDefault(e => VFXExpression.GetVFXValueTypeFromType(parameter.model.type) == e); if (type == VFXValueType.None) { continue; } var currentName = commonBaseName + parameter.model.type.UserFriendlyName(); vfxComponent.ResetOverride(currentName); { //If we use bindings, internal value is restored but it doesn't change serialized property (strange at first but intended behavior) var baseValue = bindingModes ? GetValue_A_Type(parameter.model.type) : GetValue_B_Type(parameter.model.type); var currentValue = fnGet(type, vfxComponent, currentName); if (type == VFXValueType.ColorGradient) { Assert.IsTrue(fnCompareGradient((Gradient)baseValue, (Gradient)currentValue)); } else if (type == VFXValueType.Curve) { Assert.IsTrue(fnCompareCurve((AnimationCurve)baseValue, (AnimationCurve)currentValue)); } else if (bindingModes && parameter.model.type == typeof(Color)) { Color col = (Color)baseValue; Assert.AreEqual(new Vector4(col.r, col.g, col.b, col.a), currentValue); } else { Assert.AreEqual(baseValue, currentValue); } } if (!bindingModes) { var internalValue = fnGet_UsingBindings(type, vfxComponent, currentName); var originalAssetValue = GetValue_A_Type(parameter.model.type); if (type == VFXValueType.ColorGradient) { Assert.IsTrue(fnCompareGradient((Gradient)originalAssetValue, (Gradient)internalValue)); } else if (type == VFXValueType.Curve) { Assert.IsTrue(fnCompareCurve((AnimationCurve)originalAssetValue, (AnimationCurve)internalValue)); } else if (parameter.model.type == typeof(Color)) { Color col = (Color)originalAssetValue; Assert.AreEqual(new Vector4(col.r, col.g, col.b, col.a), internalValue); } else { Assert.AreEqual(originalAssetValue, internalValue); } } yield return(null); } }
public VFXContextDataAnchorController(VFXSlot model, VFXNodeController sourceNode, bool hidden) : base(model, sourceNode, hidden) { }