private static VFXSlot CreateSub(VFXProperty property, Direction direction) { var desc = VFXLibrary.GetSlot(property.type); if (desc != null) { var slot = desc.CreateInstance(); slot.m_Direction = direction; slot.m_Property = property; foreach (var subInfo in property.SubProperties()) { var subSlot = CreateSub(subInfo, direction); if (slot.property.attributes.attributes.OfType <MinMaxAttribute>().Any()) { var parentRange = property.attributes.FindRange(); subSlot.UpdateAttributes(new VFXPropertyAttributes(new RangeAttribute(parentRange.x, parentRange.y)), false); } if (subSlot != null) { subSlot.Attach(slot, false); } } return(slot); } throw new InvalidOperationException(string.Format("Unable to create slot for property {0} of type {1}", property.name, property.type)); }
public override bool Equals(object obj) { if (!(obj is VFXProperty)) { return(false); } VFXProperty other = (VFXProperty)obj; return(type == other.type && name == other.name); }
public override VFXExpressionMapper GetExpressionMapper(VFXDeviceTarget target) { var meshData = (VFXDataMesh)GetData(); switch (target) { case VFXDeviceTarget.GPU: { var mapper = new VFXExpressionMapper(); for (int i = 2; i < GetNbInputSlots(); ++i) { VFXExpression exp = GetInputSlot(i).GetExpression(); VFXProperty prop = GetInputSlot(i).property; // As there's not shader generation here, we need expressions that can be evaluated on CPU if (exp.IsAny(VFXExpression.Flags.NotCompilableOnCPU)) { throw new InvalidOperationException(string.Format("Expression for slot {0} must be evaluable on CPU: {1}", prop.name, exp)); } // needs to convert to srgb as color are linear in vfx graph // This should not be performed for colors with the attribute [HDR] and be performed for vector4 with the attribute [Gamma] // But property attributes cannot seem to be accessible from C# :( if (prop.type == typeof(Color)) { exp = VFXOperatorUtility.LinearToGamma(exp); } mapper.AddExpression(exp, prop.name, -1); } return(mapper); } case VFXDeviceTarget.CPU: { var mapper = new VFXExpressionMapper(); mapper.AddExpression(GetInputSlot(0).GetExpression(), "mesh", -1); mapper.AddExpression(GetInputSlot(1).GetExpression(), "transform", -1); mapper.AddExpression(GetInputSlot(2).GetExpression(), "subMeshMask", -1); return(mapper); } default: return(null); } }
// Create and return a slot hierarchy from a property info public static VFXSlot Create(VFXProperty property, Direction direction, object value = null) { var slot = CreateSub(property, direction); // First create slot tree var masterData = new MasterData() { m_Owner = null, m_Value = new VFXSerializableObject(property.type, value), }; slot.PropagateToChildren(s => s.SetMasterSlotAndData(slot, null)); slot.m_MasterData = masterData; slot.UpdateDefaultExpressionValue(); slot.InitializeSpaceableCachedSlot(); return(slot); }
private static VFXSlot CreateSub(VFXProperty property, Direction direction) { var desc = VFXLibrary.GetSlot(property.type); if (desc != null) { var slot = desc.CreateInstance(); slot.m_Direction = direction; slot.m_Property = property; foreach (var subInfo in property.SubProperties()) { var subSlot = CreateSub(subInfo, direction); if (subSlot != null) { subSlot.Attach(slot, false); } } return(slot); } throw new InvalidOperationException(string.Format("Unable to create slot for property {0} of type {1}", property.name, property.type)); }
public override VFXExpressionMapper GetExpressionMapper(VFXDeviceTarget target) { var meshData = (VFXDataMesh)GetData(); switch (target) { case VFXDeviceTarget.GPU: { var mapper = new VFXExpressionMapper(); for (int i = 2; i < GetNbInputSlots(); ++i) { VFXExpression exp = GetInputSlot(i).GetExpression(); VFXProperty prop = GetInputSlot(i).property; // As there's not shader generation here, we need expressions that can be evaluated on CPU if (exp.IsAny(VFXExpression.Flags.NotCompilableOnCPU)) { throw new InvalidOperationException(string.Format("Expression for slot {0} must be evaluable on CPU: {1}", prop.name, exp)); } // needs to convert to srgb as color are linear in vfx graph // This should not be performed for colors with the attribute [HDR] and be performed for vector4 with the attribute [Gamma] // But property attributes cannot seem to be accessible from C# :( if (prop.type == typeof(Color)) { exp = VFXOperatorUtility.LinearToGamma(exp); } mapper.AddExpression(exp, prop.name, -1); } return(mapper); } case VFXDeviceTarget.CPU: { var mapper = new VFXExpressionMapper(); mapper.AddExpression(GetInputSlot(0).GetExpression(), "mesh", -1); mapper.AddExpression(GetInputSlot(1).GetExpression(), "transform", -1); mapper.AddExpression(GetInputSlot(2).GetExpression(), "subMeshMask", -1); // TODO Remove this once material are serialized // Add material properties if (shader != null) { var mat = meshData.GetOrCreateMaterial(); for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); ++i) { if (ShaderUtil.IsShaderPropertyHidden(shader, i)) { var name = ShaderUtil.GetPropertyName(shader, i); var nameId = Shader.PropertyToID(name); if (!mat.HasProperty(nameId)) { continue; } VFXExpression expr = null; switch (ShaderUtil.GetPropertyType(shader, i)) { case ShaderUtil.ShaderPropertyType.Float: expr = VFXValue.Constant <float>(mat.GetFloat(nameId)); break; default: break; } if (expr != null) { mapper.AddExpression(expr, name, -1); } } } } return(mapper); } default: return(null); } }
protected bool SyncSlots(VFXSlot.Direction direction, bool notify) { bool isInput = direction == VFXSlot.Direction.kInput; var expectedProperties = (isInput ? inputProperties : outputProperties).ToArray(); int nbSlots = isInput ? GetNbInputSlots() : GetNbOutputSlots(); var currentSlots = isInput ? inputSlots : outputSlots; // check all slots owner (TODO Still useful?) for (int i = 0; i < nbSlots; ++i) { VFXSlot slot = currentSlots[i]; var slotOwner = slot.owner as VFXSlotContainerModel <ParentType, ChildrenType>; if (slotOwner != this) { Debug.LogError("Slot :" + slot.name + " of Container" + name + "Has a wrong owner."); slot.SetOwner(this); // make sure everything works even if the owner was lost for some reason. } } bool recreate = false; if (nbSlots != expectedProperties.Length) { recreate = true; } else { for (int i = 0; i < nbSlots; ++i) { if (!currentSlots[i].property.Equals(expectedProperties[i].property)) { recreate = true; break; } } } if (recreate) { var existingSlots = new List <VFXSlot>(currentSlots); // Remove all slots for (int i = nbSlots - 1; i >= 0; --i) { InnerRemoveSlot(currentSlots[i], false); } var newSlotCount = expectedProperties.Length; var newSlots = new VFXSlot[newSlotCount]; var createdSlots = new List <VFXSlot>(newSlotCount); // Reuse slots that already exists or create a new one if not for (int i = 0; i < newSlotCount; ++i) { var p = expectedProperties[i]; var slot = existingSlots.Find(s => p.property.Equals(s.property)); if (slot != null) { slot.UpdateAttributes(p.property.attributes); existingSlots.Remove(slot); } else { slot = VFXSlot.Create(p, direction); createdSlots.Add(slot); } newSlots[i] = slot; } for (int i = 0; i < createdSlots.Count; ++i) { var dstSlot = createdSlots[i]; // Try to keep links and value for slots of same name and compatible types var srcSlot = existingSlots.FirstOrDefault(s => s.property.name == dstSlot.property.name); // Find the first slot with same type (should perform a more clever selection based on name distance) if (srcSlot == null) { srcSlot = existingSlots.FirstOrDefault(s => s.property.type == dstSlot.property.type); } // Try to find a slot that can be implicitely converted if (srcSlot == null) { srcSlot = existingSlots.FirstOrDefault(s => VFXConverter.CanConvertTo(s.property.type, dstSlot.property.type)); } if (srcSlot != null) { VFXSlot.CopyLinksAndValue(dstSlot, srcSlot, notify); srcSlot.UnlinkAll(true, notify); existingSlots.Remove(srcSlot); } } // Remove all remaining links foreach (var slot in existingSlots) { slot.UnlinkAll(true, notify); } // Add all slots foreach (var s in newSlots) { InnerAddSlot(s, -1, false); } if (notify) { Invalidate(InvalidationCause.kStructureChanged); } } else { // Update properties for (int i = 0; i < nbSlots; ++i) { VFXProperty prop = currentSlots[i].property; currentSlots[i].UpdateAttributes(expectedProperties[i].property.attributes); } } return(recreate); }
public VFXPropertyWithValue(VFXProperty property, object value = null) { this.property = property; this.value = value; }