Skip to content

Commit

Permalink
Initial
Browse files Browse the repository at this point in the history
Working version

Fix copy paste error

Change TransformVecMult to output vec4, generate docs

Some more docs.

Suggestion: remove unnecessary default

Co-authored-by: A Thousand Ships <[email protected]>
  • Loading branch information
tetrapod00 and AThousandShips committed Sep 21, 2024
1 parent 621cadc commit e619ebd
Show file tree
Hide file tree
Showing 6 changed files with 317 additions and 14 deletions.
48 changes: 48 additions & 0 deletions doc/classes/VisualShaderNodeCoordinateSpaceHelper.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeCoordinateSpaceHelper" inherits="VisualShaderNode" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Transforms a vector from one coordinate space to another.
</brief_description>
<description>
Transforms a vector from one coordinate space to another. See also [VisualShaderNodeTransformVecMult].
</description>
<tutorials>
</tutorials>
<members>
<member name="from_space" type="int" setter="set_from_space" getter="get_from_space" enum="VisualShaderNodeCoordinateSpaceHelper.Space" default="0">
Coordinate space to transform from.
</member>
<member name="to_space" type="int" setter="set_to_space" getter="get_to_space" enum="VisualShaderNodeCoordinateSpaceHelper.Space" default="0">
Coordinate space to transform to.
</member>
<member name="vector_type" type="int" setter="set_vector_type" getter="get_vector_type" enum="VisualShaderNodeCoordinateSpaceHelper.VectorType" default="0">
Type of the vector to transform, either position or direction.
</member>
</members>
<constants>
<constant name="SPACE_MODEL" value="0" enum="Space">
Model space.
</constant>
<constant name="SPACE_WORLD" value="1" enum="Space">
World space.
</constant>
<constant name="SPACE_VIEW" value="2" enum="Space">
View space.
</constant>
<constant name="SPACE_CLIP" value="3" enum="Space">
Clip space.
</constant>
<constant name="SPACE_MAX" value="4" enum="Space">
Represents the size of the [enum Space] enum.
</constant>
<constant name="VECTOR_POSITION" value="0" enum="VectorType">
A position vector.
</constant>
<constant name="VECTOR_DIRECTION" value="1" enum="VectorType">
A direction vector, such as a normal vector.
</constant>
<constant name="VECTOR_MAX" value="2" enum="VectorType">
Represents the size of the [enum VectorType] enum.
</constant>
</constants>
</class>
18 changes: 12 additions & 6 deletions doc/classes/VisualShaderNodeTransformVecMult.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Multiplies a [Transform3D] and a [Vector3] within the visual shader graph.
</brief_description>
<description>
A multiplication operation on a transform (4×4 matrix) and a vector, with support for different multiplication operators.
A multiplication operation on a transform (4×4 matrix) and a vector, with support for different multiplication operators. See also [VisualShaderNodeCoordinateSpaceHelper].
</description>
<tutorials>
</tutorials>
Expand All @@ -15,18 +15,24 @@
</members>
<constants>
<constant name="OP_AxB" value="0" enum="Operator">
Multiplies transform [code]a[/code] by the vector [code]b[/code].
Multiplies transform [code]a[/code] by the [Vector3] [code]b[/code].
</constant>
<constant name="OP_BxA" value="1" enum="Operator">
Multiplies vector [code]b[/code] by the transform [code]a[/code].
Multiplies [Vector3] [code]b[/code] by the transform [code]a[/code].
</constant>
<constant name="OP_3x3_AxB" value="2" enum="Operator">
Multiplies transform [code]a[/code] by the vector [code]b[/code], skipping the last row and column of the transform.
Multiplies transform [code]a[/code] by the [Vector3] [code]b[/code], skipping the last row and column of the transform.
</constant>
<constant name="OP_3x3_BxA" value="3" enum="Operator">
Multiplies vector [code]b[/code] by the transform [code]a[/code], skipping the last row and column of the transform.
Multiplies [Vector3] [code]b[/code] by the transform [code]a[/code], skipping the last row and column of the transform.
</constant>
<constant name="OP_MAX" value="4" enum="Operator">
<constant name="OP_VEC4_AxB" value="4" enum="Operator">
Multiplies transform [code]a[/code] by the vector [code]b[/code]. Accepts [Vector4] input.
</constant>
<constant name="OP_VEC4_BxA" value="5" enum="Operator">
Multiplies vector [code]b[/code] by the transform [code]a[/code]. Accepts [Vector4] input.
</constant>
<constant name="OP_MAX" value="6" enum="Operator">
Represents the size of the [enum Operator] enum.
</constant>
</constants>
Expand Down
1 change: 1 addition & 0 deletions editor/plugins/visual_shader_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7197,6 +7197,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("MultiplyComp (*)", "Transform/Operators", "VisualShaderNodeTransformOp", TTR("Performs per-component multiplication of two transforms."), { VisualShaderNodeTransformOp::OP_AxB_COMP }, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("Subtract (-)", "Transform/Operators", "VisualShaderNodeTransformOp", TTR("Subtracts two transforms."), { VisualShaderNodeTransformOp::OP_A_MINUS_B }, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("TransformVectorMult (*)", "Transform/Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("CoordinateSpaceHelper (*)", "Transform/Operators", "VisualShaderNodeCoordinateSpaceHelper", TTR("Transform between coordinate spaces."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));

add_options.push_back(AddOption("TransformConstant", "Transform/Variables", "VisualShaderNodeTransformConstant", TTR("Transform constant."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("TransformParameter", "Transform/Variables", "VisualShaderNodeTransformParameter", TTR("Transform parameter."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM));
Expand Down
1 change: 1 addition & 0 deletions scene/register_scene_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,7 @@ void register_scene_types() {
GDREGISTER_CLASS(VisualShaderNodeColorOp);
GDREGISTER_CLASS(VisualShaderNodeTransformOp);
GDREGISTER_CLASS(VisualShaderNodeTransformVecMult);
GDREGISTER_CLASS(VisualShaderNodeCoordinateSpaceHelper);
GDREGISTER_CLASS(VisualShaderNodeFloatFunc);
GDREGISTER_CLASS(VisualShaderNodeIntFunc);
GDREGISTER_CLASS(VisualShaderNodeUIntFunc);
Expand Down
201 changes: 193 additions & 8 deletions scene/resources/visual_shader_nodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2636,7 +2636,8 @@ int VisualShaderNodeTransformVecMult::get_input_port_count() const {
}

VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_input_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_TRANSFORM : PORT_TYPE_VECTOR_3D;
PortType vector_type = (op == OP_VEC4_AxB || op == OP_VEC4_BxA) ? PORT_TYPE_VECTOR_4D : PORT_TYPE_VECTOR_3D;
return p_port == 0 ? PORT_TYPE_TRANSFORM : vector_type;
}

String VisualShaderNodeTransformVecMult::get_input_port_name(int p_port) const {
Expand All @@ -2648,7 +2649,7 @@ int VisualShaderNodeTransformVecMult::get_output_port_count() const {
}

VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR_3D : PORT_TYPE_SCALAR;
return PORT_TYPE_VECTOR_4D;
}

String VisualShaderNodeTransformVecMult::get_output_port_name(int p_port) const {
Expand All @@ -2657,13 +2658,17 @@ String VisualShaderNodeTransformVecMult::get_output_port_name(int p_port) const

String VisualShaderNodeTransformVecMult::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
if (op == OP_AxB) {
return " " + p_output_vars[0] + " = (" + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 1.0)).xyz;\n";
return " " + p_output_vars[0] + " = (" + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 1.0));\n";
} else if (op == OP_BxA) {
return " " + p_output_vars[0] + " = (vec4(" + p_input_vars[1] + ", 1.0) * " + p_input_vars[0] + ").xyz;\n";
return " " + p_output_vars[0] + " = (vec4(" + p_input_vars[1] + ", 1.0) * " + p_input_vars[0] + ");\n";
} else if (op == OP_3x3_AxB) {
return " " + p_output_vars[0] + " = (" + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 0.0)).xyz;\n";
} else {
return " " + p_output_vars[0] + " = (vec4(" + p_input_vars[1] + ", 0.0) * " + p_input_vars[0] + ").xyz;\n";
return " " + p_output_vars[0] + " = (" + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 0.0));\n";
} else if (op == OP_3x3_BxA) {
return " " + p_output_vars[0] + " = (vec4(" + p_input_vars[1] + ", 0.0) * " + p_input_vars[0] + ");\n";
} else if (op == OP_VEC4_AxB) {
return " " + p_output_vars[0] + " = (" + p_input_vars[0] + " * " + p_input_vars[1] + ");\n";
} else { // OP_VEC4_BxA
return " " + p_output_vars[0] + " = (" + p_input_vars[1] + " * " + p_input_vars[0] + ");\n";
}
}

