123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- using System;
- using System.Linq;
- using System.Runtime.CompilerServices;
- using UnityEngine;
- using UnityEngine.VFX;
- namespace UnityEditor.VFX
- {
- abstract class VFXExpressionNumericOperation : VFXExpression
- {
- protected VFXExpressionNumericOperation(VFXExpression[] parents)
- : base(Flags.None, parents)
- {
- m_additionnalOperands = new int[] { };
- }
- static private object[] ToObjectArray(float input) { return new object[] { input }; }
- static private object[] ToObjectArray(Vector2 input) { return new object[] { input.x, input.y }; }
- static private object[] ToObjectArray(Vector3 input) { return new object[] { input.x, input.y, input.z }; }
- static private object[] ToObjectArray(Vector4 input) { return new object[] { input.x, input.y, input.z, input.w }; }
- static protected object[] ToObjectArray(VFXExpression input)
- {
- switch (input.valueType)
- {
- case VFXValueType.Float: return ToObjectArray(input.Get<float>());
- case VFXValueType.Float2: return ToObjectArray(input.Get<Vector2>());
- case VFXValueType.Float3: return ToObjectArray(input.Get<Vector3>());
- case VFXValueType.Float4: return ToObjectArray(input.Get<Vector4>());
- case VFXValueType.Int32: return new object[] { input.Get<int>() };
- case VFXValueType.Uint32: return new object[] { input.Get<uint>() };
- case VFXValueType.Boolean: return new object[] { input.Get<bool>() };
- }
- return null;
- }
- static protected VFXExpression ToVFXValue(object[] input, VFXValue.Mode mode)
- {
- if (input[0] is int)
- {
- if (input.Length != 1)
- throw new InvalidOperationException("VFXExpressionMathOperation : Unexpected size of int");
- return new VFXValue<int>((int)input[0], mode);
- }
- else if (input[0] is uint)
- {
- if (input.Length != 1)
- throw new InvalidOperationException("VFXExpressionMathOperation : Unexpected size of uint");
- return new VFXValue<uint>((uint)input[0], mode);
- }
- else if (input[0] is bool)
- {
- if (input.Length != 1)
- throw new InvalidOperationException("VFXExpressionMathOperation : Unexpected size of bool");
- return new VFXValue<bool>((bool)input[0], mode);
- }
- else if (input[0] is float)
- {
- if (input.OfType<float>().Count() != input.Length)
- throw new InvalidOperationException("VFXExpressionMathOperation : Unexpected type of float among other float");
- switch (input.Length)
- {
- case 1: return new VFXValue<float>((float)input[0], mode);
- case 2: return new VFXValue<Vector2>(new Vector2((float)input[0], (float)input[1]), mode);
- case 3: return new VFXValue<Vector3>(new Vector3((float)input[0], (float)input[1], (float)input[2]), mode);
- case 4: return new VFXValue<Vector4>(new Vector4((float)input[0], (float)input[1], (float)input[2], (float)input[3]), mode);
- }
- }
- return null;
- }
- static protected bool IsNumeric(VFXValueType type)
- {
- return IsFloatValueType(type) || IsUIntValueType(type) || IsIntValueType(type) || IsBoolValueType(type);
- }
- sealed public override VFXExpressionOperation operation { get { return m_Operation; } }
- sealed protected override int[] additionnalOperands { get { return m_additionnalOperands; } }
- protected override VFXExpression Reduce(VFXExpression[] reducedParents)
- {
- var newExpression = (VFXExpressionNumericOperation)base.Reduce(reducedParents);
- newExpression.m_additionnalOperands = m_additionnalOperands.Select(o => o).ToArray();
- newExpression.m_Operation = m_Operation;
- return newExpression;
- }
- protected int[] m_additionnalOperands;
- protected VFXExpressionOperation m_Operation;
- }
- abstract class VFXExpressionUnaryNumericOperation : VFXExpressionNumericOperation
- {
- protected VFXExpressionUnaryNumericOperation(VFXExpression parent, VFXExpressionOperation operation) : base(new VFXExpression[1] { parent })
- {
- if (!IsNumeric(parent.valueType))
- {
- throw new ArgumentException("Incorrect VFXExpressionUnaryMathOperation");
- }
- m_additionnalOperands = new int[] { (int)parent.valueType };
- m_Operation = operation;
- }
- sealed protected override VFXExpression Evaluate(VFXExpression[] reducedParents)
- {
- var source = ToObjectArray(reducedParents[0]);
- var result = new object[source.Length];
- if (source[0] is float)
- {
- result = source.Select(o => (object)ProcessUnaryOperation((float)o)).ToArray();
- }
- else if (source[0] is int)
- {
- result = source.Select(o => (object)ProcessUnaryOperation((int)o)).ToArray();
- }
- else if (source[0] is uint)
- {
- result = source.Select(o => (object)ProcessUnaryOperation((uint)o)).ToArray();
- }
- else if (source[0] is bool)
- {
- result = source.Select(o => (object)ProcessUnaryOperation((bool)o)).ToArray();
- }
- else
- {
- throw new InvalidOperationException("Unexpected type in VFXExpressionUnaryMathOperation");
- }
- return ToVFXValue(result, VFXValue.Mode.Constant);
- }
- abstract protected float ProcessUnaryOperation(float input);
- abstract protected int ProcessUnaryOperation(int input);
- abstract protected uint ProcessUnaryOperation(uint input);
- abstract protected bool ProcessUnaryOperation(bool input);
- sealed public override string GetCodeString(string[] parents)
- {
- var valueType = this.parents.First().valueType;
- valueType = IsFloatValueType(valueType) ? VFXValueType.Float : valueType;
- return GetUnaryOperationCode(parents[0], valueType);
- }
- abstract protected string GetUnaryOperationCode(string x, VFXValueType type);
- }
- abstract class VFXExpressionBinaryNumericOperation : VFXExpressionNumericOperation
- {
- protected VFXExpressionBinaryNumericOperation(VFXExpression parentLeft, VFXExpression parentRight, VFXExpressionOperation operation)
- : base(new VFXExpression[2] { parentLeft, parentRight })
- {
- if (!IsNumeric(parentLeft.valueType) || !IsNumeric(parentRight.valueType))
- {
- throw new ArgumentException("Incorrect VFXExpressionBinaryMathOperation (not numeric type)");
- }
- if (parentRight.valueType != parentLeft.valueType)
- {
- throw new ArgumentException("Incorrect VFXExpressionBinaryFloatOperation (incompatible numeric type)");
- }
- m_additionnalOperands = new int[] { (int)parentLeft.valueType };
- m_Operation = operation;
- }
- sealed protected override VFXExpression Evaluate(VFXExpression[] reducedParents)
- {
- var parentLeft = reducedParents[0];
- var parentRight = reducedParents[1];
- var sourceLeft = ToObjectArray(parentLeft);
- var sourceRight = ToObjectArray(parentRight);
- var result = new object[sourceLeft.Length];
- if (sourceLeft[0] is float)
- {
- for (int iChannel = 0; iChannel < sourceLeft.Length; ++iChannel)
- {
- result[iChannel] = ProcessBinaryOperation((float)sourceLeft[iChannel], (float)sourceRight[iChannel]);
- }
- }
- else if (sourceLeft[0] is int)
- {
- for (int iChannel = 0; iChannel < sourceLeft.Length; ++iChannel)
- {
- result[iChannel] = ProcessBinaryOperation((int)sourceLeft[iChannel], (int)sourceRight[iChannel]);
- }
- }
- else if (sourceLeft[0] is uint)
- {
- for (int iChannel = 0; iChannel < sourceLeft.Length; ++iChannel)
- {
- result[iChannel] = ProcessBinaryOperation((uint)sourceLeft[iChannel], (uint)sourceRight[iChannel]);
- }
- }
- else if (sourceLeft[0] is bool)
- {
- for (int iChannel = 0; iChannel < sourceLeft.Length; ++iChannel)
- {
- result[iChannel] = ProcessBinaryOperation((bool)sourceLeft[iChannel], (bool)sourceRight[iChannel]);
- }
- }
- else
- {
- throw new InvalidOperationException("Unexpected type in VFXExpressionUnaryMathOperation");
- }
- return ToVFXValue(result, VFXValue.Mode.Constant);
- }
- abstract protected float ProcessBinaryOperation(float x, float y);
- abstract protected int ProcessBinaryOperation(int x, int y);
- abstract protected uint ProcessBinaryOperation(uint x, uint y);
- abstract protected bool ProcessBinaryOperation(bool x, bool y);
- sealed public override string GetCodeString(string[] parents)
- {
- var valueType = this.parents.First().valueType;
- valueType = IsFloatValueType(valueType) ? VFXValueType.Float : valueType;
- return GetBinaryOperationCode(parents[0], parents[1], valueType);
- }
- abstract protected string GetBinaryOperationCode(string x, string y, VFXValueType type);
- }
- }
|