You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
387 lines
12 KiB
387 lines
12 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
using UnityEditor.Experimental.GraphView;
|
|
|
|
using UnityEngine;
|
|
using UnityEngine.VFX;
|
|
using UnityEngine.UIElements;
|
|
|
|
|
|
namespace UnityEditor.VFX.UI
|
|
{
|
|
abstract class VFXParameterDataAnchorController : VFXDataAnchorController
|
|
{
|
|
public VFXParameterDataAnchorController(VFXSlot model, VFXParameterNodeController sourceNode, bool hidden) : base(model, sourceNode, hidden)
|
|
{
|
|
}
|
|
|
|
public override string name
|
|
{
|
|
get
|
|
{
|
|
if (depth == 0)
|
|
return sourceNode.exposedName;
|
|
return base.name;
|
|
}
|
|
}
|
|
|
|
public new VFXParameterNodeController sourceNode
|
|
{
|
|
get { return base.sourceNode as VFXParameterNodeController; }
|
|
}
|
|
public override bool expandedSelf
|
|
{
|
|
get
|
|
{
|
|
return sourceNode.infos.expandedSlots != null && sourceNode.infos.expandedSlots.Contains(model);
|
|
}
|
|
}
|
|
public override void ExpandPath()
|
|
{
|
|
if (sourceNode.infos.expandedSlots == null)
|
|
sourceNode.infos.expandedSlots = new List<VFXSlot>();
|
|
bool changed = false;
|
|
if (!sourceNode.infos.expandedSlots.Contains(model))
|
|
{
|
|
sourceNode.infos.expandedSlots.Add(model);
|
|
changed = true;
|
|
}
|
|
|
|
if (SlotShouldSkipFirstLevel(model))
|
|
{
|
|
VFXSlot firstChild = model.children.First();
|
|
if (!sourceNode.infos.expandedSlots.Contains(firstChild))
|
|
{
|
|
sourceNode.infos.expandedSlots.Add(firstChild);
|
|
changed = true;
|
|
}
|
|
}
|
|
if (changed)
|
|
{
|
|
sourceNode.model.Invalidate(VFXModel.InvalidationCause.kUIChanged);
|
|
}
|
|
}
|
|
|
|
public override void RetractPath()
|
|
{
|
|
if (sourceNode.infos.expandedSlots != null)
|
|
{
|
|
bool changed = sourceNode.infos.expandedSlots.Remove(model);
|
|
if (SlotShouldSkipFirstLevel(model))
|
|
{
|
|
changed |= sourceNode.infos.expandedSlots.Remove(model.children.First());
|
|
}
|
|
if (changed)
|
|
{
|
|
sourceNode.model.Invalidate(VFXModel.InvalidationCause.kUIChanged);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
class VFXParameterOutputDataAnchorController : VFXParameterDataAnchorController
|
|
{
|
|
public VFXParameterOutputDataAnchorController(VFXSlot model, VFXParameterNodeController sourceNode, bool hidden) : base(model, sourceNode, hidden)
|
|
{
|
|
}
|
|
|
|
public override Direction direction
|
|
{ get { return Direction.Output; } }
|
|
}
|
|
class VFXParameterInputDataAnchorController : VFXParameterDataAnchorController
|
|
{
|
|
public VFXParameterInputDataAnchorController(VFXSlot model, VFXParameterNodeController sourceNode, bool hidden) : base(model, sourceNode, hidden)
|
|
{
|
|
}
|
|
|
|
public override Direction direction
|
|
{ get { return Direction.Input; } }
|
|
}
|
|
|
|
class VFXParameterNodeController : VFXNodeController, IPropertyRMProvider
|
|
{
|
|
VFXParameterController m_ParentController;
|
|
|
|
int m_Id;
|
|
|
|
public VFXParameterNodeController(VFXParameterController controller, VFXParameter.Node infos, VFXViewController viewController) : base(controller.model, viewController)
|
|
{
|
|
m_ParentController = controller;
|
|
m_Id = infos.id;
|
|
}
|
|
|
|
protected override void ModelChanged(UnityEngine.Object obj)
|
|
{
|
|
base.ModelChanged(obj);
|
|
|
|
foreach (var port in inputPorts)
|
|
{
|
|
port.ApplyChanges(); // call the port ApplyChange because expanded states are stored in the VFXParameter.Node
|
|
}
|
|
|
|
foreach (var port in outputPorts)
|
|
{
|
|
port.ApplyChanges(); // call the port ApplyChange because expanded states are stored in the VFXParameter.Node
|
|
}
|
|
}
|
|
|
|
public VFXParameter.Node infos
|
|
{
|
|
get { return m_ParentController.model.GetNode(m_Id); }
|
|
}
|
|
|
|
protected override VFXDataAnchorController AddDataAnchor(VFXSlot slot, bool input, bool hidden)
|
|
{
|
|
VFXDataAnchorController newAnchor;
|
|
if (input)
|
|
newAnchor = new VFXParameterInputDataAnchorController(slot, this, hidden);
|
|
else
|
|
newAnchor = new VFXParameterOutputDataAnchorController(slot, this, hidden);
|
|
|
|
newAnchor.portType = slot.property.type;
|
|
return newAnchor;
|
|
}
|
|
|
|
public override string title
|
|
{
|
|
get { return parentController.isOutput ? inputPorts.First().name : outputPorts.First().name; }
|
|
}
|
|
|
|
public string exposedName
|
|
{
|
|
get { return m_ParentController.model.exposedName; }
|
|
}
|
|
public bool exposed
|
|
{
|
|
get { return m_ParentController.model.exposed; }
|
|
}
|
|
|
|
public int order
|
|
{
|
|
get { return m_ParentController.model.order; }
|
|
}
|
|
public override bool expanded { get; set; }
|
|
public override bool superCollapsed
|
|
{
|
|
get
|
|
{
|
|
return !infos.expanded;
|
|
}
|
|
set
|
|
{
|
|
infos.expanded = !value;
|
|
model.Invalidate(VFXModel.InvalidationCause.kUIChanged);
|
|
}
|
|
}
|
|
|
|
public VFXSpace space
|
|
{
|
|
get
|
|
{
|
|
return m_ParentController.space;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_ParentController.space = value;
|
|
}
|
|
}
|
|
|
|
public bool spaceableAndMasterOfSpace
|
|
{
|
|
get
|
|
{
|
|
return m_ParentController.spaceableAndMasterOfSpace;
|
|
}
|
|
}
|
|
|
|
public bool IsSpaceInherited()
|
|
{
|
|
return m_ParentController.IsSpaceInherited();
|
|
}
|
|
|
|
bool IPropertyRMProvider.expanded
|
|
{
|
|
get
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
bool IPropertyRMProvider.editable
|
|
{
|
|
get { return true; }
|
|
}
|
|
|
|
bool IPropertyRMProvider.expandable { get { return false; } }
|
|
bool IPropertyRMProvider.expandableIfShowsEverything { get { return false; } }
|
|
|
|
|
|
IEnumerable<int> IPropertyRMProvider.filteredOutEnumerators { get { return null; } }
|
|
public object value
|
|
{
|
|
get
|
|
{
|
|
return m_ParentController.value;
|
|
}
|
|
set
|
|
{
|
|
m_ParentController.value = value;
|
|
}
|
|
}
|
|
|
|
string IPropertyRMProvider.name { get { return "Value"; } }
|
|
|
|
object[] IPropertyRMProvider.customAttributes { get { return new object[] { }; } }
|
|
|
|
VFXPropertyAttributes IPropertyRMProvider.attributes { get { return new VFXPropertyAttributes(); } }
|
|
|
|
public Type portType
|
|
{
|
|
get
|
|
{
|
|
return m_ParentController.model.type;
|
|
}
|
|
}
|
|
|
|
int IPropertyRMProvider.depth { get { return 0; } }
|
|
|
|
void IPropertyRMProvider.ExpandPath()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
void IPropertyRMProvider.RetractPath()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
void IPropertyRMProvider.StartLiveModification() { }
|
|
void IPropertyRMProvider.EndLiveModification() { }
|
|
|
|
public override void CollectGizmos()
|
|
{
|
|
if (parentController.isOutput)
|
|
return;
|
|
m_GizmoableAnchors.Clear();
|
|
if (VFXGizmoUtility.HasGizmo(m_ParentController.portType))
|
|
{
|
|
m_GizmoableAnchors.Add(m_ParentController);
|
|
}
|
|
}
|
|
|
|
public override void DrawGizmos(VisualEffect component)
|
|
{
|
|
if (currentGizmoable is VFXParameterController gizmoable)
|
|
{
|
|
gizmoable.DrawGizmos(component);
|
|
}
|
|
}
|
|
|
|
public override void OnEdgeFromInputGoingToBeRemoved(VFXDataAnchorController myInput)
|
|
{
|
|
base.OnEdgeFromInputGoingToBeRemoved(myInput);
|
|
if (parentController.isOutput)
|
|
infos.linkedSlots.RemoveAll(t => t.inputSlot == myInput.model);
|
|
}
|
|
|
|
public override void OnEdgeFromOutputGoingToBeRemoved(VFXDataAnchorController myOutput, VFXDataAnchorController otherInput)
|
|
{
|
|
base.OnEdgeFromOutputGoingToBeRemoved(myOutput, otherInput);
|
|
if (!parentController.isOutput)
|
|
infos.linkedSlots.RemoveAll(t => t.outputSlot == myOutput.model && t.inputSlot == otherInput.model);
|
|
}
|
|
|
|
public override Bounds GetGizmoBounds(VisualEffect component)
|
|
{
|
|
return m_ParentController.GetGizmoBounds(component);
|
|
}
|
|
|
|
public override int id
|
|
{
|
|
get { return m_Id; }
|
|
}
|
|
|
|
public override Vector2 position
|
|
{
|
|
get
|
|
{
|
|
return infos.position;
|
|
}
|
|
set
|
|
{
|
|
infos.position = value;
|
|
model.Invalidate(VFXModel.InvalidationCause.kUIChanged);
|
|
}
|
|
}
|
|
|
|
public VFXParameterController parentController
|
|
{
|
|
get { return m_ParentController; }
|
|
}
|
|
|
|
public VFXInlineOperator ConvertToInline()
|
|
{
|
|
if (parentController.isOutput)
|
|
return null;
|
|
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);
|
|
return op;
|
|
}
|
|
}
|
|
}
|