From c41a446ae96bc1b74b9f8660c2859a0e1ab696c1 Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Mon, 28 Mar 2022 15:02:32 +0200 Subject: [PATCH] Add `Rotate Vector` node to Visject Surface graphs --- Source/Editor/Surface/Archetypes/Math.cs | 14 ++++++++++++++ Source/Engine/Visject/ShaderGraph.cpp | 9 ++++++++- Source/Engine/Visject/ShaderGraphValue.cpp | 4 ++-- Source/Engine/Visject/VisjectGraph.cpp | 10 ++++++++-- Source/Shaders/Common.hlsl | 2 +- 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Math.cs b/Source/Editor/Surface/Archetypes/Math.cs index 2bfb3e816..b9d4098bc 100644 --- a/Source/Editor/Surface/Archetypes/Math.cs +++ b/Source/Editor/Surface/Archetypes/Math.cs @@ -427,6 +427,20 @@ namespace FlaxEditor.Surface.Archetypes NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 4), } }, + new NodeArchetype + { + TypeID = 49, + Title = "Rotate Vector", + Description = "Rotates given vector using the Quaternion", + Flags = NodeFlags.AllGraphs, + Size = new Vector2(200, 40), + Elements = new[] + { + NodeElementArchetype.Factory.Input(0, "Quaternion", true, typeof(Quaternion), 0), + NodeElementArchetype.Factory.Input(1, "Vector", true, typeof(Vector3), 1), + NodeElementArchetype.Factory.Output(0, string.Empty, typeof(Vector3), 2), + } + }, }; } } diff --git a/Source/Engine/Visject/ShaderGraph.cpp b/Source/Engine/Visject/ShaderGraph.cpp index d06a00977..11adc31cd 100644 --- a/Source/Engine/Visject/ShaderGraph.cpp +++ b/Source/Engine/Visject/ShaderGraph.cpp @@ -409,10 +409,17 @@ void ShaderGenerator::ProcessGroupMath(Box* box, Node* node, Value& value) const auto rangeA = tryGetValue(node->GetBox(1), node->Values[1].AsVector2()); const auto rangeB = tryGetValue(node->GetBox(2), node->Values[2].AsVector2()); const auto clamp = tryGetValue(node->GetBox(3), node->Values[3]).AsBool(); - const auto mapFunc = String::Format(TEXT("{2}.x + ({0} - {1}.x) * ({2}.y - {2}.x) / ({1}.y - {1}.x)"), inVal.Value, rangeA.Value, rangeB.Value); value = writeLocal(ValueType::Float, String::Format(TEXT("{2} ? clamp({0}, {1}.x, {1}.y) : {0}"), mapFunc, rangeB.Value, clamp.Value), node); break; + } + // Rotate Vector + case 49: + { + const Value quaternion = tryGetValue(node->GetBox(0), Value::InitForZero(VariantType::Quaternion)).Cast(VariantType::Quaternion); + const Value vector = tryGetValue(node->GetBox(1), Vector3::Forward).Cast(VariantType::Vector3); + value = writeLocal(ValueType::Vector3, String::Format(TEXT("QuatRotateVector({0}, {1})"), quaternion.Value, vector.Value), node); + break; } default: break; diff --git a/Source/Engine/Visject/ShaderGraphValue.cpp b/Source/Engine/Visject/ShaderGraphValue.cpp index 828f9ac0f..0b4178ca3 100644 --- a/Source/Engine/Visject/ShaderGraphValue.cpp +++ b/Source/Engine/Visject/ShaderGraphValue.cpp @@ -130,7 +130,7 @@ ShaderGraphValue ShaderGraphValue::InitForZero(VariantType::Types type) CRASH; v = nullptr; } - return ShaderGraphValue(type, String(v)); + return ShaderGraphValue(type, v); } ShaderGraphValue ShaderGraphValue::InitForHalf(VariantType::Types type) @@ -309,7 +309,7 @@ ShaderGraphValue ShaderGraphValue::Cast(const ShaderGraphValue& v, VariantType:: format = TEXT("{0}.xyz"); break; case VariantType::Types::Quaternion: - format = TEXT("QuatRotateVector(float3(0, 0, 1), {0})"); + format = TEXT("QuatRotateVector({0}, float3(0, 0, 1))"); // Returns direction vector break; } break; diff --git a/Source/Engine/Visject/VisjectGraph.cpp b/Source/Engine/Visject/VisjectGraph.cpp index e2091e749..658121b20 100644 --- a/Source/Engine/Visject/VisjectGraph.cpp +++ b/Source/Engine/Visject/VisjectGraph.cpp @@ -405,11 +405,17 @@ void VisjectExecutor::ProcessGroupMath(Box* box, Node* node, Value& value) const Vector2 rangeA = tryGetValue(node->GetBox(1), node->Values[1]).AsVector2(); const Vector2 rangeB = tryGetValue(node->GetBox(2), node->Values[2]).AsVector2(); const bool clamp = tryGetValue(node->GetBox(3), node->Values[3]).AsBool; - auto mapFunc = Math::Remap(inVal, rangeA.X, rangeA.Y, rangeB.X, rangeB.Y); - value = clamp ? Math::Clamp(mapFunc, rangeB.X, rangeB.Y) : mapFunc; break; + } + // Rotate Vector + case 49: + { + const Quaternion quaternion = (Quaternion)tryGetValue(node->GetBox(0), Quaternion::Identity); + const Vector3 vector = (Vector3)tryGetValue(node->GetBox(1), Vector3::Forward); + value = quaternion * vector; + break; } default: break; diff --git a/Source/Shaders/Common.hlsl b/Source/Shaders/Common.hlsl index 8e5a682c6..fd5fc19f4 100644 --- a/Source/Shaders/Common.hlsl +++ b/Source/Shaders/Common.hlsl @@ -211,7 +211,7 @@ float4 QuatMultiply(float4 q1, float4 q2) } // Vector rotation with a quaternion (http://mathworld.wolfram.com/Quaternion.html) -float3 QuatRotateVector(float3 v, float4 q) +float3 QuatRotateVector(float4 q, float3 v) { float4 nq = q * float4(-1, -1, -1, 1); return QuatMultiply(q, QuatMultiply(float4(v, 0), nq)).xyz;