Beispiel #1
0
        public static string AdaptNodeOutput(AbstractMaterialNode node, int outputSlotId, ConcreteSlotValueType convertToType)
        {
            var outputSlot = node.FindOutputSlot <MaterialSlot>(outputSlotId);

            if (outputSlot == null)
            {
                return(kErrorString);
            }

            var convertFromType = outputSlot.concreteValueType;
            var rawOutput       = node.GetVariableNameForSlot(outputSlotId);

            if (convertFromType == convertToType)
            {
                return(rawOutput);
            }

            switch (convertToType)
            {
            case ConcreteSlotValueType.Vector1:
                return(string.Format("({0}).x", rawOutput));

            case ConcreteSlotValueType.Vector2:
                switch (convertFromType)
                {
                case ConcreteSlotValueType.Vector1:
                    return(string.Format("({0}.xx)", rawOutput));

                case ConcreteSlotValueType.Vector3:
                case ConcreteSlotValueType.Vector4:
                    return(string.Format("({0}.xy)", rawOutput));

                default:
                    return(kErrorString);
                }

            case ConcreteSlotValueType.Vector3:
                switch (convertFromType)
                {
                case ConcreteSlotValueType.Vector1:
                    return(string.Format("({0}.xxx)", rawOutput));

                case ConcreteSlotValueType.Vector2:
                    return(string.Format("({0}3({1}, 0.0))", node.precision, rawOutput));

                case ConcreteSlotValueType.Vector4:
                    return(string.Format("({0}.xyz)", rawOutput));

                default:
                    return(kErrorString);
                }

            case ConcreteSlotValueType.Vector4:
                switch (convertFromType)
                {
                case ConcreteSlotValueType.Vector1:
                    return(string.Format("({0}.xxxx)", rawOutput));

                case ConcreteSlotValueType.Vector2:
                    return(string.Format("({0}4({1}, 0.0, 1.0))", node.precision, rawOutput));

                case ConcreteSlotValueType.Vector3:
                    return(string.Format("({0}4({1}, 1.0))", node.precision, rawOutput));

                default:
                    return(kErrorString);
                }

            case ConcreteSlotValueType.Matrix3:
                return(rawOutput);

            case ConcreteSlotValueType.Matrix2:
                return(rawOutput);

            default:
                return(kErrorString);
            }
        }
Beispiel #2
0
 public static string ToClassName(this ConcreteSlotValueType type)
 {
     return(k_ConcreteSlotValueTypeClassNames[(int)type]);
 }
        public static string ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision p, ConcreteSlotValueType slotValue)
        {
            switch (slotValue)
            {
            case ConcreteSlotValueType.Boolean:
                return(p.ToString());

            case ConcreteSlotValueType.Vector1:
                return(p.ToString());

            case ConcreteSlotValueType.Vector2:
                return(p + "2");

            case ConcreteSlotValueType.Vector3:
                return(p + "3");

            case ConcreteSlotValueType.Vector4:
                return(p + "4");

            case ConcreteSlotValueType.Texture2D:
                return("Texture2D");

            case ConcreteSlotValueType.Cubemap:
                return("Cubemap");

            case ConcreteSlotValueType.Matrix2:
                return(p + "2x2");

            case ConcreteSlotValueType.Matrix3:
                return(p + "3x3");

            case ConcreteSlotValueType.Matrix4:
                return(p + "4x4");

            case ConcreteSlotValueType.SamplerState:
                return("SamplerState");

            default:
                return("Error");
            }
        }
Beispiel #4
0
        // Internal validation
        // -------------------------------------------------

        public override void ValidateNode()
        {
            var isInError    = false;
            var errorMessage = k_validationErrorMessage;

            // all children nodes needs to be updated first
            // so do that here
            var slots = ListPool <MaterialSlot> .Get();

            GetInputSlots(slots);
            foreach (var inputSlot in slots)
            {
                inputSlot.hasError = false;

                var edges = owner.GetEdges(inputSlot.slotReference);
                foreach (var edge in edges)
                {
                    var fromSocketRef = edge.outputSlot;
                    var outputNode    = owner.GetNodeFromGuid(fromSocketRef.nodeGuid);
                    if (outputNode == null)
                    {
                        continue;
                    }

                    outputNode.ValidateNode();
                }
            }
            ListPool <MaterialSlot> .Release(slots);

            var dynamicInputSlotsToCompare = DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicSlots = ListPool <DynamicValueMaterialSlot> .Get();

            // iterate the input slots
            s_TempSlots.Clear();
            GetInputSlots(s_TempSlots);
            foreach (var inputSlot in s_TempSlots)
            {
                // if there is a connection
                var edges = owner.GetEdges(inputSlot.slotReference).ToList();
                if (!edges.Any())
                {
                    if (inputSlot is DynamicValueMaterialSlot)
                    {
                        skippedDynamicSlots.Add(inputSlot as DynamicValueMaterialSlot);
                    }
                    continue;
                }

                // get the output details
                var outputSlotRef = edges[0].outputSlot;
                var outputNode    = owner.GetNodeFromGuid(outputSlotRef.nodeGuid);
                if (outputNode == null)
                {
                    continue;
                }

                var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId);
                if (outputSlot == null)
                {
                    continue;
                }

                if (outputSlot.hasError)
                {
                    inputSlot.hasError = true;
                    continue;
                }

                var outputConcreteType = outputSlot.concreteValueType;
                // dynamic input... depends on output from other node.
                // we need to compare ALL dynamic inputs to make sure they
                // are compatable.
                if (inputSlot is DynamicValueMaterialSlot)
                {
                    dynamicInputSlotsToCompare.Add((DynamicValueMaterialSlot)inputSlot, outputConcreteType);
                    continue;
                }

                // if we have a standard connection... just check the types work!
                if (!ImplicitConversionExists(outputConcreteType, inputSlot.concreteValueType))
                {
                    inputSlot.hasError = true;
                }
            }

            m_MultiplyType = GetMultiplyType(dynamicInputSlotsToCompare.Values);

            // Resolve dynamics depending on matrix/vector configuration
            switch (m_MultiplyType)
            {
            // If all matrix resolve as per dynamic matrix
            case MultiplyType.Matrix:
                var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicMatrixType);
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(dynamicMatrixType);
                }
                break;

            // If mixed handle differently:
            // Iterate all slots and set their concretes based on their edges
            // Find matrix slot and convert its type to a vector type
            // Reiterate all slots and set non matrix slots to the vector type
            case MultiplyType.Mixed:
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    SetConcreteValueTypeFromEdge(dynamicKvP.Key);
                }
                MaterialSlot          matrixSlot = GetMatrixSlot();
                ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    if (dynamicKvP.Key != matrixSlot)
                    {
                        dynamicKvP.Key.SetConcreteType(vectorType);
                    }
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(vectorType);
                }
                break;

            // If all vector resolve as per dynamic vector
            default:
                var dynamicVectorType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicVectorType);
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(dynamicVectorType);
                }
                break;
            }

            s_TempSlots.Clear();
            GetInputSlots(s_TempSlots);
            var inputError = s_TempSlots.Any(x => x.hasError);

            // configure the output slots now
            // their slotType will either be the default output slotType
            // or the above dynanic slotType for dynamic nodes
            // or error if there is an input error
            s_TempSlots.Clear();
            GetOutputSlots(s_TempSlots);
            foreach (var outputSlot in s_TempSlots)
            {
                outputSlot.hasError = false;

                if (inputError)
                {
                    outputSlot.hasError = true;
                    continue;
                }

                if (outputSlot is DynamicValueMaterialSlot)
                {
                    // Apply similar logic to output slot
                    switch (m_MultiplyType)
                    {
                    // As per dynamic matrix
                    case MultiplyType.Matrix:
                        var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                        (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicMatrixType);
                        break;

                    // Mixed configuration
                    // Find matrix slot and convert type to vector
                    // Set output concrete to vector
                    case MultiplyType.Mixed:
                        MaterialSlot          matrixSlot = GetMatrixSlot();
                        ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                        (outputSlot as DynamicValueMaterialSlot).SetConcreteType(vectorType);
                        break;

                    // As per dynamic vector
                    default:
                        var dynamicVectorType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                        (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicVectorType);
                        break;
                    }
                    continue;
                }
            }

            isInError |= inputError;
            s_TempSlots.Clear();
            GetOutputSlots(s_TempSlots);
            isInError |= s_TempSlots.Any(x => x.hasError);
            isInError |= CalculateNodeHasError(ref errorMessage);
            hasError   = isInError;

            if (isInError)
            {
                ((GraphData)owner).AddValidationError(tempId, errorMessage);
            }
            else
            {
                ++version;
            }

            ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);
        }
Beispiel #5
0
 public void SetConcreteType(ConcreteSlotValueType valueType)
 {
     m_ConcreteValueType = valueType;
 }
