diff options
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 59 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.h | 2 | ||||
-rw-r--r-- | servers/rendering/shader_language.cpp | 112 | ||||
-rw-r--r-- | servers/rendering/shader_language.h | 1 |
4 files changed, 91 insertions, 83 deletions
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index f179c01f89..3173d2c7f0 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2697,15 +2697,28 @@ void Node3DEditorViewport::_notification(int p_what) { se->aabb = new_aabb; - t.translate(se->aabb.position); + Transform3D t_offset = t; // apply AABB scaling before item's global transform - Basis aabb_s; - aabb_s.scale(se->aabb.size); - t.basis = t.basis * aabb_s; + { + const Vector3 offset(0.005, 0.005, 0.005); + Basis aabb_s; + aabb_s.scale(se->aabb.size + offset); + t.translate(se->aabb.position - offset / 2); + t.basis = t.basis * aabb_s; + } + { + const Vector3 offset(0.01, 0.01, 0.01); + Basis aabb_s; + aabb_s.scale(se->aabb.size + offset); + t_offset.translate(se->aabb.position - offset / 2); + t_offset.basis = t_offset.basis * aabb_s; + } RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance, t); + RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_offset, t_offset); RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray, t); + RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray_offset, t_offset); } if (changed || (spatial_editor->is_gizmo_visible() && !exist)) { @@ -4731,9 +4744,15 @@ Node3DEditorSelectedItem::~Node3DEditorSelectedItem() { if (sbox_instance.is_valid()) { RenderingServer::get_singleton()->free(sbox_instance); } + if (sbox_instance_offset.is_valid()) { + RenderingServer::get_singleton()->free(sbox_instance_offset); + } if (sbox_instance_xray.is_valid()) { RenderingServer::get_singleton()->free(sbox_instance_xray); } + if (sbox_instance_xray_offset.is_valid()) { + RenderingServer::get_singleton()->free(sbox_instance_xray_offset); + } } void Node3DEditor::select_gizmo_highlight_axis(int p_axis) { @@ -4836,23 +4855,39 @@ Object *Node3DEditor::_get_editor_data(Object *p_what) { si->sbox_instance = RenderingServer::get_singleton()->instance_create2( selection_box->get_rid(), sp->get_world_3d()->get_scenario()); + si->sbox_instance_offset = RenderingServer::get_singleton()->instance_create2( + selection_box->get_rid(), + sp->get_world_3d()->get_scenario()); RS::get_singleton()->instance_geometry_set_cast_shadows_setting( si->sbox_instance, RS::SHADOW_CASTING_SETTING_OFF); + RS::get_singleton()->instance_geometry_set_cast_shadows_setting( + si->sbox_instance_offset, + RS::SHADOW_CASTING_SETTING_OFF); // Use the Edit layer to hide the selection box when View Gizmos is disabled, since it is a bit distracting. // It's still possible to approximately guess what is selected by looking at the manipulation gizmo position. RS::get_singleton()->instance_set_layer_mask(si->sbox_instance, 1 << Node3DEditorViewport::GIZMO_EDIT_LAYER); + RS::get_singleton()->instance_set_layer_mask(si->sbox_instance_offset, 1 << Node3DEditorViewport::GIZMO_EDIT_LAYER); RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true); + RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance_offset, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true); si->sbox_instance_xray = RenderingServer::get_singleton()->instance_create2( selection_box_xray->get_rid(), sp->get_world_3d()->get_scenario()); + si->sbox_instance_xray_offset = RenderingServer::get_singleton()->instance_create2( + selection_box_xray->get_rid(), + sp->get_world_3d()->get_scenario()); RS::get_singleton()->instance_geometry_set_cast_shadows_setting( si->sbox_instance_xray, RS::SHADOW_CASTING_SETTING_OFF); + RS::get_singleton()->instance_geometry_set_cast_shadows_setting( + si->sbox_instance_xray_offset, + RS::SHADOW_CASTING_SETTING_OFF); // Use the Edit layer to hide the selection box when View Gizmos is disabled, since it is a bit distracting. // It's still possible to approximately guess what is selected by looking at the manipulation gizmo position. RS::get_singleton()->instance_set_layer_mask(si->sbox_instance_xray, 1 << Node3DEditorViewport::GIZMO_EDIT_LAYER); - RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true); + RS::get_singleton()->instance_set_layer_mask(si->sbox_instance_xray_offset, 1 << Node3DEditorViewport::GIZMO_EDIT_LAYER); + RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance_xray, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true); + RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance_xray_offset, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true); return si; } @@ -4860,10 +4895,6 @@ Object *Node3DEditor::_get_editor_data(Object *p_what) { void Node3DEditor::_generate_selection_boxes() { // Use two AABBs to create the illusion of a slightly thicker line. AABB aabb(Vector3(), Vector3(1, 1, 1)); - AABB aabb_offset(Vector3(), Vector3(1, 1, 1)); - // Grow the bounding boxes slightly to avoid Z-fighting with the mesh's edges. - aabb.grow_by(0.005); - aabb_offset.grow_by(0.01); // Create a x-ray (visible through solid surfaces) and standard version of the selection box. // Both will be drawn at the same position, but with different opacity. @@ -4883,16 +4914,6 @@ void Node3DEditor::_generate_selection_boxes() { st_xray->add_vertex(b); } - for (int i = 0; i < 12; i++) { - Vector3 a, b; - aabb_offset.get_edge(i, a, b); - - st->add_vertex(a); - st->add_vertex(b); - st_xray->add_vertex(a); - st_xray->add_vertex(b); - } - Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D); mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); const Color selection_box_color = EDITOR_GET("editors/3d/selection_box_color"); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 59f3ec6fcd..e8948071e6 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -431,7 +431,9 @@ public: bool last_xform_dirty; Node3D *sp; RID sbox_instance; + RID sbox_instance_offset; RID sbox_instance_xray; + RID sbox_instance_xray_offset; Ref<EditorNode3DGizmo> gizmo; Map<int, Transform3D> subgizmos; // map ID -> initial transform diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index f99637fb06..f4de887912 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -930,7 +930,6 @@ void ShaderLanguage::clear() { error_set = false; error_str = ""; last_const = false; - pass_array = false; while (nodes) { Node *n = nodes; nodes = nodes->next; @@ -2387,9 +2386,12 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI failed_builtin = true; bool fail = false; for (int i = 0; i < argcount; i++) { - if (p_func->arguments[i + 1]->type == Node::TYPE_ARRAY && !static_cast<const ArrayNode *>(p_func->arguments[i + 1])->is_indexed()) { - fail = true; - break; + if (p_func->arguments[i + 1]->type == Node::TYPE_ARRAY) { + const ArrayNode *anode = static_cast<const ArrayNode *>(p_func->arguments[i + 1]); + if (anode->call_expression == nullptr && !anode->is_indexed()) { + fail = true; + break; + } } if (get_scalar_type(args[i]) == args[i] && p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[i + 1]), builtin_func_defs[idx].args[i])) { //all good, but needs implicit conversion later @@ -4007,9 +4009,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc if (!is_token_variable_datatype(tk.type)) { _set_tkpos(prev_pos); - pass_array = true; Node *n = _parse_and_reduce_expression(p_block, p_function_info); - pass_array = false; if (!n) { _set_error("Invalid data type for array"); @@ -4099,7 +4099,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc return nullptr; } - if (!_compare_datatypes(p_type, p_struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) { + if (!_compare_datatypes(p_type, p_struct_name, 0, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) { return nullptr; } @@ -4347,9 +4347,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons int carg = -1; - pass_array = true; bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg); - pass_array = false; // Check if block has a variable with the same name as function to prevent shader crash. ShaderLanguage::BlockNode *bnode = p_block; @@ -4601,62 +4599,58 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons Node *assign_expression = nullptr; if (array_size > 0) { - if (!pass_array) { - tk = _get_token(); + prepos = _get_tkpos(); + tk = _get_token(); - if (tk.type != TK_BRACKET_OPEN && tk.type != TK_PERIOD && tk.type != TK_OP_ASSIGN) { - _set_error("Expected '[','.' or '='"); + if (tk.type == TK_OP_ASSIGN) { + if (is_const) { + _set_error("Constants cannot be modified."); + return nullptr; + } + assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size); + if (!assign_expression) { + return nullptr; + } + } else if (tk.type == TK_PERIOD) { + completion_class = TAG_ARRAY; + p_block->block_tag = SubClassTag::TAG_ARRAY; + call_expression = _parse_and_reduce_expression(p_block, p_function_info); + p_block->block_tag = SubClassTag::TAG_GLOBAL; + if (!call_expression) { + return nullptr; + } + data_type = call_expression->get_datatype(); + } else if (tk.type == TK_BRACKET_OPEN) { // indexing + index_expression = _parse_and_reduce_expression(p_block, p_function_info); + if (!index_expression) { return nullptr; } - if (tk.type == TK_OP_ASSIGN) { - if (is_const) { - _set_error("Constants cannot be modified."); - return nullptr; - } - assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size); - if (!assign_expression) { - return nullptr; - } - } else if (tk.type == TK_PERIOD) { - completion_class = TAG_ARRAY; - p_block->block_tag = SubClassTag::TAG_ARRAY; - call_expression = _parse_and_reduce_expression(p_block, p_function_info); - p_block->block_tag = SubClassTag::TAG_GLOBAL; - if (!call_expression) { - return nullptr; - } - data_type = call_expression->get_datatype(); - } else { // indexing - index_expression = _parse_and_reduce_expression(p_block, p_function_info); - if (!index_expression) { - return nullptr; - } - - if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { - _set_error("Only integer expressions are allowed for indexing"); - return nullptr; - } + if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { + _set_error("Only integer expressions are allowed for indexing"); + return nullptr; + } - if (index_expression->type == Node::TYPE_CONSTANT) { - ConstantNode *cnode = (ConstantNode *)index_expression; - if (cnode) { - if (!cnode->values.is_empty()) { - int value = cnode->values[0].sint; - if (value < 0 || value >= array_size) { - _set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1)); - return nullptr; - } + if (index_expression->type == Node::TYPE_CONSTANT) { + ConstantNode *cnode = (ConstantNode *)index_expression; + if (cnode) { + if (!cnode->values.is_empty()) { + int value = cnode->values[0].sint; + if (value < 0 || value >= array_size) { + _set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1)); + return nullptr; } } } + } - tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); - return nullptr; - } + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return nullptr; } + } else { + _set_tkpos(prepos); } ArrayNode *arrname = alloc_node<ArrayNode>(); @@ -5081,10 +5075,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } mn->index_expression = index_expression; } else { - if (!pass_array) { - _set_error("Expected '[','.' or '='"); - return nullptr; - } _set_tkpos(prev_pos); } } @@ -6027,9 +6017,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun if (tk.type == TK_IDENTIFIER) { // a function call array initialization _set_tkpos(prev_pos); - pass_array = true; Node *n = _parse_and_reduce_expression(p_block, p_function_info); - pass_array = false; if (!n) { _set_error("Expected correct array initializer!"); @@ -6754,12 +6742,10 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } else { _set_tkpos(pos); //rollback, wants expression - pass_array = true; Node *expr = _parse_and_reduce_expression(p_block, p_function_info); if (!expr) { return ERR_PARSE_ERROR; } - pass_array = false; if (b->parent_function->return_type != expr->get_datatype() || b->parent_function->return_array_size != expr->get_array_size() || return_struct_name != expr->get_datatype_name()) { _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'"); diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 7908658028..1444546f05 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -876,7 +876,6 @@ private: StringName current_function; bool last_const = false; - bool pass_array = false; StringName last_name; VaryingFunctionNames varying_function_names; |