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); } }
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"); } }
// 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); }
public void SetConcreteType(ConcreteSlotValueType valueType) { m_ConcreteValueType = valueType; }
// 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); }
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); }