Expand All @@ -2672,6 +2677,28 @@ void VisualShaderNodeTransformVecMult::set_operator(Operator p_op) {
if (op == p_op) {
return;
}
switch (p_op) {
case OP_AxB: {
set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
} break;
case OP_BxA: {
set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
} break;
case OP_3x3_AxB: {
set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
} break;
case OP_3x3_BxA: {
set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
} break;
case OP_VEC4_AxB: {
set_input_port_default_value(1, Vector4(), get_input_port_default_value(1));
} break;
case OP_VEC4_BxA: {
set_input_port_default_value(1, Vector4(), get_input_port_default_value(1));
} break;
default:
break;
}
op = p_op;
emit_changed();
}
Expand All @@ -2690,12 +2717,14 @@ void VisualShaderNodeTransformVecMult::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeTransformVecMult::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeTransformVecMult::get_operator);

ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "A x B,B x A,A x B (3x3),B x A (3x3)"), "set_operator", "get_operator");
ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "A x B,B x A,A x B (3x3),B x A (3x3), A x B (Vec4), B x A (Vec4)"), "set_operator", "get_operator");

BIND_ENUM_CONSTANT(OP_AxB);
BIND_ENUM_CONSTANT(OP_BxA);
BIND_ENUM_CONSTANT(OP_3x3_AxB);
BIND_ENUM_CONSTANT(OP_3x3_BxA);
BIND_ENUM_CONSTANT(OP_VEC4_AxB);
BIND_ENUM_CONSTANT(OP_VEC4_BxA);
BIND_ENUM_CONSTANT(OP_MAX);
}

