static public VFXExpression ApplyAddressingMode(VFXExpression index, VFXExpression count, SequentialAddressingMode mode)
        {
            VFXExpression r = null;

            if (mode == SequentialAddressingMode.Wrap)
            {
                r = Modulo(index, count);
            }
            else if (mode == SequentialAddressingMode.Clamp)
            {
                var countMinusOne = count - OneExpression[VFXValueType.Uint32];
                r = new VFXExpressionMin(index, countMinusOne);
            }
            else if (mode == SequentialAddressingMode.Mirror)
            {
                var two   = TwoExpression[VFXValueType.Uint32];
                var cycle = count * two - two;
                cycle = new VFXExpressionMax(cycle, OneExpression[VFXValueType.Uint32]);
                var modulo = Modulo(index, cycle);
                //var compare = new VFXExpressionCondition(VFXCondition.Less, new VFXExpressionCastUintToFloat(modulo), new VFXExpressionCastUintToFloat(count)); <= Use this line for 7.x.x/8.x.x/9.x.x backport
                var compare = new VFXExpressionCondition(VFXValueType.Uint32, VFXCondition.Less, modulo, count);
                r = new VFXExpressionBranch(compare, modulo, cycle - modulo);
            }
            return(r);
        }
        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);
        }