// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Types/String.h" #include "Engine/Core/Object.h" #include "GraphNode.h" /// /// Shader source generator value container. Caches the value type and the value variable name (shader local, global parameter or constant value). Supports value type casting and component swizzle. /// struct ShaderGraphValue : Object { private: static const Char* _subs[]; public: /// /// The value type. /// VariantType::Types Type; /// /// The shader value. /// String Value; public: /// /// Zero value (as float). /// static const ShaderGraphValue Zero; /// /// Half value (as float). /// static const ShaderGraphValue Half; /// /// One value (as float). /// static const ShaderGraphValue One; /// /// True value (as bool). /// static const ShaderGraphValue True; /// /// False value (as bool). /// static const ShaderGraphValue False; public: /// /// Initializes a new instance of the struct. /// ShaderGraphValue() : Type(VariantType::Types::Null) { } /// /// Initializes a new instance of the struct. /// /// The type. /// The value. ShaderGraphValue(VariantType::Types type, const Char* value) : Type(type) , Value(value) { } /// /// Initializes a new instance of the struct. /// /// The type. /// The value. ShaderGraphValue(VariantType::Types type, const String& value) : Type(type) , Value(value) { } /// /// Initializes a new instance of the struct. /// /// The value. explicit ShaderGraphValue(const bool value) : Type(VariantType::Types::Bool) , Value(value ? TEXT("true") : TEXT("false")) { } /// /// Initializes a new instance of the struct. /// /// The value. explicit ShaderGraphValue(const float value) : Type(VariantType::Types::Float) , Value(StringUtils::ToString(value)) { } /// /// Initializes a new instance of the struct. /// /// The value. explicit ShaderGraphValue(const int32 value) : Type(VariantType::Types::Int) , Value(StringUtils::ToString(value)) { } /// /// Initializes a new instance of the struct. /// /// The value. explicit ShaderGraphValue(const Variant& v); public: /// /// Returns true if value is valid. /// /// True if is valid, otherwise false. bool IsValid() const { return Type != VariantType::Types::Null; } /// /// Returns true if value is invalid. /// /// True if is invalid, otherwise false. bool IsInvalid() const { return Type == VariantType::Types::Null; } /// /// Checks if value contains static part with zero. /// /// True if contains zero number. bool IsZero() const; /// /// Checks if value contains static part with one. /// /// True if contains one number. bool IsOne() const; /// /// Clears this instance. /// void Clear() { Type = VariantType::Types::Null; Value.Clear(); } public: /// /// Formats thw value. /// /// The format text. /// The value. /// The formatted value. static String Format(const Char* format, const ShaderGraphValue& v1) { return String::Format(format, v1.Value); } /// /// Formats thw value. /// /// The format text. /// The first value. /// The second value. /// The formatted value. static String Format(const Char* format, const ShaderGraphValue& v1, const ShaderGraphValue& v2) { return String::Format(format, v1.Value, v2.Value); } /// /// Formats thw value. /// /// The format text. /// The first value. /// The second value. /// The third value. /// The formatted value. static String Format(const Char* format, const ShaderGraphValue& v1, const ShaderGraphValue& v2, const ShaderGraphValue& v3) { return String::Format(format, v1.Value, v2.Value, v3.Value); } /// /// Formats thw value. /// /// The format text. /// The first value. /// The second value. /// The third value. /// The fourth value. /// The formatted value. static String Format(const Char* format, const ShaderGraphValue& v1, const ShaderGraphValue& v2, const ShaderGraphValue& v3, const ShaderGraphValue& v4) { return String::Format(format, v1.Value, v2.Value, v3.Value, v4.Value); } public: /// /// Initializes the shader variable for given connection type Zero. /// /// The graph connection type. /// Initial value for given type. static ShaderGraphValue InitForZero(VariantType::Types type); /// /// Initializes the shader variable for given connection type Half. /// /// The graph connection type. /// Initial value for given type. static ShaderGraphValue InitForHalf(VariantType::Types type); /// /// Initializes the shader variable for given connection type One. /// /// The graph connection type. /// Initial value for given type. static ShaderGraphValue InitForOne(VariantType::Types type); /// /// Create float2 from X and Y values. /// /// The x. /// The y. /// float2 static ShaderGraphValue Float2(const ShaderGraphValue& x, const ShaderGraphValue& y) { return ShaderGraphValue( VariantType::Types::Vector2, String::Format(TEXT("float2({0}, {1})"), Cast(x, VariantType::Types::Float).Value, Cast(y, VariantType::Types::Float).Value)); } /// /// Create float3 from X, Y and Z values. /// /// The x. /// The y. /// The z. /// float3 static ShaderGraphValue Float3(const ShaderGraphValue& x, const ShaderGraphValue& y, const ShaderGraphValue& z) { return ShaderGraphValue( VariantType::Types::Vector3, String::Format(TEXT("float3({0}, {1}, {2})"), Cast(x, VariantType::Types::Float).Value, Cast(y, VariantType::Types::Float).Value, Cast(z, VariantType::Types::Float).Value)); } /// /// Create float4 from X, Y, Z and W values. /// /// The X. /// The Y. /// The Z. /// The W. /// float4 static ShaderGraphValue Float4(const ShaderGraphValue& x, const ShaderGraphValue& y, const ShaderGraphValue& z, const ShaderGraphValue& w) { return ShaderGraphValue( VariantType::Types::Vector4, String::Format(TEXT("float4({0}, {1}, {2}, {3})"), Cast(x, VariantType::Types::Float).Value, Cast(y, VariantType::Types::Float).Value, Cast(z, VariantType::Types::Float).Value, Cast(w, VariantType::Types::Float).Value)); } public: /// /// Gets the X component of the value. Valid only for single or vector types. /// /// The X component. ShaderGraphValue GetX() const { return ShaderGraphValue(VariantType::Types::Float, Value + _subs[0]); } /// /// Gets the Y component of the value. Valid only for vector types. /// /// The Y component. ShaderGraphValue GetY() const { return ShaderGraphValue(VariantType::Types::Float, Value + _subs[1]); } /// /// Gets the Z component of the value. Valid only for vector types. /// /// The Z component. ShaderGraphValue GetZ() const { return ShaderGraphValue(VariantType::Types::Float, Value + _subs[2]); } /// /// Gets the W component of the value. Valid only for vector types. /// /// The W component. ShaderGraphValue GetW() const { return ShaderGraphValue(VariantType::Types::Float, Value + _subs[3]); } public: /// /// Casts the value to the bool type. /// /// Bool ShaderGraphValue AsBool() const { return Cast(*this, VariantType::Types::Bool); } /// /// Casts the value to the integer type. /// /// Integer ShaderGraphValue AsInt() const { return Cast(*this, VariantType::Types::Int); } /// /// Casts the value to the unsigned integer type. /// /// UnsignedInteger ShaderGraphValue AsUint() const { return Cast(*this, VariantType::Types::Uint); } /// /// Casts the value to the float type. /// /// Float ShaderGraphValue AsFloat() const { return Cast(*this, VariantType::Types::Float); } /// /// Casts the value to the Vector2 type. /// /// Vector2 ShaderGraphValue AsVector2() const { return Cast(*this, VariantType::Types::Vector2); } /// /// Casts the value to the Vector3 type. /// /// Vector3 ShaderGraphValue AsVector3() const { return Cast(*this, VariantType::Types::Vector3); } /// /// Casts the value to the Vector4 type. /// /// Vector4 ShaderGraphValue AsVector4() const { return Cast(*this, VariantType::Types::Vector4); } /// /// Casts the value from its type to the another type. /// /// The result type. /// The result value. ShaderGraphValue Cast(const VariantType::Types to) const { return Cast(*this, to); } /// /// Casts the value from its type to the another type. /// /// The value to cast. /// The result type. /// The result value. static ShaderGraphValue Cast(const ShaderGraphValue& v, VariantType::Types to); public: // [Object] String ToString() const override { return Value; } };