Expand All @@ -2704,6 +2733,162 @@ VisualShaderNodeTransformVecMult::VisualShaderNodeTransformVecMult() {
set_input_port_default_value(1, Vector3());
}

////////////// CoordinateSpaceHelper

String VisualShaderNodeCoordinateSpaceHelper::get_caption() const {
return "CoordinateSpaceHelper";
}

int VisualShaderNodeCoordinateSpaceHelper::get_input_port_count() const {
return 1;
}

VisualShaderNodeCoordinateSpaceHelper::PortType VisualShaderNodeCoordinateSpaceHelper::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR_3D;
}

String VisualShaderNodeCoordinateSpaceHelper::get_input_port_name(int p_port) const {
return "Input";
}

int VisualShaderNodeCoordinateSpaceHelper::get_output_port_count() const {
return 1;
}

VisualShaderNodeCoordinateSpaceHelper::PortType VisualShaderNodeCoordinateSpaceHelper::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR_3D;
}

String VisualShaderNodeCoordinateSpaceHelper::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}

String VisualShaderNodeCoordinateSpaceHelper::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String identity = " " + p_output_vars[0] + " = " + p_input_vars[0] + ";\n";
String matrix;
if (from_space == SPACE_MODEL) {
if (to_space == SPACE_MODEL) {
return identity;
} else if (to_space == SPACE_WORLD) {
matrix = "MODEL_MATRIX";
} else if (to_space == SPACE_VIEW) {
matrix = (p_type == VisualShader::TYPE_VERTEX) ? "MODELVIEW_MATRIX" : "VIEW_MATRIX * MODEL_MATRIX";
} else if (to_space == SPACE_CLIP) {
matrix = (p_type == VisualShader::TYPE_VERTEX) ? "PROJECTION_MATRIX * MODELVIEW_MATRIX" : "PROJECTION_MATRIX * VIEW_MATRIX * MODEL_MATRIX";
}
} else if (from_space == SPACE_WORLD) {
if (to_space == SPACE_MODEL) {
matrix = "inverse(MODEL_MATRIX)";
} else if (to_space == SPACE_WORLD) {
return identity;
} else if (to_space == SPACE_VIEW) {
matrix = "VIEW_MATRIX";
} else if (to_space == SPACE_CLIP) {
matrix = "PROJECTION_MATRIX * VIEW_MATRIX";
}
} else if (from_space == SPACE_VIEW) {
if (to_space == SPACE_MODEL) {
matrix = (p_type == VisualShader::TYPE_VERTEX) ? "inverse(MODELVIEW_MATRIX)" : "inverse(MODEL_MATRIX) * INV_VIEW_MATRIX";
} else if (to_space == SPACE_WORLD) {
matrix = "INV_VIEW_MATRIX";
} else if (to_space == SPACE_VIEW) {
return identity;
} else if (to_space == SPACE_CLIP) {
matrix = "PROJECTION_MATRIX";
}
} else if (from_space == SPACE_CLIP) {
if (to_space == SPACE_MODEL) {
matrix = (p_type == VisualShader::TYPE_VERTEX) ? "inverse(MODELVIEW_MATRIX) * INV_PROJECTION_MATRIX" : "inverse(MODEL_MATRIX) * INV_VIEW_MATRIX * INV_PROJECTION_MATRIX";
} else if (to_space == SPACE_WORLD) {
matrix = "INV_VIEW_MATRIX * INV_PROJECTION_MATRIX";
} else if (to_space == SPACE_VIEW) {
matrix = "INV_PROJECTION_MATRIX";
} else if (to_space == SPACE_CLIP) {
return identity;
}
}
String vec4_w = vector_type == VECTOR_POSITION ? "1.0" : "0.0";
return " " + p_output_vars[0] + " = (" + matrix + " * vec4(" + p_input_vars[0] + ", " + vec4_w + ")).xyz;\n";

