Exemple #1
0
        public static void ToOperatorWithoutFloatN(VFXOperator input, Type outputType)
        {
            if (!input.inputSlots.Where(o => o.property.type == typeof(FloatN)).Any())
            {
                Debug.LogError("SanitizeToOperatorNew is dedicated to operator using FloatN " + input);
                return;
            }

            var realTypeAndValue = input.inputSlots.Select(o =>
            {
                Type type      = null;
                object value   = null;
                bool wasFloatN = o.property.type == typeof(FloatN);
                if (!wasFloatN)
                {
                    type  = o.property.type;
                    value = o.HasLink() ? null : o.value;
                }
                else
                {
                    if (o.HasLink())
                    {
                        type = o.LinkedSlots.First().property.type;
                    }
                    else
                    {
                        var floatN = (FloatN)o.value;
                        type       = floatN.GetCurrentType();
                        value      = (FloatN)o.value;
                    }
                }
                return(new
                {
                    type = type,
                    value = value,
                    wasFloatN = wasFloatN
                });
            }).ToArray();

            var output = ScriptableObject.CreateInstance(outputType) as VFXOperatorDynamicOperand;

            //Transfer settings
            var settingsIn  = input.GetSettings(true).Where(o => o.FieldType != typeof(SerializableType));
            var settingsOut = output.GetSettings(true).Where(o => o.FieldType != typeof(SerializableType));

            if (settingsIn.Count() != settingsOut.Count())
            {
                Debug.LogError("Settings has been changed, unable to automatically transfer them");
                return;
            }

            var itSettingIn  = settingsIn.GetEnumerator();
            var itSettingOut = settingsOut.GetEnumerator();

            while (itSettingIn.MoveNext() && itSettingOut.MoveNext())
            {
                if (itSettingIn.Current.Name != itSettingOut.Current.Name.Replace("m_", string.Empty))
                {
                    Debug.Log(string.Format("Unexpected settings : {0} vs {1}", itSettingIn.Current.Name, itSettingOut.Current.Name));
                    return;
                }
                output.SetSettingValue(itSettingOut.Current.Name, itSettingIn.Current.GetValue(input));
            }

            //Apply dynamic type behavior
            if (output is IVFXOperatorUniform)
            {
                var uniform = output as IVFXOperatorUniform;
                var maxType = realTypeAndValue.Where(o => o.wasFloatN && o.type != typeof(FloatN))
                              .Select(o => o.type)
                              .OrderBy(o => VFXExpression.TypeToSize(VFXExpression.GetVFXValueTypeFromType(o)))
                              .LastOrDefault();

                if (maxType != null)
                {
                    //ignore int/uint while sanitizing
                    if (maxType == typeof(int) || maxType == typeof(uint))
                    {
                        maxType = typeof(float);
                    }

                    maxType = output.GetBestAffinityType(maxType);
                    uniform.SetOperandType(maxType);
                }
            }
            else if (output is VFXOperatorNumericCascadedUnified)
            {
                var cascaded = output as VFXOperatorNumericCascadedUnified;
                //Remove all empty last operand (has influence of output type for append)
                realTypeAndValue = realTypeAndValue.Reverse().SkipWhile(o => o.type == typeof(FloatN)).Reverse().ToArray();

                while (cascaded.inputSlots.Count < realTypeAndValue.Length)
                {
                    cascaded.AddOperand();
                }

                for (int i = 0; i < realTypeAndValue.Length; ++i)
                {
                    var currentType = cascaded.GetBestAffinityType(realTypeAndValue[i].type);
                    if (currentType != null)
                    {
                        cascaded.SetOperandType(i, currentType);
                    }
                }
            }
            else if (output is VFXOperatorNumericUnified)
            {
                var unified = output as VFXOperatorNumericUnified;
                var slotIndiceThatShouldHaveSameType = Enumerable.Empty <int>();
                var slotIndiceThatCanBeScale         = Enumerable.Empty <int>();
                if (output is IVFXOperatorNumericUnifiedConstrained)
                {
                    slotIndiceThatShouldHaveSameType = (output as IVFXOperatorNumericUnifiedConstrained).slotIndicesThatMustHaveSameType;
                    slotIndiceThatCanBeScale         = (output as IVFXOperatorNumericUnifiedConstrained).slotIndicesThatCanBeScalar;
                }

                Type maxTypeConstrained = null;
                if (slotIndiceThatShouldHaveSameType.Any())
                {
                    var typeConstrained = slotIndiceThatShouldHaveSameType.Select(i =>
                    {
                        if (i < realTypeAndValue.Length)
                        {
                            return(realTypeAndValue[i].type);
                        }
                        return((Type)null);
                    }).Where(o => o != null);

                    if (!typeConstrained.Any())
                    {
                        Debug.LogError("Unexpected behavior while sanitizing to unified constrained");
                        return;
                    }
                    maxTypeConstrained = typeConstrained.OrderBy(o => VFXExpression.TypeToSize(VFXExpression.GetVFXValueTypeFromType(o))).LastOrDefault();
                }

                for (int i = 0; i < realTypeAndValue.Length; ++i)
                {
                    var currentType = realTypeAndValue[i].type;
                    if (slotIndiceThatShouldHaveSameType.Contains(i) &&
                        !(slotIndiceThatCanBeScale.Contains(i) && VFXExpression.GetMatchingScalar(currentType) == currentType))
                    {
                        currentType = maxTypeConstrained;
                    }
                    currentType = output.GetBestAffinityType(currentType);
                    if (currentType != null)
                    {
                        unified.SetOperandType(i, currentType);
                    }
                }
            }
            else
            {
                Debug.LogError("Unable to determine what kind of " + output.GetType());
                return;
            }

            for (int i = 0; i < realTypeAndValue.Length; ++i)
            {
                var current = realTypeAndValue[i];
                if (!current.wasFloatN)
                {
                    VFXSlot.CopyLinksAndValue(output.inputSlots[i], input.inputSlots[i], true);
                }
                else
                {
                    if (current.value == null)
                    {
                        var slotDst = output.inputSlots[i];
                        var slotSrc = input.inputSlots[i].LinkedSlots.First();
                        if (slotSrc.CanLink(slotDst))
                        {
                            //Main path (most common case)
                            VFXSlot.CopyLinks(output.inputSlots[i], input.inputSlots[i], true);
                        }
                        else
                        {
                            //Trying to connect by subslot (e.g. : Vector4 to Vector3)
                            var itSubSlotSrc = slotSrc.children.GetEnumerator();
                            var itSubSlotDst = slotDst.children.GetEnumerator();
                            while (itSubSlotDst.MoveNext() && itSubSlotSrc.MoveNext())
                            {
                                itSubSlotSrc.Current.Link(itSubSlotDst.Current);
                            }
                        }
                    }
                    else
                    {
                        object orgValue   = null;
                        var    floatN     = (FloatN)current.value;
                        var    targetType = output.inputSlots[i].property.type;
                        if (targetType == typeof(float))
                        {
                            orgValue = (float)floatN;
                        }
                        else if (targetType == typeof(Vector2))
                        {
                            orgValue = (Vector2)floatN;
                        }
                        else if (targetType == typeof(Vector3))
                        {
                            orgValue = (Vector3)floatN;
                        }
                        else if (targetType == typeof(Vector4))
                        {
                            orgValue = (Vector4)floatN;
                        }
                        else
                        {
                            Debug.LogError("Unexpected type of FloatN while sanitizing : " + targetType);
                            return;
                        }
                        output.inputSlots[i].value = orgValue;
                    }
                }
            }

            for (int i = 0; i < input.outputSlots.Count; ++i)
            {
                VFXSlot.CopyLinks(output.outputSlots[i], input.outputSlots[i], true);
            }
            VFXModel.ReplaceModel(output, input);
        }