using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.VFX; namespace UnityEditor.VFX.Operator { [VFXHelpURL("Operator-Switch")] [VFXInfo(category = "Logic", synonyms = new []{ "Select" })] class Switch : VFXOperatorDynamicBranch { [VFXSetting(VFXSettingAttribute.VisibleFlags.Default), SerializeField, Tooltip("Sets the number of switch cases.")] uint m_EntryCount = 2u; [VFXSetting(VFXSettingAttribute.VisibleFlags.InInspector), SerializeField] bool m_CustomCaseValue = false; public class TestInputProperties { [Tooltip("Sets the integer value that determines which entry is output.")] public uint testValue = 0; } public class ManualRandom { [Tooltip("Random Value")] public float rand = 0.0f; } public sealed override string name { get { return "Switch"; } } public override sealed IEnumerable staticSlotIndex { get { yield return 0; //TestInputProperties if (m_CustomCaseValue) { var offset = 1; var stride = expressionCountPerUniqueSlot + 1; do { yield return offset; offset += stride; } while (offset < stride * m_EntryCount + 1); } } } protected override Type defaultValueType { get { return typeof(Color); } } protected override void OnInvalidate(VFXModel model, InvalidationCause cause) { if (m_EntryCount < 1) m_EntryCount = 1; if (m_EntryCount > 32) m_EntryCount = 32; base.OnInvalidate(model, cause); } protected sealed override IEnumerable inputProperties { get { var baseInputProperties = base.inputProperties; //returns value is unused but there is a lazy init in input var manualRandomProperties = PropertiesFromType("TestInputProperties"); foreach (var property in manualRandomProperties) yield return property; var defaultValue = GetDefaultValueForType(GetOperandType()); for (uint i = 0; i < m_EntryCount + 1; ++i) { var prefix = i.ToString(); if (i != m_EntryCount && m_CustomCaseValue) yield return new VFXPropertyWithValue(new VFXProperty(typeof(uint), "Case " + prefix), i); var name = (i == m_EntryCount) ? "default" : "Value " + prefix; yield return new VFXPropertyWithValue(new VFXProperty((Type)GetOperandType(), name), defaultValue); } } } protected sealed override VFXExpression[] BuildExpression(VFXExpression[] inputExpression) { var expressionCountPerUniqueSlot = this.expressionCountPerUniqueSlot; if (!m_CustomCaseValue) { //Insert Case (0,1,..) entries manually var newInputExpression = new VFXExpression[1 /* entry */ + m_EntryCount * (expressionCountPerUniqueSlot + 1 /* case */) + expressionCountPerUniqueSlot /* default */]; newInputExpression[0] = inputExpression[0]; int offsetWrite = 1; int offsetRead = 1; for (uint i = 0; i < m_EntryCount + 1; ++i) { if (i != m_EntryCount) newInputExpression[offsetWrite++] = new VFXValue(i); for (int sub = 0; sub < expressionCountPerUniqueSlot; ++sub) { newInputExpression[offsetWrite++] = inputExpression[offsetRead++]; } } inputExpression = newInputExpression; } var referenceValue = inputExpression.First(); var startCaseOffset = 1; var stride = expressionCountPerUniqueSlot + 1; var compare = new VFXExpression[m_EntryCount]; int offsetCase = startCaseOffset; var valueStartIndex = new int[m_EntryCount + 1]; for (uint i = 0; i < m_EntryCount; i++) { valueStartIndex[i] = offsetCase + 1; compare[i] = new VFXExpressionCondition(VFXValueType.Uint32, VFXCondition.Equal, referenceValue, inputExpression[offsetCase]); offsetCase += stride; } valueStartIndex[m_EntryCount] = inputExpression.Length - expressionCountPerUniqueSlot; //Last is default value, without a case return ChainedBranchResult(compare, inputExpression, valueStartIndex); } } }