#include #include #include #include #include #include #include template VecValue::VecValue(ShaderGraph& graph) : ShaderNode(graph) { static_assert(ComponentCount <= s_vectorComponents.size()); std::array defaultValues; for (std::size_t i = 0; i < ComponentCount; ++i) defaultValues[i] = (i == 3) ? 1.f : 0.f; m_value.Set(defaultValues.data()); UpdatePreview(); } template QString VecValue::caption() const { static QString caption = "Vector" + QString::number(ComponentCount) + " constant"; return caption; } template QString VecValue::name() const { static QString name = "vec" + QString::number(ComponentCount) + "_constant"; return name; } template QtNodes::NodeDataType VecValue::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const { assert(portType == QtNodes::PortType::Out); assert(portIndex == 0); return VecData::Type(); } template unsigned int VecValue::nPorts(QtNodes::PortType portType) const { switch (portType) { case QtNodes::PortType::In: return 0; case QtNodes::PortType::Out: return 1; } return 0; } template std::shared_ptr VecValue::outData(QtNodes::PortIndex port) { assert(port == 0); auto out = std::make_shared(ComponentCount); out->preview = QImage(1, 1, QImage::Format_RGBA8888); out->preview.fill(ToColor()); return out; } template void VecValue::BuildNodeEdition(QFormLayout* layout) { ShaderNode::BuildNodeEdition(layout); for (std::size_t i = 0; i < ComponentCount; ++i) { QDoubleSpinBox* spinbox = new QDoubleSpinBox; spinbox->setDecimals(6); spinbox->setRange(std::numeric_limits::lowest(), std::numeric_limits::max()); spinbox->setValue(m_value[i]); connect(spinbox, qOverload(&QDoubleSpinBox::valueChanged), [=](double) { m_value[i] = spinbox->value(); Q_EMIT dataUpdated(0); UpdatePreview(); }); layout->addRow(QString::fromUtf8(&s_vectorComponents[i], 1), spinbox); } } template Nz::ShaderNodes::ExpressionPtr VecValue::GetExpression(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count) const { assert(count == 0); return Nz::ShaderBuilder::Constant(m_value); } template bool VecValue::ComputePreview(QPixmap& pixmap) { pixmap.fill(ToColor()); return true; } template QColor VecValue::ToColor() const { std::array values = { 0.f, 0.f, 0.f, 1.f }; for (std::size_t i = 0; i < ComponentCount; ++i) values[i] = std::clamp(m_value[i], 0.f, 1.f); return QColor::fromRgbF(values[0], values[1], values[2], values[3]); } template void VecValue::restore(const QJsonObject& data) { QJsonArray vecValues = data["value"].toArray(); std::size_t commonValues = std::min(static_cast(vecValues.size()), ComponentCount); for (std::size_t i = 0; i < commonValues; ++i) m_value[i] = float(vecValues[int(i)].toDouble(m_value[i])); ShaderNode::restore(data); } template QJsonObject VecValue::save() const { QJsonObject data = ShaderNode::save(); QJsonArray vecValues; for (std::size_t i = 0; i < ComponentCount; ++i) vecValues.push_back(m_value[i]); data["value"] = vecValues; return data; }