return identity;
}

void VisualShaderNodeCoordinateSpaceHelper::set_from_space(Space p_from_space) {
ERR_FAIL_INDEX(int(p_from_space), int(SPACE_MAX));
if (from_space == p_from_space) {
return;
}
from_space = p_from_space;
emit_changed();
}

VisualShaderNodeCoordinateSpaceHelper::Space VisualShaderNodeCoordinateSpaceHelper::get_from_space() const {
return from_space;
}

void VisualShaderNodeCoordinateSpaceHelper::set_to_space(Space p_to_space) {
ERR_FAIL_INDEX(int(p_to_space), int(SPACE_MAX));
if (to_space == p_to_space) {
return;
}
to_space = p_to_space;
emit_changed();
}

VisualShaderNodeCoordinateSpaceHelper::Space VisualShaderNodeCoordinateSpaceHelper::get_to_space() const {
return to_space;
}

void VisualShaderNodeCoordinateSpaceHelper::set_vector_type(VectorType p_vector_type) {
ERR_FAIL_INDEX(int(p_vector_type), int(VECTOR_MAX));
if (vector_type == p_vector_type) {
return;
}
vector_type = p_vector_type;
emit_changed();
}

VisualShaderNodeCoordinateSpaceHelper::VectorType VisualShaderNodeCoordinateSpaceHelper::get_vector_type() const {
return vector_type;
}

Vector<StringName> VisualShaderNodeCoordinateSpaceHelper::get_editable_properties() const {
Vector<StringName> props;
props.push_back("from_space");
props.push_back("to_space");
props.push_back("vector_type");
return props;
}

void VisualShaderNodeCoordinateSpaceHelper::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_from_space", "from_space"), &VisualShaderNodeCoordinateSpaceHelper::set_from_space);
ClassDB::bind_method(D_METHOD("get_from_space"), &VisualShaderNodeCoordinateSpaceHelper::get_from_space);

ClassDB::bind_method(D_METHOD("set_to_space", "to_space"), &VisualShaderNodeCoordinateSpaceHelper::set_to_space);
ClassDB::bind_method(D_METHOD("get_to_space"), &VisualShaderNodeCoordinateSpaceHelper::get_to_space);

ClassDB::bind_method(D_METHOD("set_vector_type", "vector_type"), &VisualShaderNodeCoordinateSpaceHelper::set_vector_type);
ClassDB::bind_method(D_METHOD("get_vector_type"), &VisualShaderNodeCoordinateSpaceHelper::get_vector_type);

ADD_PROPERTY(PropertyInfo(Variant::INT, "from_space", PROPERTY_HINT_ENUM, "Model to...,World to...,View to...,Clip to..."), "set_from_space", "get_from_space");
ADD_PROPERTY(PropertyInfo(Variant::INT, "to_space", PROPERTY_HINT_ENUM, "Model,World,View,Clip"), "set_to_space", "get_to_space");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vector_type", PROPERTY_HINT_ENUM, "Position,Direction"), "set_vector_type", "get_vector_type");

BIND_ENUM_CONSTANT(SPACE_MODEL);
BIND_ENUM_CONSTANT(SPACE_WORLD);
BIND_ENUM_CONSTANT(SPACE_VIEW);
BIND_ENUM_CONSTANT(SPACE_CLIP);
BIND_ENUM_CONSTANT(SPACE_MAX);

BIND_ENUM_CONSTANT(VECTOR_POSITION);
BIND_ENUM_CONSTANT(VECTOR_DIRECTION);
BIND_ENUM_CONSTANT(VECTOR_MAX);
}

VisualShaderNodeCoordinateSpaceHelper::VisualShaderNodeCoordinateSpaceHelper() {
set_input_port_default_value(0, Vector3());
}

////////////// Float Func

String VisualShaderNodeFloatFunc::get_caption() const {
Expand Down
Loading

0 comments on commit e619ebd

Please sign in to comment.