mirror of
https://github.com/godotengine/godot
synced 2024-09-30 04:53:46 +00:00
Compare commits
36 commits
0a9e6e478e
...
54346e94a9
Author | SHA1 | Date | |
---|---|---|---|
54346e94a9 | |||
50022484a3 | |||
8978196a48 | |||
c5c6f2db89 | |||
8f6cbf1724 | |||
9b93bdb4e7 | |||
e78088cc3a | |||
315d3c4d21 | |||
7c5e075531 | |||
2c0446b893 | |||
2e506516ee | |||
824784f80b | |||
6b59c57f2a | |||
6daf4d6008 | |||
8c211e64ec | |||
c8a61b67e4 | |||
65cbe89371 | |||
45b8274dc6 | |||
30f5fc0aa3 | |||
d8037528f0 | |||
9c84aae940 | |||
7c4774edd2 | |||
b4a6dcc947 | |||
4311836be2 | |||
ff5aecbc38 | |||
4b436d64aa | |||
7b04e3865a | |||
724d6581d6 | |||
a715a00d76 | |||
0d80705f11 | |||
0fcdf48f83 | |||
0a726862ea | |||
85ff7a2d2a | |||
2a39b5bcde | |||
70ebb6378c | |||
a54cb5b07b |
|
@ -339,7 +339,6 @@ NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) {
|
|||
data->refcount.init();
|
||||
data->absolute = p_absolute;
|
||||
data->path = p_path;
|
||||
data->has_slashes = true;
|
||||
data->hash_cache_valid = false;
|
||||
}
|
||||
|
||||
|
@ -353,7 +352,6 @@ NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p
|
|||
data->absolute = p_absolute;
|
||||
data->path = p_path;
|
||||
data->subpath = p_subpath;
|
||||
data->has_slashes = true;
|
||||
data->hash_cache_valid = false;
|
||||
}
|
||||
|
||||
|
@ -373,7 +371,6 @@ NodePath::NodePath(const String &p_path) {
|
|||
|
||||
bool absolute = (path[0] == '/');
|
||||
bool last_is_slash = true;
|
||||
bool has_slashes = false;
|
||||
int slices = 0;
|
||||
int subpath_pos = path.find(":");
|
||||
|
||||
|
@ -402,7 +399,6 @@ NodePath::NodePath(const String &p_path) {
|
|||
for (int i = (int)absolute; i < path.length(); i++) {
|
||||
if (path[i] == '/') {
|
||||
last_is_slash = true;
|
||||
has_slashes = true;
|
||||
} else {
|
||||
if (last_is_slash) {
|
||||
slices++;
|
||||
|
@ -419,7 +415,6 @@ NodePath::NodePath(const String &p_path) {
|
|||
data = memnew(Data);
|
||||
data->refcount.init();
|
||||
data->absolute = absolute;
|
||||
data->has_slashes = has_slashes;
|
||||
data->subpath = subpath;
|
||||
data->hash_cache_valid = false;
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ class NodePath {
|
|||
StringName concatenated_path;
|
||||
StringName concatenated_subpath;
|
||||
bool absolute;
|
||||
bool has_slashes;
|
||||
mutable bool hash_cache_valid;
|
||||
mutable uint32_t hash_cache;
|
||||
};
|
||||
|
|
|
@ -92,13 +92,6 @@
|
|||
[/codeblocks]
|
||||
</description>
|
||||
</method>
|
||||
<method name="rename_parameter">
|
||||
<return type="void" />
|
||||
<param index="0" name="old_name" type="String" />
|
||||
<param index="1" name="new_name" type="String" />
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="active" type="bool" setter="set_active" getter="is_active" default="false">
|
||||
|
|
|
@ -205,7 +205,7 @@
|
|||
<param index="2" name="atlas_coords" type="Vector2i" default="Vector2i(-1, -1)" />
|
||||
<param index="3" name="alternative_tile" type="int" default="-1" />
|
||||
<description>
|
||||
Returns a [Vector2i] array with the positions of all cells containing a tile in the given layer. Tiles may be filtered according to their source ([param source_id]), their atlas coordinates ([param atlas_coords]) or alternative id ([param source_id]).
|
||||
Returns a [Vector2i] array with the positions of all cells containing a tile in the given layer. Tiles may be filtered according to their source ([param source_id]), their atlas coordinates ([param atlas_coords]) or alternative id ([param alternative_tile]).
|
||||
If a parameter has it's value set to the default one, this parameter is not used to filter a cell. Thus, if all parameters have their respective default value, this method returns the same result as [method get_used_cells].
|
||||
A cell is considered empty if its source identifier equals -1, its atlas coordinates identifiers is [code]Vector2(-1, -1)[/code] and its alternative identifier is -1.
|
||||
</description>
|
||||
|
@ -279,8 +279,8 @@
|
|||
<description>
|
||||
Sets the tile indentifiers for the cell on layer [param layer] at coordinates [param coords]. Each tile of the [TileSet] is identified using three parts:
|
||||
- The source identifier [param source_id] identifies a [TileSetSource] identifier. See [method TileSet.set_source_id],
|
||||
- The atlas coordinates identifier [param atlas_coords] identifies a tile coordinates in the atlas (if the source is a [TileSetAtlasSource]. For [TileSetScenesCollectionSource] it should always be [code]Vector2i(0, 0)[/code]),
|
||||
- The alternative tile identifier [param alternative_tile] identifies a tile alternative the source is a [TileSetAtlasSource], and the scene for a [TileSetScenesCollectionSource].
|
||||
- The atlas coordinates identifier [param atlas_coords] identifies a tile coordinates in the atlas (if the source is a [TileSetAtlasSource]). For [TileSetScenesCollectionSource] it should always be [code]Vector2i(0, 0)[/code]),
|
||||
- The alternative tile identifier [param alternative_tile] identifies a tile alternative in the atlas (if the source is a [TileSetAtlasSource]), and the scene for a [TileSetScenesCollectionSource].
|
||||
If [param source_id] is set to [code]-1[/code], [param atlas_coords] to [code]Vector2i(-1, -1)[/code] or [param alternative_tile] to [code]-1[/code], the cell will be erased. An erased cell gets [b]all[/b] its identifiers automatically set to their respective invalid values, namely [code]-1[/code], [code]Vector2i(-1, -1)[/code] and [code]-1[/code].
|
||||
</description>
|
||||
</method>
|
||||
|
|
|
@ -591,14 +591,12 @@ void ConnectDialog::popup_dialog(const String p_for_signal) {
|
|||
|
||||
void ConnectDialog::_advanced_pressed() {
|
||||
if (advanced->is_pressed()) {
|
||||
set_min_size(Size2(900, 500) * EDSCALE);
|
||||
connect_to_label->set_text(TTR("Connect to Node:"));
|
||||
tree->set_connect_to_script_mode(false);
|
||||
|
||||
vbc_right->show();
|
||||
error_label->hide();
|
||||
} else {
|
||||
set_min_size(Size2(600, 500) * EDSCALE);
|
||||
reset_size();
|
||||
connect_to_label->set_text(TTR("Connect to Script:"));
|
||||
tree->set_connect_to_script_mode(true);
|
||||
|
@ -613,18 +611,15 @@ void ConnectDialog::_advanced_pressed() {
|
|||
}
|
||||
|
||||
ConnectDialog::ConnectDialog() {
|
||||
set_min_size(Size2(600, 500) * EDSCALE);
|
||||
|
||||
VBoxContainer *vbc = memnew(VBoxContainer);
|
||||
add_child(vbc);
|
||||
set_min_size(Size2(0, 500) * EDSCALE);
|
||||
|
||||
HBoxContainer *main_hb = memnew(HBoxContainer);
|
||||
vbc->add_child(main_hb);
|
||||
main_hb->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
add_child(main_hb);
|
||||
|
||||
VBoxContainer *vbc_left = memnew(VBoxContainer);
|
||||
main_hb->add_child(vbc_left);
|
||||
vbc_left->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
vbc_left->set_custom_minimum_size(Vector2(400 * EDSCALE, 0));
|
||||
|
||||
from_signal = memnew(LineEdit);
|
||||
vbc_left->add_margin_child(TTR("From Signal:"), from_signal);
|
||||
|
@ -685,6 +680,7 @@ ConnectDialog::ConnectDialog() {
|
|||
vbc_right = memnew(VBoxContainer);
|
||||
main_hb->add_child(vbc_right);
|
||||
vbc_right->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
vbc_right->set_custom_minimum_size(Vector2(150 * EDSCALE, 0));
|
||||
vbc_right->hide();
|
||||
|
||||
HBoxContainer *add_bind_hb = memnew(HBoxContainer);
|
||||
|
|
|
@ -65,6 +65,20 @@ void EditorLayoutsDialog::_line_gui_input(const Ref<InputEvent> &p_event) {
|
|||
}
|
||||
}
|
||||
|
||||
void EditorLayoutsDialog::_update_ok_disable_state() {
|
||||
if (layout_names->is_anything_selected()) {
|
||||
get_ok_button()->set_disabled(false);
|
||||
} else {
|
||||
get_ok_button()->set_disabled(!name->is_visible() || name->get_text().is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
void EditorLayoutsDialog::_deselect_layout_names() {
|
||||
// The deselect method does not emit any signal, therefore we need update the disable state as well.
|
||||
layout_names->deselect_all();
|
||||
_update_ok_disable_state();
|
||||
}
|
||||
|
||||
void EditorLayoutsDialog::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("name_confirmed", PropertyInfo(Variant::STRING, "name")));
|
||||
}
|
||||
|
@ -82,8 +96,8 @@ void EditorLayoutsDialog::ok_pressed() {
|
|||
|
||||
void EditorLayoutsDialog::_post_popup() {
|
||||
ConfirmationDialog::_post_popup();
|
||||
name->clear();
|
||||
layout_names->clear();
|
||||
name->clear();
|
||||
|
||||
Ref<ConfigFile> config;
|
||||
config.instantiate();
|
||||
|
@ -112,9 +126,9 @@ EditorLayoutsDialog::EditorLayoutsDialog() {
|
|||
makevb->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, -5);
|
||||
|
||||
layout_names = memnew(ItemList);
|
||||
layout_names->set_auto_height(true);
|
||||
makevb->add_margin_child(TTR("Select existing layout:"), layout_names);
|
||||
layout_names->set_custom_minimum_size(Size2(300 * EDSCALE, 1));
|
||||
layout_names->set_auto_height(true);
|
||||
layout_names->set_custom_minimum_size(Size2(300 * EDSCALE, 50 * EDSCALE));
|
||||
layout_names->set_visible(true);
|
||||
layout_names->set_offset(SIDE_TOP, 5);
|
||||
layout_names->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 5);
|
||||
|
@ -122,16 +136,17 @@ EditorLayoutsDialog::EditorLayoutsDialog() {
|
|||
layout_names->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
layout_names->set_select_mode(ItemList::SELECT_MULTI);
|
||||
layout_names->set_allow_rmb_select(true);
|
||||
layout_names->connect("multi_selected", callable_mp(this, &EditorLayoutsDialog::_update_ok_disable_state).unbind(2));
|
||||
|
||||
name = memnew(LineEdit);
|
||||
name->set_placeholder("Or enter new layout name");
|
||||
makevb->add_child(name);
|
||||
name->set_placeholder("Or enter new layout name");
|
||||
name->set_offset(SIDE_TOP, 5);
|
||||
name->set_custom_minimum_size(Size2(300 * EDSCALE, 1));
|
||||
name->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 5);
|
||||
name->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, -5);
|
||||
name->connect("gui_input", callable_mp(this, &EditorLayoutsDialog::_line_gui_input));
|
||||
name->connect("focus_entered", callable_mp(layout_names, &ItemList::deselect_all));
|
||||
name->connect("focus_entered", callable_mp(this, &EditorLayoutsDialog::_deselect_layout_names));
|
||||
name->connect("text_changed", callable_mp(this, &EditorLayoutsDialog::_update_ok_disable_state).unbind(1));
|
||||
}
|
||||
|
||||
void EditorLayoutsDialog::set_name_line_enabled(bool p_enabled) {
|
||||
|
|
|
@ -44,6 +44,8 @@ class EditorLayoutsDialog : public ConfirmationDialog {
|
|||
VBoxContainer *makevb = nullptr;
|
||||
|
||||
void _line_gui_input(const Ref<InputEvent> &p_event);
|
||||
void _update_ok_disable_state();
|
||||
void _deselect_layout_names();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
|
|
@ -2636,7 +2636,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
|
|||
new_menu->connect("id_pressed", callable_mp(this, &FileSystemDock::_tree_rmb_option));
|
||||
|
||||
p_popup->add_child(new_menu);
|
||||
p_popup->add_submenu_item(TTR("New"), "New");
|
||||
p_popup->add_submenu_item(TTR("New"), "New", FILE_NEW);
|
||||
|
||||
new_menu->add_icon_item(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")), TTR("Folder..."), FILE_NEW_FOLDER);
|
||||
new_menu->add_icon_item(get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")), TTR("Scene..."), FILE_NEW_SCENE);
|
||||
|
|
|
@ -90,17 +90,18 @@ private:
|
|||
FILE_DUPLICATE,
|
||||
FILE_REIMPORT,
|
||||
FILE_INFO,
|
||||
FILE_NEW_FOLDER,
|
||||
FILE_NEW_SCRIPT,
|
||||
FILE_NEW_SCENE,
|
||||
FILE_NEW,
|
||||
FILE_SHOW_IN_EXPLORER,
|
||||
FILE_OPEN_EXTERNAL,
|
||||
FILE_COPY_PATH,
|
||||
FILE_COPY_UID,
|
||||
FILE_NEW_RESOURCE,
|
||||
FILE_NEW_TEXTFILE,
|
||||
FOLDER_EXPAND_ALL,
|
||||
FOLDER_COLLAPSE_ALL,
|
||||
FILE_NEW_RESOURCE,
|
||||
FILE_NEW_TEXTFILE,
|
||||
FILE_NEW_FOLDER,
|
||||
FILE_NEW_SCRIPT,
|
||||
FILE_NEW_SCENE,
|
||||
};
|
||||
|
||||
FileSortOption file_sort = FILE_SORT_NAME;
|
||||
|
|
|
@ -985,8 +985,6 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima
|
|||
undo_redo->create_action(TTR("Node Renamed"));
|
||||
undo_redo->add_do_method(blend_tree.ptr(), "rename_node", prev_name, name);
|
||||
undo_redo->add_undo_method(blend_tree.ptr(), "rename_node", name, prev_name);
|
||||
undo_redo->add_do_method(tree, "rename_parameter", base_path + prev_name, base_path + name);
|
||||
undo_redo->add_undo_method(tree, "rename_parameter", base_path + name, base_path + prev_name);
|
||||
undo_redo->add_do_method(this, "update_graph");
|
||||
undo_redo->add_undo_method(this, "update_graph");
|
||||
undo_redo->commit_action();
|
||||
|
|
|
@ -2404,7 +2404,7 @@ Vector<String> ProjectConverter3To4::check_for_files() {
|
|||
directories_to_check.append(current_dir.path_join(file_name) + "/");
|
||||
} else {
|
||||
bool proper_extension = false;
|
||||
if (file_name.ends_with(".gd") || file_name.ends_with(".shader") || file_name.ends_with(".tscn") || file_name.ends_with(".tres") || file_name.ends_with(".godot") || file_name.ends_with(".cs") || file_name.ends_with(".csproj"))
|
||||
if (file_name.ends_with(".gd") || file_name.ends_with(".shader") || file_name.ends_with(".gdshader") || file_name.ends_with(".tscn") || file_name.ends_with(".tres") || file_name.ends_with(".godot") || file_name.ends_with(".cs") || file_name.ends_with(".csproj"))
|
||||
proper_extension = true;
|
||||
|
||||
if (proper_extension) {
|
||||
|
|
|
@ -4037,6 +4037,10 @@ void GDScriptAnalyzer::reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op)
|
|||
Variant GDScriptAnalyzer::make_expression_reduced_value(GDScriptParser::ExpressionNode *p_expression, bool &is_reduced) {
|
||||
Variant value;
|
||||
|
||||
if (p_expression == nullptr) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (p_expression->is_constant) {
|
||||
is_reduced = true;
|
||||
value = p_expression->reduced_value;
|
||||
|
@ -4101,6 +4105,10 @@ Variant GDScriptAnalyzer::make_dictionary_reduced_value(GDScriptParser::Dictiona
|
|||
}
|
||||
|
||||
Variant GDScriptAnalyzer::make_subscript_reduced_value(GDScriptParser::SubscriptNode *p_subscript, bool &is_reduced) {
|
||||
if (p_subscript->base == nullptr || p_subscript->index == nullptr) {
|
||||
return Variant();
|
||||
}
|
||||
|
||||
bool is_base_value_reduced = false;
|
||||
Variant base_value = make_expression_reduced_value(p_subscript->base, is_base_value_reduced);
|
||||
if (!is_base_value_reduced) {
|
||||
|
|
|
@ -1953,17 +1953,19 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
|
|||
case GDScriptParser::DataType::CLASS:
|
||||
if (base_type.class_type->has_function(p_context.current_function->identifier->name)) {
|
||||
GDScriptParser::FunctionNode *parent_function = base_type.class_type->get_member(p_context.current_function->identifier->name).function;
|
||||
const GDScriptParser::ParameterNode *parameter = parent_function->parameters[parent_function->parameters_indices[p_identifier]];
|
||||
if ((!id_type.is_set() || id_type.is_variant()) && parameter->get_datatype().is_hard_type()) {
|
||||
id_type = parameter->get_datatype();
|
||||
}
|
||||
if (parameter->initializer) {
|
||||
GDScriptParser::CompletionContext c = p_context;
|
||||
c.current_function = parent_function;
|
||||
c.current_class = base_type.class_type;
|
||||
c.base = nullptr;
|
||||
if (_guess_expression_type(c, parameter->initializer, r_type)) {
|
||||
return true;
|
||||
if (parent_function->parameters_indices.has(p_identifier)) {
|
||||
const GDScriptParser::ParameterNode *parameter = parent_function->parameters[parent_function->parameters_indices[p_identifier]];
|
||||
if ((!id_type.is_set() || id_type.is_variant()) && parameter->get_datatype().is_hard_type()) {
|
||||
id_type = parameter->get_datatype();
|
||||
}
|
||||
if (parameter->initializer) {
|
||||
GDScriptParser::CompletionContext c = p_context;
|
||||
c.current_function = parent_function;
|
||||
c.current_class = base_type.class_type;
|
||||
c.base = nullptr;
|
||||
if (_guess_expression_type(c, parameter->initializer, r_type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3602,6 +3602,7 @@ bool GDScriptParser::tool_annotation(const AnnotationNode *p_annotation, Node *p
|
|||
|
||||
bool GDScriptParser::icon_annotation(const AnnotationNode *p_annotation, Node *p_node) {
|
||||
ERR_FAIL_COND_V_MSG(p_node->type != Node::CLASS, false, R"("@icon" annotation can only be applied to classes.)");
|
||||
ERR_FAIL_COND_V(p_annotation->resolved_arguments.is_empty(), false);
|
||||
ClassNode *p_class = static_cast<ClassNode *>(p_node);
|
||||
p_class->icon_path = p_annotation->resolved_arguments[0];
|
||||
return true;
|
||||
|
@ -3830,6 +3831,10 @@ template <PropertyUsageFlags t_usage>
|
|||
bool GDScriptParser::export_group_annotations(const AnnotationNode *p_annotation, Node *p_node) {
|
||||
AnnotationNode *annotation = const_cast<AnnotationNode *>(p_annotation);
|
||||
|
||||
if (annotation->resolved_arguments.is_empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
annotation->export_info.name = annotation->resolved_arguments[0];
|
||||
|
||||
switch (t_usage) {
|
||||
|
@ -3887,7 +3892,7 @@ bool GDScriptParser::rpc_annotation(const AnnotationNode *p_annotation, Node *p_
|
|||
|
||||
Dictionary rpc_config;
|
||||
rpc_config["rpc_mode"] = MultiplayerAPI::RPC_MODE_AUTHORITY;
|
||||
if (p_annotation->resolved_arguments.size()) {
|
||||
if (!p_annotation->resolved_arguments.is_empty()) {
|
||||
int last = p_annotation->resolved_arguments.size() - 1;
|
||||
if (p_annotation->resolved_arguments[last].get_type() == Variant::INT) {
|
||||
rpc_config["channel"] = p_annotation->resolved_arguments[last].operator int();
|
||||
|
|
|
@ -185,7 +185,9 @@ namespace GodotTools.Export
|
|||
|
||||
foreach (string file in Directory.GetFiles(publishOutputTempDir, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
AddSharedObject(file, tags: null, projectDataDirName);
|
||||
AddSharedObject(file, tags: null,
|
||||
Path.Join(projectDataDirName,
|
||||
Path.GetRelativePath(publishOutputTempDir, Path.GetDirectoryName(file))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -262,7 +262,7 @@ TypedArray<RID> GodotNavigationServer::map_get_agents(RID p_map) const {
|
|||
const NavMap *map = map_owner.get_or_null(p_map);
|
||||
ERR_FAIL_COND_V(map == nullptr, agents_rids);
|
||||
|
||||
const LocalVector<RvoAgent *> agents = map->get_agents();
|
||||
const LocalVector<NavAgent *> agents = map->get_agents();
|
||||
agents_rids.resize(agents.size());
|
||||
|
||||
for (uint32_t i = 0; i < agents.size(); i++) {
|
||||
|
@ -282,7 +282,7 @@ RID GodotNavigationServer::region_get_map(RID p_region) const {
|
|||
}
|
||||
|
||||
RID GodotNavigationServer::agent_get_map(RID p_agent) const {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND_V(agent == nullptr, RID());
|
||||
|
||||
if (agent->get_map()) {
|
||||
|
@ -579,13 +579,13 @@ RID GodotNavigationServer::agent_create() {
|
|||
MutexLock lock(operations_mutex);
|
||||
|
||||
RID rid = agent_owner.make_rid();
|
||||
RvoAgent *agent = agent_owner.get_or_null(rid);
|
||||
NavAgent *agent = agent_owner.get_or_null(rid);
|
||||
agent->set_self(rid);
|
||||
return rid;
|
||||
}
|
||||
|
||||
COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND(agent == nullptr);
|
||||
|
||||
if (agent->get_map()) {
|
||||
|
@ -612,77 +612,77 @@ COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) {
|
|||
}
|
||||
|
||||
COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_distance) {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND(agent == nullptr);
|
||||
|
||||
agent->get_agent()->neighborDist_ = p_distance;
|
||||
}
|
||||
|
||||
COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count) {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND(agent == nullptr);
|
||||
|
||||
agent->get_agent()->maxNeighbors_ = p_count;
|
||||
}
|
||||
|
||||
COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time) {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND(agent == nullptr);
|
||||
|
||||
agent->get_agent()->timeHorizon_ = p_time;
|
||||
}
|
||||
|
||||
COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius) {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND(agent == nullptr);
|
||||
|
||||
agent->get_agent()->radius_ = p_radius;
|
||||
}
|
||||
|
||||
COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed) {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND(agent == nullptr);
|
||||
|
||||
agent->get_agent()->maxSpeed_ = p_max_speed;
|
||||
}
|
||||
|
||||
COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity) {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND(agent == nullptr);
|
||||
|
||||
agent->get_agent()->velocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z);
|
||||
}
|
||||
|
||||
COMMAND_2(agent_set_target_velocity, RID, p_agent, Vector3, p_velocity) {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND(agent == nullptr);
|
||||
|
||||
agent->get_agent()->prefVelocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z);
|
||||
}
|
||||
|
||||
COMMAND_2(agent_set_position, RID, p_agent, Vector3, p_position) {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND(agent == nullptr);
|
||||
|
||||
agent->get_agent()->position_ = RVO::Vector3(p_position.x, p_position.y, p_position.z);
|
||||
}
|
||||
|
||||
COMMAND_2(agent_set_ignore_y, RID, p_agent, bool, p_ignore) {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND(agent == nullptr);
|
||||
|
||||
agent->get_agent()->ignore_y_ = p_ignore;
|
||||
}
|
||||
|
||||
bool GodotNavigationServer::agent_is_map_changed(RID p_agent) const {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND_V(agent == nullptr, false);
|
||||
|
||||
return agent->is_map_changed();
|
||||
}
|
||||
|
||||
COMMAND_2(agent_set_callback, RID, p_agent, Callable, p_callback) {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_agent);
|
||||
ERR_FAIL_COND(agent == nullptr);
|
||||
|
||||
agent->set_callback(p_callback);
|
||||
|
@ -713,7 +713,7 @@ COMMAND_1(free, RID, p_object) {
|
|||
}
|
||||
|
||||
// Remove any assigned agent
|
||||
for (RvoAgent *agent : map->get_agents()) {
|
||||
for (NavAgent *agent : map->get_agents()) {
|
||||
map->remove_agent(agent);
|
||||
agent->set_map(nullptr);
|
||||
}
|
||||
|
@ -746,7 +746,7 @@ COMMAND_1(free, RID, p_object) {
|
|||
link_owner.free(p_object);
|
||||
|
||||
} else if (agent_owner.owns(p_object)) {
|
||||
RvoAgent *agent = agent_owner.get_or_null(p_object);
|
||||
NavAgent *agent = agent_owner.get_or_null(p_object);
|
||||
|
||||
// Removes this agent from the map if assigned
|
||||
if (agent->get_map() != nullptr) {
|
||||
|
|
|
@ -36,10 +36,10 @@
|
|||
#include "core/templates/rid_owner.h"
|
||||
#include "servers/navigation_server_3d.h"
|
||||
|
||||
#include "nav_agent.h"
|
||||
#include "nav_link.h"
|
||||
#include "nav_map.h"
|
||||
#include "nav_region.h"
|
||||
#include "rvo_agent.h"
|
||||
|
||||
/// The commands are functions executed during the `sync` phase.
|
||||
|
||||
|
@ -71,7 +71,7 @@ class GodotNavigationServer : public NavigationServer3D {
|
|||
mutable RID_Owner<NavLink> link_owner;
|
||||
mutable RID_Owner<NavMap> map_owner;
|
||||
mutable RID_Owner<NavRegion> region_owner;
|
||||
mutable RID_Owner<RvoAgent> agent_owner;
|
||||
mutable RID_Owner<NavAgent> agent_owner;
|
||||
|
||||
bool active = true;
|
||||
LocalVector<NavMap *> active_maps;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**************************************************************************/
|
||||
/* rvo_agent.cpp */
|
||||
/* nav_agent.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
|
@ -28,15 +28,15 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "rvo_agent.h"
|
||||
#include "nav_agent.h"
|
||||
|
||||
#include "nav_map.h"
|
||||
|
||||
void RvoAgent::set_map(NavMap *p_map) {
|
||||
void NavAgent::set_map(NavMap *p_map) {
|
||||
map = p_map;
|
||||
}
|
||||
|
||||
bool RvoAgent::is_map_changed() {
|
||||
bool NavAgent::is_map_changed() {
|
||||
if (map) {
|
||||
bool is_changed = map->get_map_update_id() != map_update_id;
|
||||
map_update_id = map->get_map_update_id();
|
||||
|
@ -46,15 +46,15 @@ bool RvoAgent::is_map_changed() {
|
|||
}
|
||||
}
|
||||
|
||||
void RvoAgent::set_callback(Callable p_callback) {
|
||||
void NavAgent::set_callback(Callable p_callback) {
|
||||
callback = p_callback;
|
||||
}
|
||||
|
||||
bool RvoAgent::has_callback() const {
|
||||
bool NavAgent::has_callback() const {
|
||||
return callback.is_valid();
|
||||
}
|
||||
|
||||
void RvoAgent::dispatch_callback() {
|
||||
void NavAgent::dispatch_callback() {
|
||||
if (!callback.is_valid()) {
|
||||
return;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/**************************************************************************/
|
||||
/* rvo_agent.h */
|
||||
/* nav_agent.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
|
@ -28,8 +28,8 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RVO_AGENT_H
|
||||
#define RVO_AGENT_H
|
||||
#ifndef NAV_AGENT_H
|
||||
#define NAV_AGENT_H
|
||||
|
||||
#include "core/object/class_db.h"
|
||||
#include "nav_rid.h"
|
||||
|
@ -38,7 +38,7 @@
|
|||
|
||||
class NavMap;
|
||||
|
||||
class RvoAgent : public NavRid {
|
||||
class NavAgent : public NavRid {
|
||||
NavMap *map = nullptr;
|
||||
RVO::Agent agent;
|
||||
Callable callback = Callable();
|
||||
|
@ -62,4 +62,4 @@ public:
|
|||
void dispatch_callback();
|
||||
};
|
||||
|
||||
#endif // RVO_AGENT_H
|
||||
#endif // NAV_AGENT_H
|
|
@ -31,9 +31,9 @@
|
|||
#include "nav_map.h"
|
||||
|
||||
#include "core/object/worker_thread_pool.h"
|
||||
#include "nav_agent.h"
|
||||
#include "nav_link.h"
|
||||
#include "nav_region.h"
|
||||
#include "rvo_agent.h"
|
||||
#include <algorithm>
|
||||
|
||||
#define THREE_POINTS_CROSS_PRODUCT(m_a, m_b, m_c) (((m_c) - (m_a)).cross((m_b) - (m_a)))
|
||||
|
@ -568,18 +568,18 @@ void NavMap::remove_link(NavLink *p_link) {
|
|||
}
|
||||
}
|
||||
|
||||
bool NavMap::has_agent(RvoAgent *agent) const {
|
||||
bool NavMap::has_agent(NavAgent *agent) const {
|
||||
return (agents.find(agent) != -1);
|
||||
}
|
||||
|
||||
void NavMap::add_agent(RvoAgent *agent) {
|
||||
void NavMap::add_agent(NavAgent *agent) {
|
||||
if (!has_agent(agent)) {
|
||||
agents.push_back(agent);
|
||||
agents_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void NavMap::remove_agent(RvoAgent *agent) {
|
||||
void NavMap::remove_agent(NavAgent *agent) {
|
||||
remove_agent_as_controlled(agent);
|
||||
int64_t agent_index = agents.find(agent);
|
||||
if (agent_index != -1) {
|
||||
|
@ -588,7 +588,7 @@ void NavMap::remove_agent(RvoAgent *agent) {
|
|||
}
|
||||
}
|
||||
|
||||
void NavMap::set_agent_as_controlled(RvoAgent *agent) {
|
||||
void NavMap::set_agent_as_controlled(NavAgent *agent) {
|
||||
const bool exist = (controlled_agents.find(agent) != -1);
|
||||
if (!exist) {
|
||||
ERR_FAIL_COND(!has_agent(agent));
|
||||
|
@ -596,7 +596,7 @@ void NavMap::set_agent_as_controlled(RvoAgent *agent) {
|
|||
}
|
||||
}
|
||||
|
||||
void NavMap::remove_agent_as_controlled(RvoAgent *agent) {
|
||||
void NavMap::remove_agent_as_controlled(NavAgent *agent) {
|
||||
int64_t active_avoidance_agent_index = controlled_agents.find(agent);
|
||||
if (active_avoidance_agent_index != -1) {
|
||||
controlled_agents.remove_at_unordered(active_avoidance_agent_index);
|
||||
|
@ -895,7 +895,7 @@ void NavMap::sync() {
|
|||
// cannot use LocalVector here as RVO library expects std::vector to build KdTree
|
||||
std::vector<RVO::Agent *> raw_agents;
|
||||
raw_agents.reserve(agents.size());
|
||||
for (RvoAgent *agent : agents) {
|
||||
for (NavAgent *agent : agents) {
|
||||
raw_agents.push_back(agent->get_agent());
|
||||
}
|
||||
rvo.buildAgentTree(raw_agents);
|
||||
|
@ -916,7 +916,7 @@ void NavMap::sync() {
|
|||
pm_edge_free_count = _new_pm_edge_free_count;
|
||||
}
|
||||
|
||||
void NavMap::compute_single_step(uint32_t index, RvoAgent **agent) {
|
||||
void NavMap::compute_single_step(uint32_t index, NavAgent **agent) {
|
||||
(*(agent + index))->get_agent()->computeNeighbors(&rvo);
|
||||
(*(agent + index))->get_agent()->computeNewVelocity(deltatime);
|
||||
}
|
||||
|
@ -930,7 +930,7 @@ void NavMap::step(real_t p_deltatime) {
|
|||
}
|
||||
|
||||
void NavMap::dispatch_callbacks() {
|
||||
for (RvoAgent *agent : controlled_agents) {
|
||||
for (NavAgent *agent : controlled_agents) {
|
||||
agent->dispatch_callback();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
class NavLink;
|
||||
class NavRegion;
|
||||
class RvoAgent;
|
||||
class NavAgent;
|
||||
|
||||
class NavMap : public NavRid {
|
||||
/// Map Up
|
||||
|
@ -78,10 +78,10 @@ class NavMap : public NavRid {
|
|||
bool agents_dirty = false;
|
||||
|
||||
/// All the Agents (even the controlled one)
|
||||
LocalVector<RvoAgent *> agents;
|
||||
LocalVector<NavAgent *> agents;
|
||||
|
||||
/// Controlled agents
|
||||
LocalVector<RvoAgent *> controlled_agents;
|
||||
LocalVector<NavAgent *> controlled_agents;
|
||||
|
||||
/// Physics delta time
|
||||
real_t deltatime = 0.0;
|
||||
|
@ -144,15 +144,15 @@ public:
|
|||
return links;
|
||||
}
|
||||
|
||||
bool has_agent(RvoAgent *agent) const;
|
||||
void add_agent(RvoAgent *agent);
|
||||
void remove_agent(RvoAgent *agent);
|
||||
const LocalVector<RvoAgent *> &get_agents() const {
|
||||
bool has_agent(NavAgent *agent) const;
|
||||
void add_agent(NavAgent *agent);
|
||||
void remove_agent(NavAgent *agent);
|
||||
const LocalVector<NavAgent *> &get_agents() const {
|
||||
return agents;
|
||||
}
|
||||
|
||||
void set_agent_as_controlled(RvoAgent *agent);
|
||||
void remove_agent_as_controlled(RvoAgent *agent);
|
||||
void set_agent_as_controlled(NavAgent *agent);
|
||||
void remove_agent_as_controlled(NavAgent *agent);
|
||||
|
||||
uint32_t get_map_update_id() const {
|
||||
return map_update_id;
|
||||
|
@ -173,7 +173,7 @@ public:
|
|||
int get_pm_edge_free_count() const { return pm_edge_free_count; }
|
||||
|
||||
private:
|
||||
void compute_single_step(uint32_t index, RvoAgent **agent);
|
||||
void compute_single_step(uint32_t index, NavAgent **agent);
|
||||
void clip_path(const LocalVector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly, Vector<int32_t> *r_path_types, TypedArray<RID> *r_path_rids, Vector<int64_t> *r_path_owners) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ env_openxr.add_source_files(module_obj, "extensions/openxr_fb_passthrough_extens
|
|||
env_openxr.add_source_files(module_obj, "extensions/openxr_fb_display_refresh_rate_extension.cpp")
|
||||
env_openxr.add_source_files(module_obj, "extensions/openxr_pico_controller_extension.cpp")
|
||||
env_openxr.add_source_files(module_obj, "extensions/openxr_wmr_controller_extension.cpp")
|
||||
env_openxr.add_source_files(module_obj, "extensions/openxr_ml2_controller_extension.cpp")
|
||||
|
||||
env.modules_sources += module_obj
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_ml2_controller_extension.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "openxr_ml2_controller_extension.h"
|
||||
#include "../action_map/openxr_interaction_profile_meta_data.h"
|
||||
|
||||
HashMap<String, bool *> OpenXRML2ControllerExtension::get_requested_extensions() {
|
||||
HashMap<String, bool *> request_extensions;
|
||||
|
||||
request_extensions[XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available;
|
||||
|
||||
return request_extensions;
|
||||
}
|
||||
|
||||
bool OpenXRML2ControllerExtension::is_available() {
|
||||
return available;
|
||||
}
|
||||
|
||||
void OpenXRML2ControllerExtension::on_register_metadata() {
|
||||
OpenXRInteractionProfileMetaData *metadata = OpenXRInteractionProfileMetaData::get_singleton();
|
||||
ERR_FAIL_NULL(metadata);
|
||||
|
||||
// Magic Leap 2 Controller
|
||||
const String profile_path = "/interaction_profiles/ml/ml2_controller";
|
||||
metadata->register_interaction_profile("Magic Leap 2 controller", "/interaction_profiles/ml/ml2_controller", XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME);
|
||||
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
|
||||
metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
|
||||
metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
|
||||
|
||||
metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
|
||||
metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
|
||||
metadata->register_io_path(profile_path, "Trigger click", user_path, user_path + "/input/trigger/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
|
||||
|
||||
metadata->register_io_path(profile_path, "Shoulder click", user_path, user_path + "/input/shoulder/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
|
||||
|
||||
metadata->register_io_path(profile_path, "Trackpad click", user_path, user_path + "/input/trackpad/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
|
||||
metadata->register_io_path(profile_path, "Trackpad force", user_path, user_path + "/input/trackpad/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
|
||||
metadata->register_io_path(profile_path, "Trackpad X", user_path, user_path + "/input/trackpad/x", "", OpenXRAction::OPENXR_ACTION_FLOAT);
|
||||
metadata->register_io_path(profile_path, "Trackpad Y", user_path, user_path + "/input/trackpad/y", "", OpenXRAction::OPENXR_ACTION_FLOAT);
|
||||
metadata->register_io_path(profile_path, "Trackpad touch", user_path, user_path + "/input/trackpad/touch", "", OpenXRAction::OPENXR_ACTION_VECTOR2);
|
||||
|
||||
metadata->register_io_path(profile_path, "Haptic output", user_path, user_path + "/output/haptic", "", OpenXRAction::OPENXR_ACTION_HAPTIC);
|
||||
}
|
||||
}
|
48
modules/openxr/extensions/openxr_ml2_controller_extension.h
Normal file
48
modules/openxr/extensions/openxr_ml2_controller_extension.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_ml2_controller_extension.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef OPENXR_ML2_CONTROLLER_EXTENSION_H
|
||||
#define OPENXR_ML2_CONTROLLER_EXTENSION_H
|
||||
|
||||
#include "openxr_extension_wrapper.h"
|
||||
|
||||
class OpenXRML2ControllerExtension : public OpenXRExtensionWrapper {
|
||||
public:
|
||||
virtual HashMap<String, bool *> get_requested_extensions() override;
|
||||
|
||||
bool is_available();
|
||||
|
||||
virtual void on_register_metadata() override;
|
||||
|
||||
private:
|
||||
bool available = false;
|
||||
};
|
||||
|
||||
#endif // OPENXR_ML2_CONTROLLER_EXTENSION_H
|
|
@ -52,6 +52,7 @@
|
|||
#include "extensions/openxr_htc_controller_extension.h"
|
||||
#include "extensions/openxr_htc_vive_tracker_extension.h"
|
||||
#include "extensions/openxr_huawei_controller_extension.h"
|
||||
#include "extensions/openxr_ml2_controller_extension.h"
|
||||
#include "extensions/openxr_palm_pose_extension.h"
|
||||
#include "extensions/openxr_pico_controller_extension.h"
|
||||
#include "extensions/openxr_wmr_controller_extension.h"
|
||||
|
@ -102,6 +103,7 @@ void initialize_openxr_module(ModuleInitializationLevel p_level) {
|
|||
OpenXRAPI::register_extension_wrapper(memnew(OpenXRFbPassthroughExtensionWrapper));
|
||||
OpenXRAPI::register_extension_wrapper(memnew(OpenXRDisplayRefreshRateExtension));
|
||||
OpenXRAPI::register_extension_wrapper(memnew(OpenXRWMRControllerExtension));
|
||||
OpenXRAPI::register_extension_wrapper(memnew(OpenXRML2ControllerExtension));
|
||||
}
|
||||
|
||||
if (OpenXRAPI::openxr_is_enabled()) {
|
||||
|
|
|
@ -899,10 +899,6 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
|
|||
bool screen_support_large = p_preset->get("screen/support_large");
|
||||
bool screen_support_xlarge = p_preset->get("screen/support_xlarge");
|
||||
|
||||
int xr_mode_index = p_preset->get("xr_features/xr_mode");
|
||||
int hand_tracking_index = p_preset->get("xr_features/hand_tracking");
|
||||
int hand_tracking_frequency_index = p_preset->get("xr_features/hand_tracking_frequency");
|
||||
|
||||
bool backup_allowed = p_preset->get("user_data_backup/allow");
|
||||
int app_category = p_preset->get("package/app_category");
|
||||
bool retain_data_on_uninstall = p_preset->get("package/retain_data_on_uninstall");
|
||||
|
@ -1046,25 +1042,6 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
|
|||
}
|
||||
}
|
||||
|
||||
// Hand tracking related configurations
|
||||
if (xr_mode_index == XR_MODE_OPENXR && hand_tracking_index > XR_HAND_TRACKING_NONE) {
|
||||
if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_metadata_name") {
|
||||
string_table.write[attr_value] = "com.oculus.handtracking.frequency";
|
||||
}
|
||||
|
||||
if (tname == "meta-data" && attrname == "value" && value == "xr_hand_tracking_metadata_value") {
|
||||
string_table.write[attr_value] = (hand_tracking_frequency_index == XR_HAND_TRACKING_FREQUENCY_LOW ? "LOW" : "HIGH");
|
||||
}
|
||||
|
||||
if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_version_name") {
|
||||
string_table.write[attr_value] = "com.oculus.handtracking.version";
|
||||
}
|
||||
|
||||
if (tname == "meta-data" && attrname == "value" && value == "xr_hand_tracking_version_value") {
|
||||
string_table.write[attr_value] = "V2.0";
|
||||
}
|
||||
}
|
||||
|
||||
iofs += 20;
|
||||
}
|
||||
|
||||
|
@ -1079,23 +1056,6 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
|
|||
Vector<bool> feature_required_list;
|
||||
Vector<int> feature_versions;
|
||||
|
||||
if (xr_mode_index == XR_MODE_OPENXR) {
|
||||
// Check for hand tracking
|
||||
if (hand_tracking_index > XR_HAND_TRACKING_NONE) {
|
||||
feature_names.push_back("oculus.software.handtracking");
|
||||
feature_required_list.push_back(hand_tracking_index == XR_HAND_TRACKING_REQUIRED);
|
||||
feature_versions.push_back(-1); // no version attribute should be added.
|
||||
}
|
||||
|
||||
// Check for passthrough
|
||||
int passthrough_mode = p_preset->get("xr_features/passthrough");
|
||||
if (passthrough_mode > XR_PASSTHROUGH_NONE) {
|
||||
feature_names.push_back("com.oculus.feature.PASSTHROUGH");
|
||||
feature_required_list.push_back(passthrough_mode == XR_PASSTHROUGH_REQUIRED);
|
||||
feature_versions.push_back(-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (feature_names.size() > 0) {
|
||||
ofs += 24; // skip over end tag
|
||||
|
||||
|
@ -2334,6 +2294,12 @@ bool EditorExportPlatformAndroid::has_valid_project_configuration(const Ref<Edit
|
|||
int xr_mode_index = p_preset->get("xr_features/xr_mode");
|
||||
int hand_tracking = p_preset->get("xr_features/hand_tracking");
|
||||
int passthrough_mode = p_preset->get("xr_features/passthrough");
|
||||
if (xr_mode_index == XR_MODE_OPENXR && !custom_build_enabled) {
|
||||
valid = false;
|
||||
err += TTR("OpenXR requires \"Use Custom Build\" to be enabled");
|
||||
err += "\n";
|
||||
}
|
||||
|
||||
if (xr_mode_index != XR_MODE_OPENXR) {
|
||||
if (hand_tracking > XR_HAND_TRACKING_NONE) {
|
||||
valid = false;
|
||||
|
|
|
@ -276,17 +276,39 @@ String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset) {
|
|||
return manifest_xr_features;
|
||||
}
|
||||
|
||||
String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
|
||||
String _get_activity_tag(const Ref<EditorExportPreset> &p_preset, bool p_uses_xr) {
|
||||
String orientation = _get_android_orientation_label(DisplayServer::ScreenOrientation(int(GLOBAL_GET("display/window/handheld/orientation"))));
|
||||
String manifest_activity_text = vformat(
|
||||
" <activity android:name=\"com.godot.game.GodotApp\" "
|
||||
"tools:replace=\"android:screenOrientation,android:excludeFromRecents,android:resizeableActivity\" "
|
||||
"tools:node=\"mergeOnlyAttributes\" "
|
||||
"android:excludeFromRecents=\"%s\" "
|
||||
"android:screenOrientation=\"%s\" "
|
||||
"android:resizeableActivity=\"%s\">\n",
|
||||
bool_to_string(p_preset->get("package/exclude_from_recents")),
|
||||
orientation,
|
||||
bool_to_string(bool(GLOBAL_GET("display/window/size/resizable"))));
|
||||
|
||||
if (p_uses_xr) {
|
||||
manifest_activity_text += " <intent-filter>\n"
|
||||
" <action android:name=\"android.intent.action.MAIN\" />\n"
|
||||
" <category android:name=\"android.intent.category.LAUNCHER\" />\n"
|
||||
"\n"
|
||||
" <!-- Enable access to OpenXR on Oculus mobile devices, no-op on other Android\n"
|
||||
" platforms. -->\n"
|
||||
" <category android:name=\"com.oculus.intent.category.VR\" />\n"
|
||||
"\n"
|
||||
" <!-- OpenXR category tag to indicate the activity starts in an immersive OpenXR mode. \n"
|
||||
" See https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#android-runtime-category. -->\n"
|
||||
" <category android:name=\"org.khronos.openxr.intent.category.IMMERSIVE_HMD\" />\n"
|
||||
" </intent-filter>\n";
|
||||
} else {
|
||||
manifest_activity_text += " <intent-filter>\n"
|
||||
" <action android:name=\"android.intent.action.MAIN\" />\n"
|
||||
" <category android:name=\"android.intent.category.LAUNCHER\" />\n"
|
||||
" </intent-filter>\n";
|
||||
}
|
||||
|
||||
manifest_activity_text += " </activity>\n";
|
||||
return manifest_activity_text;
|
||||
}
|
||||
|
@ -307,9 +329,7 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
|
|||
" android:hasFragileUserData=\"%s\"\n"
|
||||
" android:requestLegacyExternalStorage=\"%s\"\n"
|
||||
" tools:replace=\"android:allowBackup,android:appCategory,android:isGame,android:hasFragileUserData,android:requestLegacyExternalStorage\"\n"
|
||||
" tools:ignore=\"GoogleAppIndexingWarning\">\n\n"
|
||||
" <meta-data tools:node=\"remove\" android:name=\"xr_hand_tracking_version_name\" />\n"
|
||||
" <meta-data tools:node=\"remove\" android:name=\"xr_hand_tracking_metadata_name\" />\n",
|
||||
" tools:ignore=\"GoogleAppIndexingWarning\">\n\n",
|
||||
bool_to_string(p_preset->get("user_data_backup/allow")),
|
||||
_get_app_category_label(app_category_index),
|
||||
bool_to_string(is_game),
|
||||
|
@ -327,7 +347,7 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
|
|||
manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.oculus.handtracking.version\" android:value=\"V2.0\" />\n";
|
||||
}
|
||||
}
|
||||
manifest_application_text += _get_activity_tag(p_preset);
|
||||
manifest_application_text += _get_activity_tag(p_preset, uses_xr);
|
||||
manifest_application_text += " </application>\n";
|
||||
return manifest_application_text;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ String _get_screen_sizes_tag(const Ref<EditorExportPreset> &p_preset);
|
|||
|
||||
String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset);
|
||||
|
||||
String _get_activity_tag(const Ref<EditorExportPreset> &p_preset);
|
||||
String _get_activity_tag(const Ref<EditorExportPreset> &p_preset, bool p_uses_xr);
|
||||
|
||||
String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_read_write_storage_permission);
|
||||
|
||||
|
|
|
@ -31,23 +31,6 @@
|
|||
android:name="org.godotengine.editor.version"
|
||||
android:value="${godotEditorVersion}" />
|
||||
|
||||
<!-- The following metadata values are replaced when Godot exports, modifying them here has no effect. -->
|
||||
<!-- Do these changes in the export preset. Adding new ones is fine. -->
|
||||
|
||||
<!-- XR hand tracking metadata -->
|
||||
<!-- This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. -->
|
||||
<!-- Removed at export time if the xr mode is not VR or hand tracking is disabled. -->
|
||||
<meta-data
|
||||
android:name="xr_hand_tracking_metadata_name"
|
||||
android:value="xr_hand_tracking_metadata_value"/>
|
||||
|
||||
<!-- XR hand tracking version -->
|
||||
<!-- This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. -->
|
||||
<!-- Removed at export time if the xr mode is not VR or hand tracking is disabled. -->
|
||||
<meta-data
|
||||
android:name="xr_hand_tracking_version_name"
|
||||
android:value="xr_hand_tracking_version_value"/>
|
||||
|
||||
<activity
|
||||
android:name=".GodotApp"
|
||||
android:label="@string/godot_project_name_string"
|
||||
|
@ -63,10 +46,6 @@
|
|||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
||||
<!-- Enable access to OpenXR on Oculus mobile devices, no-op on other Android
|
||||
platforms. -->
|
||||
<category android:name="com.oculus.intent.category.VR" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
|
|
@ -3920,6 +3920,7 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
|
|||
}
|
||||
}
|
||||
show_window(MAIN_WINDOW_ID);
|
||||
force_process_and_drop_events();
|
||||
|
||||
#if defined(GLES3_ENABLED)
|
||||
if (rendering_driver == "opengl3") {
|
||||
|
|
|
@ -250,7 +250,7 @@ void Camera2D::_notification(int p_what) {
|
|||
add_to_group(group_name);
|
||||
add_to_group(canvas_group_name);
|
||||
|
||||
if (enabled && !viewport->get_camera_2d()) {
|
||||
if (!Engine::get_singleton()->is_editor_hint() && enabled && !viewport->get_camera_2d()) {
|
||||
make_current();
|
||||
}
|
||||
|
||||
|
@ -260,11 +260,11 @@ void Camera2D::_notification(int p_what) {
|
|||
} break;
|
||||
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
remove_from_group(group_name);
|
||||
remove_from_group(canvas_group_name);
|
||||
if (is_current()) {
|
||||
clear_current();
|
||||
}
|
||||
remove_from_group(group_name);
|
||||
remove_from_group(canvas_group_name);
|
||||
viewport = nullptr;
|
||||
} break;
|
||||
|
||||
|
|
|
@ -2084,20 +2084,6 @@ void AnimationTree::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||
}
|
||||
}
|
||||
|
||||
void AnimationTree::rename_parameter(const String &p_base, const String &p_new_base) {
|
||||
//rename values first
|
||||
for (const PropertyInfo &E : properties) {
|
||||
if (E.name.begins_with(p_base)) {
|
||||
String new_name = E.name.replace_first(p_base, p_new_base);
|
||||
property_map[new_name] = property_map[E.name];
|
||||
}
|
||||
}
|
||||
|
||||
//update tree second
|
||||
properties_dirty = true;
|
||||
_update_properties();
|
||||
}
|
||||
|
||||
real_t AnimationTree::get_connection_activity(const StringName &p_path, int p_connection) const {
|
||||
if (!input_activity_map_get.has(p_path)) {
|
||||
return 0;
|
||||
|
@ -2143,8 +2129,6 @@ void AnimationTree::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("_update_properties"), &AnimationTree::_update_properties);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("rename_parameter", "old_name", "new_name"), &AnimationTree::rename_parameter);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTree::advance);
|
||||
|
||||
GDVIRTUAL_BIND(_post_process_key_value, "animation", "track", "value", "object", "object_idx");
|
||||
|
|
|
@ -389,8 +389,6 @@ public:
|
|||
real_t get_connection_activity(const StringName &p_path, int p_connection) const;
|
||||
void advance(double p_time);
|
||||
|
||||
void rename_parameter(const String &p_base, const String &p_new_base);
|
||||
|
||||
uint64_t get_last_process_pass() const;
|
||||
AnimationTree();
|
||||
~AnimationTree();
|
||||
|
|
|
@ -84,6 +84,7 @@ void LineEdit::_move_caret_left(bool p_select, bool p_move_by_word) {
|
|||
}
|
||||
|
||||
shift_selection_check_post(p_select);
|
||||
_reset_caret_blink_timer();
|
||||
}
|
||||
|
||||
void LineEdit::_move_caret_right(bool p_select, bool p_move_by_word) {
|
||||
|
@ -116,6 +117,7 @@ void LineEdit::_move_caret_right(bool p_select, bool p_move_by_word) {
|
|||
}
|
||||
|
||||
shift_selection_check_post(p_select);
|
||||
_reset_caret_blink_timer();
|
||||
}
|
||||
|
||||
void LineEdit::_move_caret_start(bool p_select) {
|
||||
|
|
|
@ -1061,10 +1061,10 @@ void Viewport::assign_next_enabled_camera_2d(const StringName &p_camera_group) {
|
|||
get_tree()->get_nodes_in_group(p_camera_group, &camera_list);
|
||||
|
||||
Camera2D *new_camera = nullptr;
|
||||
for (const Node *E : camera_list) {
|
||||
const Camera2D *cam = Object::cast_to<Camera2D>(E);
|
||||
for (Node *E : camera_list) {
|
||||
Camera2D *cam = Object::cast_to<Camera2D>(E);
|
||||
if (cam->is_enabled()) {
|
||||
new_camera = const_cast<Camera2D *>(cam);
|
||||
new_camera = cam;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue