Example #1
0
        public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
        {
            var inputValue = GetSlotValue(InputSlotId, generationMode);

            var inputSlot        = FindInputSlot <MaterialSlot>(InputSlotId);
            var numInputChannels = 0;

            if (inputSlot != null)
            {
                numInputChannels = SlotValueHelper.GetChannelCount(inputSlot.concreteValueType);
                if (numInputChannels > 4)
                {
                    numInputChannels = 0;
                }

                if (!owner.GetEdges(inputSlot.slotReference).Any())
                {
                    numInputChannels = 0;
                }
            }

            for (var i = 0; i < 4; i++)
            {
                var outputFormat = numInputChannels == 1 ? inputValue : string.Format("{0}[{1}]", inputValue, i);
                var outputValue  = i >= numInputChannels ? "0" : outputFormat;
                visitor.AddShaderChunk(string.Format("{0} {1} = {2};", precision, GetVariableNameForSlot(s_OutputSlots[i]), outputValue), true);
            }
        }
Example #2
0
        private static bool ImplicitConversionExists(ConcreteSlotValueType from, ConcreteSlotValueType to)
        {
            if (from == to)
            {
                return(true);
            }

            var fromCount = SlotValueHelper.GetChannelCount(from);
            var toCount   = SlotValueHelper.GetChannelCount(to);


            // can convert from v1 vectors :)
            if (from == ConcreteSlotValueType.Vector1 && toCount > 0)
            {
                return(true);
            }

            if (toCount == 0)
            {
                return(false);
            }

            if (toCount <= fromCount)
            {
                return(true);
            }

            return(false);
        }
Example #3
0
        void ValidateChannelCount()
        {
            int channelCount = SlotValueHelper.GetChannelCount(FindSlot <MaterialSlot>(InputSlotId).concreteValueType);

            if (channelMask >= 1 << channelCount)
            {
                channelMask = -1;
            }
        }
Example #4
0
 public bool IsCompatibleWith(MaterialSlot otherSlot)
 {
     return(otherSlot != null &&
            otherSlot.owner != owner &&
            otherSlot.isInputSlot != isInputSlot &&
            ((isInputSlot
              ? SlotValueHelper.AreCompatible(valueType, otherSlot.concreteValueType)
              : SlotValueHelper.AreCompatible(otherSlot.valueType, concreteValueType))));
 }
 protected override string ConcreteSlotValueAsVariable()
 {
     var channelCount = SlotValueHelper.GetChannelCount(concreteValueType);
     string values = NodeUtils.FloatToShaderValue(value.m00);
     if (channelCount == 1)
         return values;
     for (var i = 1; i < channelCount; i++)
         values += ", " + NodeUtils.FloatToShaderValue(value.GetRow(0)[i]);
     return string.Format("$precision{0}({1})", channelCount, values);
 }
Example #6
0
 public bool IsCompatibleWith(MaterialSlot otherSlot)
 {
     return(otherSlot != null &&
            otherSlot.owner != owner &&
            otherSlot.isInputSlot != isInputSlot &&
            !hidden &&
            !otherSlot.hidden &&
            ((isInputSlot
             ? SlotValueHelper.AreCompatible(valueType, otherSlot.concreteValueType, otherSlot.IsConnectionTestable())
             : SlotValueHelper.AreCompatible(otherSlot.valueType, concreteValueType, IsConnectionTestable()))));
 }
Example #7
0
        public override void ValidateNode()
        {
            base.ValidateNode();

            var inputValueType = FindInputSlot <MaterialSlot>(InputSlotId).concreteValueType;
            var InputValueSize = SlotValueHelper.GetChannelCount(inputValueType);

            if (!ValidateMaskInput(InputValueSize))
            {
                owner.AddValidationError(objectId, "Invalid mask for a Vector" + InputValueSize + " input.", ShaderCompilerMessageSeverity.Error);
            }
        }
Example #8
0
        public void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode)
        {
            ValidateChannelCount();
            registry.ProvideFunction(GetFunctionName(), s =>
            {
                int channelCount = SlotValueHelper.GetChannelCount(FindSlot <MaterialSlot>(InputSlotId).concreteValueType);
                s.AppendLine(GetFunctionPrototype("In", "Out"));
                using (s.BlockScope())
                {
                    if (channelMask == 0)
                    {
                        s.AppendLine("Out = 0;");
                    }
                    else if (channelMask == -1)
                    {
                        s.AppendLine("Out = In;");
                    }
                    else
                    {
                        bool red   = (channelMask & 1) != 0;
                        bool green = (channelMask & 2) != 0;
                        bool blue  = (channelMask & 4) != 0;
                        bool alpha = (channelMask & 8) != 0;

                        switch (channelCount)
                        {
                        case 1:
                            s.AppendLine("Out = In.r;");
                            break;

                        case 2:
                            s.AppendLine(string.Format("Out = {0}2({1}, {2});", precision,
                                                       red ? "In.r" : "0", green ? "In.g" : "0"));
                            break;

                        case 3:
                            s.AppendLine(string.Format("Out = {0}3({1}, {2}, {3});", precision,
                                                       red ? "In.r" : "0", green ? "In.g" : "0", blue ? "In.b" : "0"));
                            break;

                        case 4:
                            s.AppendLine(string.Format("Out = {0}4({1}, {2}, {3}, {4});", precision,
                                                       red ? "In.r" : "0", green ? "In.g" : "0", blue ? "In.b" : "0", alpha ? "In.a" : "0"));
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }
                }
            });
        }
Example #9
0
        protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)
        {
            var    channelCount = SlotValueHelper.GetChannelCount(concreteValueType);
            string values       = NodeUtils.FloatToShaderValue(value.x);

            if (channelCount == 1)
            {
                return(values);
            }
            for (var i = 1; i < channelCount; i++)
            {
                values += ", " + value[i];
            }
            return(string.Format("{0}{1}({2})", precision, channelCount, values));
        }
 protected override string ConcreteSlotValueAsVariable()
 {
     var channelCount = (int)SlotValueHelper.GetMatrixDimension(concreteValueType);
     var values = "";
     bool isFirst = true;
     for (var r = 0; r < channelCount; r++)
     {
         for (var c = 0; c < channelCount; c++)
         {
             if (!isFirst)
                 values += ", ";
             isFirst = false;
             values += value.GetRow(r)[c];
         }
     }
     return string.Format("$precision{0}x{0}({1})", channelCount, values);
 }
Example #11
0
        public static bool ImplicitConversionExists(ConcreteSlotValueType from, ConcreteSlotValueType to)
        {
            if (from == to)
            {
                return(true);
            }

            var fromCount = SlotValueHelper.GetChannelCount(from);
            var toCount   = SlotValueHelper.GetChannelCount(to);

            if (toCount > 0 && fromCount > 0)
            {
                return(true);
            }

            return(false);
        }
Example #12
0
        public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
        {
            var outputSlotType = FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString();
            var outputName     = GetVariableNameForSlot(OutputSlotId);
            var inputValue     = GetSlotValue(InputSlotId, generationMode);
            var inputValueType = FindInputSlot <MaterialSlot>(InputSlotId).concreteValueType;
            var InputValueSize = SlotValueHelper.GetChannelCount(inputValueType);

            if (!ValidateMaskInput(InputValueSize))
            {
                sb.AppendLine(string.Format("{0} {1} = 0;", outputSlotType, outputName));
            }
            else
            {
                sb.AppendLine("{0} {1} = {2}.{3};", outputSlotType, outputName, inputValue, convertedMask);
            }
        }
Example #13
0
        protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)
        {
            var  channelCount = (int)SlotValueHelper.GetMatrixDimension(concreteValueType);
            var  values       = "";
            bool isFirst      = true;

            for (var r = 0; r < channelCount; r++)
            {
                for (var c = 0; c < channelCount; c++)
                {
                    if (!isFirst)
                    {
                        values += ", ";
                    }
                    isFirst = false;
                    values += value.GetRow(r)[c];
                }
            }
            return(string.Format("{0}{1}x{1}({2})", precision, channelCount, values));
        }
Example #14
0
        void ValidateChannelCount()
        {
            var channelCount = SlotValueHelper.GetChannelCount(FindInputSlot <MaterialSlot>(InputSlotId).concreteValueType);

            if ((int)redChannel >= channelCount)
            {
                redChannel = TextureChannel.Red;
            }
            if ((int)greenChannel >= channelCount)
            {
                greenChannel = TextureChannel.Red;
            }
            if ((int)blueChannel >= channelCount)
            {
                blueChannel = TextureChannel.Red;
            }
            if ((int)alphaChannel >= channelCount)
            {
                alphaChannel = TextureChannel.Red;
            }
        }
Example #15
0
        public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
        {
            var inputValue = GetSlotValue(InputSlotId, generationMode);

            var inputSlot        = FindInputSlot <MaterialSlot>(InputSlotId);
            var numInputChannels = 0;

            if (inputSlot != null)
            {
                numInputChannels = SlotValueHelper.GetChannelCount(inputSlot.concreteValueType);
                if (numInputChannels > 4)
                {
                    numInputChannels = 0;
                }
            }

            for (var i = 0; i < 4; i++)
            {
                var outputFormat = numInputChannels == 1 ? inputValue : string.Format("{0}[{1}]", inputValue, i);
                var outputValue  = i >= numInputChannels ? "0" : outputFormat;
                sb.AppendLine(string.Format("$precision {0} = {1};", GetVariableNameForSlot(s_OutputSlots[i]), outputValue));
            }
        }
Example #16
0
        // Internal validation
        // -------------------------------------------------

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

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

            // iterate the input slots
            using (var tempSlots = PooledList <MaterialSlot> .Get())
            {
                GetInputSlots(tempSlots);
                foreach (var inputSlot in tempSlots)
                {
                    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    = 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;
                    }
                }

                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;
                }

                tempSlots.Clear();
                GetInputSlots(tempSlots);
                bool inputError = tempSlots.Any(x => x.hasError);
                if (inputError)
                {
                    owner.AddConcretizationError(guid, string.Format("Node {0} had input error", guid));
                    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
                tempSlots.Clear();
                GetOutputSlots(tempSlots);
                foreach (var outputSlot in 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 = ConvertDynamicVectorInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                            (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicVectorType);
                            break;
                        }
                        continue;
                    }
                }

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

            CalculateNodeHasError();

            ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);
        }
Example #17
0
        // Internal validation
        // -------------------------------------------------

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

            // 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();
                    if (outputNode.hasError)
                    {
                        isInError = true;
                    }
                }
            }
            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();
            hasError   = isInError;

            if (!hasError)
            {
                ++version;
            }

            ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);
        }
Example #18
0
        public void GenerateNodeCode(ShaderGenerator visitor, GraphContext graphContext, GenerationMode generationMode)
        {
            var inputValue = GetSlotValue(InputSlotId, generationMode);

            var  inputSlot    = FindInputSlot <MaterialSlot>(InputSlotId);
            var  numInputRows = 0;
            bool useIndentity = false;

            if (inputSlot != null)
            {
                numInputRows = SlotValueHelper.GetMatrixDimension(inputSlot.concreteValueType);
                if (numInputRows > 4)
                {
                    numInputRows = 0;
                }

                if (!owner.GetEdges(inputSlot.slotReference).Any())
                {
                    numInputRows = 0;
                    useIndentity = true;
                }
            }

            int concreteRowCount = useIndentity ? 2 : numInputRows;

            for (var r = 0; r < 4; r++)
            {
                string outputValue;
                if (r >= numInputRows)
                {
                    outputValue = string.Format("{0}{1}(", precision, concreteRowCount);
                    for (int c = 0; c < concreteRowCount; c++)
                    {
                        if (c != 0)
                        {
                            outputValue += ", ";
                        }
                        outputValue += Matrix4x4.identity.GetRow(r)[c];
                    }
                    outputValue += ")";
                }
                else
                {
                    switch (m_Axis)
                    {
                    case MatrixAxis.Column:
                        outputValue = string.Format("{0}{1}(", precision, numInputRows);
                        for (int c = 0; c < numInputRows; c++)
                        {
                            if (c != 0)
                            {
                                outputValue += ", ";
                            }
                            outputValue += string.Format("{0}[{1}].{2}", inputValue, c, s_ComponentList[r]);
                        }
                        outputValue += ")";
                        break;

                    default:
                        outputValue = string.Format("{0}[{1}]", inputValue, r);
                        break;
                    }
                }
                visitor.AddShaderChunk(string.Format("{0}{1} {2} = {3};", precision, concreteRowCount, GetVariableNameForSlot(s_OutputSlots[r]), outputValue), true);
            }
        }
Example #19
0
        public override void ValidateNode()
        {
            var isInError    = false;
            var errorMessage = k_validationErrorMessage;

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

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

            var dynamicMatrixInputSlotsToCompare = DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicMatrixSlots = ListPool <DynamicMatrixMaterialSlot> .Get();

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

                // if there is a connection
                var edges = owner.GetEdges(inputSlot.slotReference).ToList();
                if (!edges.Any())
                {
                    if (inputSlot is DynamicVectorMaterialSlot)
                    {
                        skippedDynamicSlots.Add(inputSlot as DynamicVectorMaterialSlot);
                    }
                    if (inputSlot is DynamicMatrixMaterialSlot)
                    {
                        skippedDynamicMatrixSlots.Add(inputSlot as DynamicMatrixMaterialSlot);
                    }
                    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 DynamicVectorMaterialSlot)
                {
                    dynamicInputSlotsToCompare.Add((DynamicVectorMaterialSlot)inputSlot, outputConcreteType);
                    continue;
                }
                else if (inputSlot is DynamicMatrixMaterialSlot)
                {
                    dynamicMatrixInputSlotsToCompare.Add((DynamicMatrixMaterialSlot)inputSlot, outputConcreteType);
                    continue;
                }

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

            // and now dynamic matrices
            var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicMatrixInputSlotsToCompare.Values);

            foreach (var dynamicKvP in dynamicMatrixInputSlotsToCompare)
            {
                dynamicKvP.Key.SetConcreteType(dynamicMatrixType);
            }
            foreach (var skippedSlot in skippedDynamicMatrixSlots)
            {
                skippedSlot.SetConcreteType(dynamicMatrixType);
            }

            // we can now figure out the dynamic slotType
            // from here set all the
            var dynamicType = SlotValueHelper.ConvertMatrixToVectorType(dynamicMatrixType);

            foreach (var dynamicKvP in dynamicInputSlotsToCompare)
            {
                dynamicKvP.Key.SetConcreteType(dynamicType);
            }
            foreach (var skippedSlot in skippedDynamicSlots)
            {
                skippedSlot.SetConcreteType(dynamicType);
            }

            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 DynamicVectorMaterialSlot)
                {
                    (outputSlot as DynamicVectorMaterialSlot).SetConcreteType(dynamicType);
                    continue;
                }
                else if (outputSlot is DynamicMatrixMaterialSlot)
                {
                    (outputSlot as DynamicMatrixMaterialSlot).SetConcreteType(dynamicMatrixType);
                    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 <DynamicVectorMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);

            ListPool <DynamicMatrixMaterialSlot> .Release(skippedDynamicMatrixSlots);

            DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Release(dynamicMatrixInputSlotsToCompare);
        }
Example #20
0
        public override void EvaluateDynamicMaterialSlots(List <MaterialSlot> inputSlots, List <MaterialSlot> outputSlots)
        {
            var dynamicInputSlotsToCompare = DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Get();

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

            var dynamicMatrixInputSlotsToCompare = DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicMatrixSlots = ListPool <DynamicMatrixMaterialSlot> .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 DynamicVectorMaterialSlot)
                        {
                            skippedDynamicSlots.Add(inputSlot as DynamicVectorMaterialSlot);
                        }
                        if (inputSlot is DynamicMatrixMaterialSlot)
                        {
                            skippedDynamicMatrixSlots.Add(inputSlot as DynamicMatrixMaterialSlot);
                        }
                        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 DynamicVectorMaterialSlot)
                    {
                        dynamicInputSlotsToCompare.Add((DynamicVectorMaterialSlot)inputSlot, outputConcreteType);
                        continue;
                    }
                    else if (inputSlot is DynamicMatrixMaterialSlot)
                    {
                        dynamicMatrixInputSlotsToCompare.Add((DynamicMatrixMaterialSlot)inputSlot, outputConcreteType);
                        continue;
                    }
                }

                // and now dynamic matrices
                var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicMatrixInputSlotsToCompare.Values);
                foreach (var dynamicKvP in dynamicMatrixInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicMatrixType);
                }
                foreach (var skippedSlot in skippedDynamicMatrixSlots)
                {
                    skippedSlot.SetConcreteType(dynamicMatrixType);
                }

                // we can now figure out the dynamic slotType
                // from here set all the
                var dynamicType = SlotValueHelper.ConvertMatrixToVectorType(dynamicMatrixType);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicType);
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(dynamicType);
                }

                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 DynamicVectorMaterialSlot)
                    {
                        (outputSlot as DynamicVectorMaterialSlot).SetConcreteType(dynamicType);
                        continue;
                    }
                    else if (outputSlot is DynamicMatrixMaterialSlot)
                    {
                        (outputSlot as DynamicMatrixMaterialSlot).SetConcreteType(dynamicMatrixType);
                        continue;
                    }
                }

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

            CalculateNodeHasError();

            ListPool <DynamicVectorMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);

            ListPool <DynamicMatrixMaterialSlot> .Release(skippedDynamicMatrixSlots);

            DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Release(dynamicMatrixInputSlotsToCompare);
        }