Beispiel #6
0
        // Internal validation
        // -------------------------------------------------

        public override void EvaluateDynamicMaterialSlots(List <MaterialSlot> inputSlots, List <MaterialSlot> outputSlots)
        {
            var dynamicInputSlotsToCompare = DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicSlots = ListPool <DynamicValueMaterialSlot> .Get();

            // iterate the input slots
            {
                foreach (var inputSlot in inputSlots)
                {
                    inputSlot.hasError = false;

                    // if there is a connection
                    var edges = owner.GetEdges(inputSlot.slotReference).ToList();
                    if (!edges.Any())
                    {
                        if (inputSlot is DynamicValueMaterialSlot)
                        {
                            skippedDynamicSlots.Add(inputSlot as DynamicValueMaterialSlot);
                        }
                        continue;
                    }

                    // get the output details
                    var outputSlotRef = edges[0].outputSlot;
                    var outputNode    = outputSlotRef.node;
                    if (outputNode == null)
                    {
                        continue;
                    }

                    var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId);
                    if (outputSlot == null)
                    {
                        continue;
                    }

                    if (outputSlot.hasError)
                    {
                        inputSlot.hasError = true;
                        continue;
                    }

                    var outputConcreteType = outputSlot.concreteValueType;
                    // dynamic input... depends on output from other node.
                    // we need to compare ALL dynamic inputs to make sure they
                    // are compatable.
                    if (inputSlot is DynamicValueMaterialSlot)
                    {
                        dynamicInputSlotsToCompare.Add((DynamicValueMaterialSlot)inputSlot, outputConcreteType);
                        continue;
                    }
                }

                m_MultiplyType = GetMultiplyType(dynamicInputSlotsToCompare.Values);

                // Resolve dynamics depending on matrix/vector configuration
                switch (m_MultiplyType)
                {
                // If all matrix resolve as per dynamic matrix
                case MultiplyType.Matrix:
                    var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                    foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                    {
                        dynamicKvP.Key.SetConcreteType(dynamicMatrixType);
                    }
                    foreach (var skippedSlot in skippedDynamicSlots)
                    {
                        skippedSlot.SetConcreteType(dynamicMatrixType);
                    }
                    break;

                // If mixed handle differently:
                // Iterate all slots and set their concretes based on their edges
                // Find matrix slot and convert its type to a vector type
                // Reiterate all slots and set non matrix slots to the vector type
                case MultiplyType.Mixed:
                    foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                    {
                        SetConcreteValueTypeFromEdge(dynamicKvP.Key);
                    }
                    MaterialSlot          matrixSlot = GetMatrixSlot();
                    ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                    foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                    {
                        if (dynamicKvP.Key != matrixSlot)
                        {
                            dynamicKvP.Key.SetConcreteType(vectorType);
                        }
                    }
                    foreach (var skippedSlot in skippedDynamicSlots)
                    {
                        skippedSlot.SetConcreteType(vectorType);
                    }
                    break;

                // If all vector resolve as per dynamic vector
                default:
                    var dynamicVectorType = ConvertDynamicVectorInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                    foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                    {
                        dynamicKvP.Key.SetConcreteType(dynamicVectorType);
                    }
                    foreach (var skippedSlot in skippedDynamicSlots)
                    {
                        skippedSlot.SetConcreteType(dynamicVectorType);
                    }
                    break;
                }

                bool inputError = inputSlots.Any(x => x.hasError);
                if (inputError)
                {
                    owner.AddConcretizationError(objectId, string.Format("Node {0} had input error", objectId));
                    hasError = true;
                }
                // configure the output slots now
                // their slotType will either be the default output slotType
                // or the above dynanic slotType for dynamic nodes
                // or error if there is an input error
                foreach (var outputSlot in outputSlots)
                {
                    outputSlot.hasError = false;

                    if (inputError)
                    {
                        outputSlot.hasError = true;
                        continue;
                    }

                    if (outputSlot is DynamicValueMaterialSlot)
                    {
                        // Apply similar logic to output slot
                        switch (m_MultiplyType)
                        {
                        // As per dynamic matrix
                        case MultiplyType.Matrix:
                            var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                            (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicMatrixType);
                            break;

                        // Mixed configuration
                        // Find matrix slot and convert type to vector
                        // Set output concrete to vector
                        case MultiplyType.Mixed:
                            MaterialSlot          matrixSlot = GetMatrixSlot();
                            ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                            (outputSlot as DynamicValueMaterialSlot).SetConcreteType(vectorType);
                            break;

                        // As per dynamic vector
                        default:
                            var dynamicVectorType = ConvertDynamicVectorInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                            (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicVectorType);
                            break;
                        }
                        continue;
                    }
                }

                if (outputSlots.Any(x => x.hasError))
                {
                    owner.AddConcretizationError(objectId, string.Format("Node {0} had output error", objectId));
                    hasError = true;
                }
            }

            CalculateNodeHasError();

            ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);
        }
 public static string ToString(this ConcreteSlotValueType type, AbstractMaterialNode.OutputPrecision precision)
 {
     return(NodeUtils.ConvertConcreteSlotValueTypeToString(precision, type));
 }
        public static bool AreCompatible(SlotValueType inputType, ConcreteSlotValueType outputType)
        {
            if (s_ValidConversions == null)
            {
                var validVectors = new List <SlotValueType>()
                {
                    SlotValueType.Dynamic, SlotValueType.DynamicVector,
                    SlotValueType.Vector1, SlotValueType.Vector2, SlotValueType.Vector3, SlotValueType.Vector4
                };

                s_ValidConversions = new Dictionary <ConcreteSlotValueType, List <SlotValueType> >()
                {
                    { ConcreteSlotValueType.Boolean, new List <SlotValueType>()
                      {
                          SlotValueType.Boolean
                      } },
                    { ConcreteSlotValueType.Vector1, validVectors },
                    { ConcreteSlotValueType.Vector2, validVectors },
                    { ConcreteSlotValueType.Vector3, validVectors },
                    { ConcreteSlotValueType.Vector4, validVectors },
                    { ConcreteSlotValueType.Matrix2, new List <SlotValueType>()
                      {
                          SlotValueType.Dynamic, SlotValueType.DynamicMatrix, SlotValueType.Matrix2
                      } },
                    { ConcreteSlotValueType.Matrix3, new List <SlotValueType>()
                      {
                          SlotValueType.Dynamic, SlotValueType.DynamicMatrix, SlotValueType.Matrix2, SlotValueType.Matrix3
                      } },
                    { ConcreteSlotValueType.Matrix4, new List <SlotValueType>()
                      {
                          SlotValueType.Dynamic, SlotValueType.DynamicMatrix, SlotValueType.Matrix2, SlotValueType.Matrix3, SlotValueType.Matrix4
                      } },
                    { ConcreteSlotValueType.Texture2D, new List <SlotValueType>()
                      {
                          SlotValueType.Texture2D
                      } },
                    { ConcreteSlotValueType.Texture3D, new List <SlotValueType>()
                      {
                          SlotValueType.Texture3D
                      } },
                    { ConcreteSlotValueType.Texture2DArray, new List <SlotValueType>()
                      {
                          SlotValueType.Texture2DArray
                      } },
                    { ConcreteSlotValueType.Cubemap, new List <SlotValueType>()
                      {
                          SlotValueType.Cubemap
                      } },
                    { ConcreteSlotValueType.SamplerState, new List <SlotValueType>()
                      {
                          SlotValueType.SamplerState
                      } },
                    { ConcreteSlotValueType.Gradient, new List <SlotValueType>()
                      {
                          SlotValueType.Gradient
                      } },
                };
            }

            if (s_ValidConversions.TryGetValue(outputType, out s_ValidSlotTypes))
            {
                return(s_ValidSlotTypes.Contains(inputType));
            }
            throw new ArgumentOutOfRangeException("Unknown Concrete Slot Type: " + outputType);
        }
Beispiel #9
0
        public static ConcreteSlotValueTypePopupName ToConcreteSlotValueTypePopupName(this ConcreteSlotValueType slotType, bool isBareResource)
        {
            ConcreteSlotValueTypePopupName result = (ConcreteSlotValueTypePopupName)slotType;

            switch (slotType)
            {
            case ConcreteSlotValueType.SamplerState:
                if (isBareResource)
                {
                    result = ConcreteSlotValueTypePopupName.BareSamplerState;
                }
                break;

            case ConcreteSlotValueType.Texture2D:
                if (isBareResource)
                {
                    result = ConcreteSlotValueTypePopupName.BareTexture2D;
                }
                break;

            case ConcreteSlotValueType.Texture2DArray:
                if (isBareResource)
                {
                    result = ConcreteSlotValueTypePopupName.BareTexture2DArray;
                }
                break;

            case ConcreteSlotValueType.Texture3D:
                if (isBareResource)
                {
                    result = ConcreteSlotValueTypePopupName.BareTexture3D;
                }
                break;

            case ConcreteSlotValueType.Cubemap:
                if (isBareResource)
                {
                    result = ConcreteSlotValueTypePopupName.BareCubemap;
                }
                break;
            }
            return(result);
        }