summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/ArrayMesh.xml3
-rw-r--r--doc/classes/ImmediateGeometry3D.xml3
-rw-r--r--doc/classes/MeshDataTool.xml2
-rw-r--r--doc/classes/SurfaceTool.xml2
-rw-r--r--editor/icons/Decal.svg1
-rwxr-xr-xmisc/hooks/pre-commit-black84
-rwxr-xr-xmisc/hooks/pre-commit-clang-format84
-rwxr-xr-xmisc/hooks/winmessage.ps1103
-rw-r--r--modules/gdscript/gdscript_editor.cpp2
-rw-r--r--modules/gdscript/gdscript_parser.cpp16
10 files changed, 284 insertions, 16 deletions
diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml
index 9e742ea581..b45716544a 100644
--- a/doc/classes/ArrayMesh.xml
+++ b/doc/classes/ArrayMesh.xml
@@ -22,6 +22,8 @@
m.mesh = arr_mesh
[/codeblock]
The [MeshInstance3D] is ready to be added to the [SceneTree] to be shown.
+ See also [ImmediateGeometry3D], [MeshDataTool] and [SurfaceTool] for procedural geometry generation.
+ [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/content/procedural_geometry/arraymesh.html</link>
@@ -56,7 +58,6 @@
Surfaces are created to be rendered using a [code]primitive[/code], which may be any of the types defined in [enum Mesh.PrimitiveType]. (As a note, when using indices, it is recommended to only use points, lines or triangles.) [method Mesh.get_surface_count] will become the [code]surf_idx[/code] for this new surface.
The [code]arrays[/code] argument is an array of arrays. See [enum ArrayType] for the values used in this array. For example, [code]arrays[0][/code] is the array of vertices. That first vertex sub-array is always required; the others are optional. Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data and the index array defines the vertex order. All sub-arrays must have the same length as the vertex array or be empty, except for [constant ARRAY_INDEX] if it is used.
Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data, and the index array defines the order of the vertices.
- Godot uses clockwise winding order for front faces of triangle primitive modes.
</description>
</method>
<method name="clear_blend_shapes">
diff --git a/doc/classes/ImmediateGeometry3D.xml b/doc/classes/ImmediateGeometry3D.xml
index 1c0831c922..d2d663847f 100644
--- a/doc/classes/ImmediateGeometry3D.xml
+++ b/doc/classes/ImmediateGeometry3D.xml
@@ -5,6 +5,9 @@
</brief_description>
<description>
Draws simple geometry from code. Uses a drawing mode similar to OpenGL 1.x.
+ See also [ArrayMesh], [MeshDataTool] and [SurfaceTool] for procedural geometry generation.
+ [b]Note:[/b] ImmediateGeometry3D is best suited to small amounts of mesh data that change every frame. It will be slow when handling large amounts of mesh data. If mesh data doesn't change often, use [ArrayMesh], [MeshDataTool] or [SurfaceTool] instead.
+ [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/MeshDataTool.xml b/doc/classes/MeshDataTool.xml
index 81ff5969e3..dcc3bbf2a6 100644
--- a/doc/classes/MeshDataTool.xml
+++ b/doc/classes/MeshDataTool.xml
@@ -17,6 +17,8 @@
mesh.surface_remove(0)
mdt.commit_to_surface(mesh)
[/codeblock]
+ See also [ArrayMesh], [ImmediateGeometry3D] and [SurfaceTool] for procedural geometry generation.
+ [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml
index 4304a8df5e..eeb6b6cd9d 100644
--- a/doc/classes/SurfaceTool.xml
+++ b/doc/classes/SurfaceTool.xml
@@ -15,6 +15,8 @@
The above [SurfaceTool] now contains one vertex of a triangle which has a UV coordinate and a specified [Color]. If another vertex were added without calling [method add_uv] or [method add_color], then the last values would be used.
Vertex attributes must be passed [b]before[/b] calling [method add_vertex]. Failure to do so will result in an error when committing the vertex information to a mesh.
Additionally, the attributes used before the first vertex is added determine the format of the mesh. For example, if you only add UVs to the first vertex, you cannot add color to any of the subsequent vertices.
+ See also [ArrayMesh], [ImmediateGeometry3D] and [MeshDataTool] for procedural geometry generation.
+ [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description>
<tutorials>
</tutorials>
diff --git a/editor/icons/Decal.svg b/editor/icons/Decal.svg
new file mode 100644
index 0000000000..23502c9d72
--- /dev/null
+++ b/editor/icons/Decal.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2c-3.3137085 0-6 2.6862915-6 6 0 2.220299 1.2092804 4.153789 3.0019531 5.191406-.05462-.325384-.089844-.657141-.089844-.998047 0-3.3137076 2.6862921-5.9999996 5.9999999-5.9999996 1.093408 0 2.115228.2976087 2.998047.8085937-.476307-2.8374399-2.937354-5.0019531-5.910156-5.0019531z" fill="#fc9c9c"/><path d="m5.001954 13.191406 8.908202-6.1894529c-.882819-.510985-1.904638-.808594-2.998046-.808594-3.3137079 0-6 2.686292-6 5.9999999 0 .340906.03522.672663.08984.998047z" fill="#ff5d5d"/><path d="m13.910156 7.0019531-8.908202 6.1894529c.882819.510985 1.904638.808594 2.998046.808594 3.313708 0 6-2.686292 6-5.9999999 0-.340906-.03522-.672663-.08984-.998047z" fill="#fc9c9c" fill-opacity=".392157"/></svg> \ No newline at end of file
diff --git a/misc/hooks/pre-commit-black b/misc/hooks/pre-commit-black
index 2dcc2e8cf1..76d97294da 100755
--- a/misc/hooks/pre-commit-black
+++ b/misc/hooks/pre-commit-black
@@ -6,7 +6,7 @@
##################################################################
# SETTINGS
# Set path to black binary.
-BLACK=`which black`
+BLACK=`which black 2>/dev/null`
BLACK_OPTIONS="-l 120"
# Remove any older patches from previous commits. Set to true or false.
@@ -18,13 +18,22 @@ FILE_EXTS="py"
# Use pygmentize instead of cat to parse diff with highlighting.
# Install it with `pip install pygments` (Linux) or `easy_install Pygments` (Mac)
-PYGMENTIZE=`which pygmentize`
+PYGMENTIZE=`which pygmentize 2>/dev/null`
if [ ! -z "$PYGMENTIZE" ]; then
READER="pygmentize -l diff"
else
READER=cat
fi
+# Path to zenity
+ZENITY=`which zenity 2>/dev/null`
+
+# Path to xmessage
+XMSG=`which xmessage 2>/dev/null`
+
+# Path to powershell (Windows only)
+PWSH=`which powershell 2>/dev/null`
+
##################################################################
# There should be no need to change anything below this line.
@@ -53,6 +62,19 @@ else
fi
if [ ! -x "$BLACK" ] ; then
+ if [ ! -t 1 ] ; then
+ if [ -x "$ZENITY" ] ; then
+ $ZENITY --error --title="Error" --text="Error: black executable not found."
+ exit 1
+ elif [ -x "$XMSG" ] ; then
+ $XMSG -center -title "Error" "Error: black executable not found."
+ exit 1
+ elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then
+ winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")"
+ $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -center -title "Error" --text "Error: black executable not found."
+ exit 1
+ fi
+ fi
printf "Error: black executable not found.\n"
printf "Set the correct path in $(canonicalize_filename "$0").\n"
exit 1
@@ -99,14 +121,62 @@ fi
# a patch has been created, notify the user and exit
printf "\nThe following differences were found between the code to commit "
printf "and the black formatter rules:\n\n"
-$READER "$patch"
-printf "\n"
-# Allows us to read user input below, assigns stdin to keyboard
-exec < /dev/tty
+if [ -t 1 ] ; then
+ $READER "$patch"
+ printf "\n"
+ # Allows us to read user input below, assigns stdin to keyboard
+ exec < /dev/tty
+ terminal="1"
+else
+ cat "$patch"
+ printf "\n"
+ # Allows non zero zenity/powershell output
+ set +e
+ terminal="0"
+fi
while true; do
- read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn
+ if [ $terminal = "0" ] ; then
+ if [ -x "$ZENITY" ] ; then
+ ans=$($ZENITY --text-info --filename="$patch" --width=800 --height=600 --title="Do you want to apply that patch?" --ok-label="Apply" --cancel-label="Do not apply" --extra-button="Apply and stage")
+ if [ "$?" = "0" ] ; then
+ yn="Y"
+ else
+ if [ "$ans" = "Apply and stage" ] ; then
+ yn="S"
+ else
+ yn="N"
+ fi
+ fi
+ elif [ -x "$XMSG" ] ; then
+ $XMSG -file "$patch" -buttons "Apply":100,"Apply and stage":200,"Do not apply":0 -center -default "Do not apply" -geometry 800x600 -title "Do you want to apply that patch?"
+ ans=$?
+ if [ "$ans" = "100" ] ; then
+ yn="Y"
+ elif [ "$ans" = "200" ] ; then
+ yn="S"
+ else
+ yn="N"
+ fi
+ elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then
+ winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")"
+ $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -file "$patch" -buttons "Apply":100,"Apply and stage":200,"Do not apply":0 -center -default "Do not apply" -geometry 800x600 -title "Do you want to apply that patch?"
+ ans=$?
+ if [ "$ans" = "100" ] ; then
+ yn="Y"
+ elif [ "$ans" = "200" ] ; then
+ yn="S"
+ else
+ yn="N"
+ fi
+ else
+ printf "Error: zenity, xmessage, or powershell executable not found.\n"
+ exit 1
+ fi
+ else
+ read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn
+ fi
case $yn in
[Yy] ) git apply $patch;
printf "The patch was applied. You can now stage the changes and commit again.\n\n";
diff --git a/misc/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format
index c5cf4ecbb1..4e1fbdeb20 100755
--- a/misc/hooks/pre-commit-clang-format
+++ b/misc/hooks/pre-commit-clang-format
@@ -16,7 +16,7 @@
##################################################################
# SETTINGS
# Set path to clang-format binary.
-CLANG_FORMAT=`which clang-format`
+CLANG_FORMAT=`which clang-format 2>/dev/null`
# Remove any older patches from previous commits. Set to true or false.
DELETE_OLD_PATCHES=false
@@ -31,13 +31,22 @@ FILE_EXTS=".c .h .cpp .hpp .cc .hh .cxx .m .mm .inc .java .glsl"
# Use pygmentize instead of cat to parse diff with highlighting.
# Install it with `pip install pygments` (Linux) or `easy_install Pygments` (Mac)
-PYGMENTIZE=`which pygmentize`
+PYGMENTIZE=`which pygmentize 2>/dev/null`
if [ ! -z "$PYGMENTIZE" ]; then
READER="pygmentize -l diff"
else
READER=cat
fi
+# Path to zenity
+ZENITY=`which zenity 2>/dev/null`
+
+# Path to xmessage
+XMSG=`which xmessage 2>/dev/null`
+
+# Path to powershell (Windows only)
+PWSH=`which powershell 2>/dev/null`
+
##################################################################
# There should be no need to change anything below this line.
@@ -66,6 +75,19 @@ else
fi
if [ ! -x "$CLANG_FORMAT" ] ; then
+ if [ ! -t 1 ] ; then
+ if [ -x "$ZENITY" ] ; then
+ $ZENITY --error --title="Error" --text="Error: clang-format executable not found."
+ exit 1
+ elif [ -x "$XMSG" ] ; then
+ $XMSG -center -title "Error" "Error: clang-format executable not found."
+ exit 1
+ elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then
+ winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")"
+ $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -center -title "Error" --text "Error: clang-format executable not found."
+ exit 1
+ fi
+ fi
printf "Error: clang-format executable not found.\n"
printf "Set the correct path in $(canonicalize_filename "$0").\n"
exit 1
@@ -117,14 +139,62 @@ fi
# a patch has been created, notify the user and exit
printf "\nThe following differences were found between the code to commit "
printf "and the clang-format rules:\n\n"
-$READER "$patch"
-printf "\n"
-# Allows us to read user input below, assigns stdin to keyboard
-exec < /dev/tty
+if [ -t 1 ] ; then
+ $READER "$patch"
+ printf "\n"
+ # Allows us to read user input below, assigns stdin to keyboard
+ exec < /dev/tty
+ terminal="1"
+else
+ cat "$patch"
+ printf "\n"
+ # Allows non zero zenity/powershell output
+ set +e
+ terminal="0"
+fi
while true; do
- read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn
+ if [ $terminal = "0" ] ; then
+ if [ -x "$ZENITY" ] ; then
+ ans=$($ZENITY --text-info --filename="$patch" --width=800 --height=600 --title="Do you want to apply that patch?" --ok-label="Apply" --cancel-label="Do not apply" --extra-button="Apply and stage")
+ if [ "$?" = "0" ] ; then
+ yn="Y"
+ else
+ if [ "$ans" = "Apply and stage" ] ; then
+ yn="S"
+ else
+ yn="N"
+ fi
+ fi
+ elif [ -x "$XMSG" ] ; then
+ $XMSG -file "$patch" -buttons "Apply":100,"Apply and stage":200,"Do not apply":0 -center -default "Do not apply" -geometry 800x600 -title "Do you want to apply that patch?"
+ ans=$?
+ if [ "$ans" = "100" ] ; then
+ yn="Y"
+ elif [ "$ans" = "200" ] ; then
+ yn="S"
+ else
+ yn="N"
+ fi
+ elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then
+ winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")"
+ $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -file "$patch" -buttons "Apply":100,"Apply and stage":200,"Do not apply":0 -center -default "Do not apply" -geometry 800x600 -title "Do you want to apply that patch?"
+ ans=$?
+ if [ "$ans" = "100" ] ; then
+ yn="Y"
+ elif [ "$ans" = "200" ] ; then
+ yn="S"
+ else
+ yn="N"
+ fi
+ else
+ printf "Error: zenity, xmessage, or powershell executable not found.\n"
+ exit 1
+ fi
+ else
+ read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn
+ fi
case $yn in
[Yy] ) git apply $patch;
printf "The patch was applied. You can now stage the changes and commit again.\n\n";
diff --git a/misc/hooks/winmessage.ps1 b/misc/hooks/winmessage.ps1
new file mode 100755
index 0000000000..3672579544
--- /dev/null
+++ b/misc/hooks/winmessage.ps1
@@ -0,0 +1,103 @@
+Param (
+ [string]$file = "",
+ [string]$text = "",
+ [string]$buttons = "OK:0",
+ [string]$default = "",
+ [switch]$nearmouse = $false,
+ [switch]$center = $false,
+ [string]$geometry = "",
+ [int32]$timeout = 0,
+ [string]$title = "Message"
+)
+Add-Type -assembly System.Windows.Forms
+
+$global:Result = 0
+
+$main_form = New-Object System.Windows.Forms.Form
+$main_form.Text = $title
+
+$geometry_data = $geometry.Split("+")
+if ($geometry_data.Length -ge 1) {
+ $size_data = $geometry_data[0].Split("x")
+ if ($size_data.Length -eq 2) {
+ $main_form.Width = $size_data[0]
+ $main_form.Height = $size_data[1]
+ }
+}
+if ($geometry_data.Length -eq 3) {
+ $main_form.StartPosition = [System.Windows.Forms.FormStartPosition]::Manual
+ $main_form.Location = New-Object System.Drawing.Point($geometry_data[1], $geometry_data[2])
+}
+if ($nearmouse) {
+ $main_form.StartPosition = [System.Windows.Forms.FormStartPosition]::Manual
+ $main_form.Location = System.Windows.Forms.Cursor.Position
+}
+if ($center) {
+ $main_form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
+}
+
+$main_form.SuspendLayout()
+
+$button_panel = New-Object System.Windows.Forms.FlowLayoutPanel
+$button_panel.SuspendLayout()
+$button_panel.FlowDirection = [System.Windows.Forms.FlowDirection]::RightToLeft
+$button_panel.Dock = [System.Windows.Forms.DockStyle]::Bottom
+$button_panel.Autosize = $true
+
+if ($file -ne "") {
+ $text = [IO.File]::ReadAllText($file).replace("`n", "`r`n")
+}
+
+if ($text -ne "") {
+ $text_box = New-Object System.Windows.Forms.TextBox
+ $text_box.Multiline = $true
+ $text_box.ReadOnly = $true
+ $text_box.Autosize = $true
+ $text_box.Text = $text
+ $text_box.Select(0,0)
+ $text_box.Dock = [System.Windows.Forms.DockStyle]::Fill
+ $main_form.Controls.Add($text_box)
+}
+
+$buttons_array = $buttons.Split(",")
+foreach ($button in $buttons_array) {
+ $button_data = $button.Split(":")
+ $button_ctl = New-Object System.Windows.Forms.Button
+ if ($button_data.Length -eq 2) {
+ $button_ctl.Tag = $button_data[1]
+ } else {
+ $button_ctl.Tag = 100 + $buttons_array.IndexOf($button)
+ }
+ if ($default -eq $button_data[0]) {
+ $main_form.AcceptButton = $button_ctl
+ }
+ $button_ctl.Autosize = $true
+ $button_ctl.Text = $button_data[0]
+ $button_ctl.Add_Click(
+ {
+ Param($sender)
+ $global:Result = $sender.Tag
+ $main_form.Close()
+ }
+ )
+ $button_panel.Controls.Add($button_ctl)
+}
+$main_form.Controls.Add($button_panel)
+
+$button_panel.ResumeLayout($false)
+$main_form.ResumeLayout($false)
+
+if ($timeout -gt 0) {
+ $timer = New-Object System.Windows.Forms.Timer
+ $timer.Add_Tick(
+ {
+ $global:Result = 0
+ $main_form.Close()
+ }
+ )
+ $timer.Interval = $timeout
+ $timer.Start()
+}
+$dlg_res = $main_form.ShowDialog()
+
+[Environment]::Exit($global:Result)
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 221cce205a..7ad0682637 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -2150,7 +2150,7 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p
}
const GDScriptParser::ClassNode *clss = p_context._class;
- bool _static = !p_context.function || p_context.function->_static;
+ bool _static = p_context.function && p_context.function->_static;
while (clss) {
GDScriptCompletionContext c = p_context;
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index a83416375c..c74d8cfbb0 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -746,6 +746,13 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
_make_completable_call(0);
completion_node = op;
+
+ if (op->arguments[0]->type == GDScriptParser::Node::Type::TYPE_BUILT_IN_FUNCTION) {
+ BuiltInFunctionNode *bn = static_cast<BuiltInFunctionNode *>(op->arguments[0]);
+ if (bn->function == GDScriptFunctions::Function::RESOURCE_LOAD) {
+ completion_type = COMPLETION_RESOURCE_PATH;
+ }
+ }
}
if (!replaced) {
if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant))
@@ -2794,6 +2801,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
return;
}
+ _mark_line_as_safe(line);
NewLineNode *nl2 = alloc_node<NewLineNode>();
nl2->line = line;
p_block->statements.push_back(nl2);
@@ -3307,6 +3315,8 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
return;
}
+ int assert_line = tokenizer->get_token_line();
+
tokenizer->advance();
Vector<Node *> args;
@@ -3320,8 +3330,14 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
return;
}
+#ifdef DEBUG_ENABLED
+ // Mark as safe, let type check mark as unsafe if needed
+ _mark_line_as_safe(assert_line);
+ _reduce_node_type(args[0]);
+#endif
AssertNode *an = alloc_node<AssertNode>();
an->condition = _reduce_expression(args[0], p_static);
+ an->line = assert_line;
if (args.size() == 2) {
an->message = _reduce_expression(args[1], p_static);