public static VFXExpression ApplyToExpressionGraph(VFXPropertyAttribute[] attributes, VFXExpression exp)
        {
            if (attributes != null)
            {
                foreach (VFXPropertyAttribute attribute in attributes)
                {
                    switch (attribute.m_Type)
                    {
                    case Type.kRange:
                        exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant(attribute.m_Min), VFXValue.Constant(attribute.m_Max));
                        break;

                    case Type.kMin:
                        exp = new VFXExpressionMax(exp, VFXOperatorUtility.CastFloat(VFXValue.Constant(attribute.m_Min), exp.valueType));
                        break;

                    case Type.kNormalize:
                        exp = VFXOperatorUtility.Normalize(exp);
                        break;

                    case Type.kTooltip:
                    case Type.kAngle:
                    case Type.kColor:
                    case Type.kRegex:
                    case Type.kDelayed:
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }

            return(exp);
        }
 sealed protected override VFXExpression ConvertExpression(VFXExpression expression, VFXSlot sourceSlot)
 {
     if (expression.valueType == VFXValueType.Float3)
     {
         return(VFXOperatorUtility.CastFloat(expression, VFXValueType.Float4, 1.0f));
     }
     return(base.ConvertExpression(expression, sourceSlot));
 }
        protected override IEnumerable <VFXExpression> ApplyPatchInputExpression(IEnumerable <VFXExpression> inputExpression)
        {
            var minIndex    = inputExpression.Select(o => Array.IndexOf(kExpectedTypeOrdering, VFXExpression.TypeToType(o.valueType))).Min();
            var unifiedType = VFXExpression.GetVFXValueTypeFromType(kExpectedTypeOrdering[minIndex]);

            foreach (var expression in inputExpression)
            {
                if (expression.valueType == unifiedType)
                {
                    yield return(expression);

                    continue;
                }

                var currentExpression = expression;
                if (VFXExpression.IsFloatValueType(unifiedType))
                {
                    if (VFXExpression.IsUIntValueType(expression.valueType))
                    {
                        currentExpression = new VFXExpressionCastUintToFloat(currentExpression);
                    }
                    else if (VFXExpression.IsIntValueType(expression.valueType))
                    {
                        currentExpression = new VFXExpressionCastIntToFloat(currentExpression);
                    }
                    currentExpression = VFXOperatorUtility.CastFloat(currentExpression, unifiedType, identityValueFloat);
                }
                else if (VFXExpression.IsIntValueType(unifiedType))
                {
                    if (VFXExpression.IsUIntValueType(currentExpression.valueType))
                    {
                        currentExpression = new VFXExpressionCastUintToInt(currentExpression);
                    }
                    else if (VFXExpression.IsFloatValueType(currentExpression.valueType))
                    {
                        currentExpression = new VFXExpressionCastFloatToInt(VFXOperatorUtility.ExtractComponents(currentExpression).First());
                    }
                }
                else if (VFXExpression.IsUIntValueType(unifiedType))
                {
                    if (VFXExpression.IsIntValueType(currentExpression.valueType))
                    {
                        currentExpression = new VFXExpressionCastIntToUint(currentExpression);
                    }
                    else if (VFXExpression.IsFloatValueType(expression.valueType))
                    {
                        currentExpression = new VFXExpressionCastFloatToUint(VFXOperatorUtility.ExtractComponents(expression).First());
                    }
                }
                yield return(currentExpression);
            }
        }
        sealed protected override VFXExpression ConvertExpression(VFXExpression expression, VFXSlot sourceSlot)
        {
            if (sourceSlot != null)
            {
                if (sourceSlot.GetType() == typeof(VFXSlotDirection))
                {
                    return(expression); //avoid multiple normalization
                }
                if (sourceSlot.property.attributes != null && sourceSlot.property.attributes.OfType <NormalizeAttribute>().Any())
                {
                    return(expression); //avoid multiple normalization from Normalize attribute (rarely used for output slot)
                }
            }

            if (expression.valueType == VFXValueType.Float4)
            {
                expression = VFXOperatorUtility.CastFloat(expression, VFXValueType.Float3);
            }

            return(ApplyPatchExpression(expression));
        }
        public static VFXExpression ApplyToExpressionGraph(VFXPropertyAttribute[] attributes, VFXExpression exp)
        {
            if (attributes != null)
            {
                foreach (VFXPropertyAttribute attribute in attributes)
                {
                    switch (attribute.m_Type)
                    {
                    case Type.kRange:
                        switch (exp.valueType)
                        {
                        case VFXValueType.Int32:
                            exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant((int)attribute.m_Min), VFXValue.Constant((int)attribute.m_Max), false);
                            break;

                        case VFXValueType.Uint32:
                            exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant((uint)attribute.m_Min), VFXValue.Constant((uint)attribute.m_Max), false);
                            break;

                        case VFXValueType.Float:
                        case VFXValueType.Float2:
                        case VFXValueType.Float3:
                        case VFXValueType.Float4:
                            exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant(attribute.m_Min), VFXValue.Constant(attribute.m_Max));
                            break;

                        default:
                            throw new NotImplementedException(string.Format("Cannot use RangeAttribute on value of type: {0}", exp.valueType));
                        }
                        break;

                    case Type.kMin:
                        switch (exp.valueType)
                        {
                        case VFXValueType.Int32:
                            exp = new VFXExpressionMax(exp, VFXValue.Constant((int)attribute.m_Min));
                            break;

                        case VFXValueType.Uint32:
                            exp = new VFXExpressionMax(exp, VFXValue.Constant((uint)attribute.m_Min));
                            break;

                        case VFXValueType.Float:
                        case VFXValueType.Float2:
                        case VFXValueType.Float3:
                        case VFXValueType.Float4:
                            exp = new VFXExpressionMax(exp, VFXOperatorUtility.CastFloat(VFXValue.Constant(attribute.m_Min), exp.valueType));
                            break;

                        default:
                            throw new NotImplementedException(string.Format("Cannot use MinAttribute on value of type: {0}", exp.valueType));
                        }
                        break;

                    case Type.kNormalize:
                        exp = VFXOperatorUtility.Normalize(exp);
                        break;

                    case Type.kTooltip:
                    case Type.kAngle:
                    case Type.kColor:
                    case Type.kRegex:
                    case Type.kDelayed:
                    case Type.kBitField:
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }

            return(exp);
        }
        public VFXExpression ApplyToExpressionGraph(VFXExpression exp)
        {
            if (m_GraphAttributes == null)
            {
                return(exp);
            }

            foreach (PropertyAttribute attribute in m_GraphAttributes)
            {
                if (attribute is RangeAttribute)
                {
                    var rangeAttribute = (RangeAttribute)attribute;
                    switch (exp.valueType)
                    {
                    case VFXValueType.Int32:
                        exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant((int)rangeAttribute.min), VFXValue.Constant((int)rangeAttribute.max), false);
                        break;

                    case VFXValueType.Uint32:
                        exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant((uint)rangeAttribute.min), VFXValue.Constant((uint)rangeAttribute.max), false);
                        break;

                    case VFXValueType.Float:
                    case VFXValueType.Float2:
                    case VFXValueType.Float3:
                    case VFXValueType.Float4:
                        exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant(rangeAttribute.min), VFXValue.Constant(rangeAttribute.max));
                        break;

                    default:
                        throw new NotImplementedException(string.Format("Cannot use RangeAttribute on value of type: {0}", exp.valueType));
                    }
                }
                else if (attribute is MinAttribute)
                {
                    var minAttribute = (MinAttribute)attribute;
                    switch (exp.valueType)
                    {
                    case VFXValueType.Int32:
                        exp = new VFXExpressionMax(exp, VFXValue.Constant((int)minAttribute.min));
                        break;

                    case VFXValueType.Uint32:
                        exp = new VFXExpressionMax(exp, VFXValue.Constant((uint)minAttribute.min));
                        break;

                    case VFXValueType.Float:
                    case VFXValueType.Float2:
                    case VFXValueType.Float3:
                    case VFXValueType.Float4:
                        exp = new VFXExpressionMax(exp, VFXOperatorUtility.CastFloat(VFXValue.Constant(minAttribute.min), exp.valueType));
                        break;

                    default:
                        throw new NotImplementedException(string.Format("Cannot use MinAttribute on value of type: {0}", exp.valueType));
                    }
                }
                else if (attribute is NormalizeAttribute)
                {
                    exp = VFXOperatorUtility.Normalize(exp);
                }
                else if (attribute is EnumAttribute)
                {
                    var enumAttribute = (EnumAttribute)attribute;
                    exp = new VFXExpressionMin(exp, VFXValue.Constant((uint)enumAttribute.values.Length - 1));
                }
                else
                {
                    throw new NotImplementedException("Unrecognized expression attribute: " + attribute);
                }
            }

            return(exp);
        }