ronantakizawa/codereview-bench huggingface dataset:
Repository: godotengine/godot
File: modules/gdscript/gdscript.cpp (C++)

Code before:
	MutexLock lock(this->mutex);

	SelfList<GDScriptFunction> *elem = function_list.first();
	while (elem) {
		elem->self()->profile.call_count.set(0);
		elem->self()->profile.self_time.set(0);
		elem->self()->profile.total_time.set(0);
		elem->self()->profile.frame_call_count.set(0);
		elem->self()->profile.frame_self_time.set(0);
		elem->self()->profile.frame_total_time.set(0);
		elem->self()->profile.last_frame_call_count = 0;
		elem->self()->profile.last_frame_self_time = 0;
		elem->self()->profile.last_frame_total_time = 0;
		elem = elem->next();
	}

	profiling = true;
#endif
}

void GDScriptLanguage::profiling_stop() {
#ifdef DEBUG_ENABLED
	MutexLock lock(this->mutex);

	profiling = false;
#endif
}

int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
	int current = 0;
#ifdef DEBUG_ENABLED

	MutexLock lock(this->mutex);

	SelfList<GDScriptFunction> *elem = function_list.first();
	while (elem) {
		if (current >= p_info_max) {
			break;
		}
		p_info_arr[current].call_count = elem->self()->profile.call_count.get();
		p_info_arr[current].self_time = elem->self()->profile.self_time.get();
		p_info_arr[current].total_time = elem->self()->profile.total_time.get();
		p_info_arr[current].signature = elem->self()->profile.signature;
		elem = elem->next();
		current++;
	}
#endif

	return current;
}


Review comment (suggestion):
```suggestion
	profile_native_calls = p_enable;
```

Code after:
	MutexLock lock(this->mutex);

	SelfList<GDScriptFunction> *elem = function_list.first();
	while (elem) {
		elem->self()->profile.call_count.set(0);
		elem->self()->profile.self_time.set(0);
		elem->self()->profile.total_time.set(0);
		elem->self()->profile.frame_call_count.set(0);
		elem->self()->profile.frame_self_time.set(0);
		elem->self()->profile.frame_total_time.set(0);
		elem->self()->profile.last_frame_call_count = 0;
		elem->self()->profile.last_frame_self_time = 0;
		elem->self()->profile.last_frame_total_time = 0;
		elem->self()->profile.native_calls.clear();
		elem->self()->profile.last_native_calls.clear();
		elem = elem->next();
	}

	profiling = true;
#endif
}

void GDScriptLanguage::profiling_set_save_native_calls(bool p_enable) {
#ifdef DEBUG_ENABLED
	MutexLock lock(mutex);
	profile_native_calls = p_enable;
#endif
}

void GDScriptLanguage::profiling_stop() {
#ifdef DEBUG_ENABLED
	MutexLock lock(this->mutex);

	profiling = false;
#endif
}

int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
	int current = 0;
#ifdef DEBUG_ENABLED

	MutexLock lock(this->mutex);

	profiling_collate_native_call_data(true);
	SelfList<GDScriptFunction> *elem = function_list.first();
	while (elem) {
		if (current >= p_info_max) {
			break;
		}
		int last_non_internal = current;
		p_info_arr[current].call_count = elem->self()->profile.call_count.get();
Repository: godotengine/godot
File: editor/plugins/curve_editor_plugin.h (C/C++)

Code before:
	Vector2 get_tangent_view_pos(int i, TangentIndex tangent) const;
	Vector2 get_view_pos(Vector2 world_pos) const;
	Vector2 get_world_pos(Vector2 view_pos) const;

	void _draw();

private:
	Transform2D _world_to_view;

	Ref<Curve> _curve_ref;
	PopupMenu *_context_menu = nullptr;
	PopupMenu *_presets_menu = nullptr;

	Array _undo_data;
	bool _has_undo_data;

	Vector2 _context_click_pos;
	int _selected_point;
	int _hover_point;
	TangentIndex _selected_tangent;
	bool _dragging;

	// Constant
	float _hover_radius;
	float _tangents_length;
};

class EditorInspectorPluginCurve : public EditorInspectorPlugin {
	GDCLASS(EditorInspectorPluginCurve, EditorInspectorPlugin);

public:
	virtual bool can_handle(Object *p_object) override;
	virtual void parse_begin(Object *p_object) override;
};

class CurveEditorPlugin : public EditorPlugin {
	GDCLASS(CurveEditorPlugin, EditorPlugin);

public:
	CurveEditorPlugin();

	virtual String get_name() const override { return "Curve"; }
};

class CurvePreviewGenerator : public EditorResourcePreviewGenerator {
	GDCLASS(CurvePreviewGenerator, EditorResourcePreviewGenerator);

public:
	virtual bool handles(const String &p_type) const override;
	virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override;
};

Review comment (suggestion):
```suggestion
	float _gizmo_handle_scale = 0.0;
```
This should be initialized.
(other values too, but you don't need to change them)

Code after:
	Vector2 get_tangent_view_pos(int i, TangentIndex tangent) const;
	Vector2 get_view_pos(Vector2 world_pos) const;
	Vector2 get_world_pos(Vector2 view_pos) const;

	void _draw();

private:
	Transform2D _world_to_view;

	Ref<Curve> _curve_ref;
	PopupMenu *_context_menu = nullptr;
	PopupMenu *_presets_menu = nullptr;

	Array _undo_data;
	bool _has_undo_data;

	Vector2 _context_click_pos;
	int _selected_point;
	int _hover_point;
	TangentIndex _selected_tangent;
	bool _dragging;

	// Constant
	float _hover_radius;
	float _tangents_length;
	float _gizmo_handle_scale = 1.0;
};

class EditorInspectorPluginCurve : public EditorInspectorPlugin {
	GDCLASS(EditorInspectorPluginCurve, EditorInspectorPlugin);

public:
	virtual bool can_handle(Object *p_object) override;
	virtual void parse_begin(Object *p_object) override;
};

class CurveEditorPlugin : public EditorPlugin {
	GDCLASS(CurveEditorPlugin, EditorPlugin);

public:
	CurveEditorPlugin();

	virtual String get_name() const override { return "Curve"; }
};

class CurvePreviewGenerator : public EditorResourcePreviewGenerator {
	GDCLASS(CurvePreviewGenerator, EditorResourcePreviewGenerator);

public:
	virtual bool handles(const String &p_type) const override;
	virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override;
Repository: godotengine/godot
File: platform/uwp/export/export_plugin.h (C/C++)

Code before:
	"contacts",
	"enterpriseAuthentication",
	"musicLibrary",
	"objects3D",
	"picturesLibrary",
	"phoneCall",
	"removableStorage",
	"sharedUserCertificates",
	"userAccountInformation",
	"videosLibrary",
	"voipCall",
	nullptr
};
static const char *uwp_device_capabilities[] = {
	"bluetooth",
	"location",
	"microphone",
	"proximity",
	"webcam",
	nullptr
};

class EditorExportPlatformUWP : public EditorExportPlatform {
	GDCLASS(EditorExportPlatformUWP, EditorExportPlatform);

	Ref<ImageTexture> logo;

	bool _valid_resource_name(const String &p_name) const {
		if (p_name.is_empty()) {
			return false;
		}
		if (p_name.ends_with(".")) {
			return false;
		}

		static const char *invalid_names[] = {
			"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7",
			"COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
			nullptr
		};

		const char **t = invalid_names;
		while (*t) {
			if (p_name == *t) {
				return false;
			}
			t++;
		}

		return true;
	}

Review comment (suggestion):
```suggestion
const String ENV_UWP_SIGNING_CERT = "GODOT_UWP_SIGNING_CERTIFICATE";
const String ENV_UWP_SIGNING_PASS = "GODOT_UWP_SIGNING_PASSWORD";
```

Code after:
	"contacts",
	"enterpriseAuthentication",
	"musicLibrary",
	"objects3D",
	"picturesLibrary",
	"phoneCall",
	"removableStorage",
	"sharedUserCertificates",
	"userAccountInformation",
	"videosLibrary",
	"voipCall",
	nullptr
};
static const char *uwp_device_capabilities[] = {
	"bluetooth",
	"location",
	"microphone",
	"proximity",
	"webcam",
	nullptr
};

// Optional environment variables for defining confidential information. If any
// of these is set, they will override the values set in the credentials file.
const String ENV_UWP_SIGNING_CERT = "GODOT_UWP_SIGNING_CERTIFICATE";
const String ENV_UWP_SIGNING_PASS = "GODOT_UWP_SIGNING_PASSWORD";

class EditorExportPlatformUWP : public EditorExportPlatform {
	GDCLASS(EditorExportPlatformUWP, EditorExportPlatform);

	Ref<ImageTexture> logo;

	bool _valid_resource_name(const String &p_name) const {
		if (p_name.is_empty()) {
			return false;
		}
		if (p_name.ends_with(".")) {
			return false;
		}

		static const char *invalid_names[] = {
			"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7",
			"COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
			nullptr
		};

		const char **t = invalid_names;
		while (*t) {
			if (p_name == *t) {
				return false;
			}
Repository: godotengine/godot
File: editor/plugins/physical_bone_3d_editor_plugin.cpp (C++)

Code before:
void PhysicalBone3DEditor::hide() {
	spatial_editor_hb->hide();
}

void PhysicalBone3DEditor::show() {
	spatial_editor_hb->show();
}

PhysicalBone3DEditorPlugin::PhysicalBone3DEditorPlugin() {}

void PhysicalBone3DEditorPlugin::make_visible(bool p_visible) {
	if (p_visible) {
		physical_bone_editor.show();
	} else {
		physical_bone_editor.hide();
		physical_bone_editor.set_selected(nullptr);
		selected = nullptr;
	}
}

void PhysicalBone3DEditorPlugin::edit(Object *p_node) {
	selected = static_cast<PhysicalBone3D *>(p_node); // Trust it
	ERR_FAIL_COND(!selected);

	physical_bone_editor.set_selected(selected);
}


Review comment (suggestion):
```suggestion
	PhysicalBone3D *bone = Object::cast_to<PhysicalBone3D>(p_node);
	if (bone) {
		selected = bone;
		physical_bone_editor.set_selected(selected);
	}
```

Code after:
void PhysicalBone3DEditor::hide() {
	spatial_editor_hb->hide();
}

void PhysicalBone3DEditor::show() {
	spatial_editor_hb->show();
}

PhysicalBone3DEditorPlugin::PhysicalBone3DEditorPlugin() {}

void PhysicalBone3DEditorPlugin::make_visible(bool p_visible) {
	if (p_visible) {
		physical_bone_editor.show();
	} else {
		physical_bone_editor.hide();
		physical_bone_editor.set_selected(nullptr);
		selected = nullptr;
	}
}

void PhysicalBone3DEditorPlugin::edit(Object *p_node) {
	PhysicalBone3D *bone = Object::cast_to<PhysicalBone3D>(p_node);
	if (bone) {
		selected = bone;
		physical_bone_editor.set_selected(selected);
	}
}
Repository: godotengine/godot
File: editor/scene_tree_dock.cpp (C++)

Code before:
		}

		_do_create(parent);

		Vector<Node *> nodes;
		for (Node *E : selection) {
			nodes.push_back(E);
		}

		// This works because editor_selection was cleared and populated with last created node in _do_create()
		Node *last_created = editor_selection->get_selected_node_list().front()->get();
		_do_reparent(last_created, -1, nodes, true);
	}

	scene_tree->get_scene_tree()->grab_focus();
}

void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_properties, bool p_remove_old) {
	Node *n = p_node;
	Node *newnode = p_by_node;

	if (p_keep_properties) {
		Node *default_oldnode = Object::cast_to<Node>(ClassDB::instantiate(n->get_class()));
		List<PropertyInfo> pinfo;
		n->get_property_list(&pinfo);

		for (const PropertyInfo &E : pinfo) {
			if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
				continue;
			}

			if (default_oldnode->get(E.name) != n->get(E.name)) {
				newnode->set(E.name, n->get(E.name));
			}
		}

		memdelete(default_oldnode);
	}

	_push_item(nullptr);

	//reconnect signals
	List<MethodInfo> sl;

	n->get_signal_list(&sl);
	for (const MethodInfo &E : sl) {
		List<Object::Connection> cl;
		n->get_signal_connection_list(E.name, &cl);

		for (const Object::Connection &c : cl) {
			if (!(c.flags & Object::CONNECT_PERSIST)) {

Review comment (bug):
```suggestion
	ERR_FAIL_COND_MSG(!p_node->is_inside_tree(), "_replace_node() can't be called on a node outside of tree. You might have called it twice.");
```

Code after:
		Node *last_created = editor_selection->get_selected_node_list().front()->get();
		_do_reparent(last_created, -1, nodes, true);
	}

	scene_tree->get_scene_tree()->grab_focus();
}

void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node) {
	EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
	ur->create_action(TTR("Change type of node(s)"), UndoRedo::MERGE_DISABLE, p_node);

	ur->add_do_method(this, "replace_node", p_node, p_by_node, true, false);
	ur->add_do_reference(p_by_node);

	_replace_node(p_node, p_by_node, true, false);

	ur->add_undo_method(this, "replace_node", p_by_node, p_node, false, false);
	ur->add_undo_reference(p_node);

	perform_node_replace(nullptr, p_node, p_by_node);

	ur->commit_action(false);
}

void SceneTreeDock::_replace_node(Node *p_node, Node *p_by_node, bool p_keep_properties, bool p_remove_old) {
	ERR_FAIL_COND_MSG(!p_node->is_inside_tree(), "_replace_node() can't be called on a node outside of tree. You might have called it twice.");
	Node *n = p_node;
	Node *newnode = p_by_node;

	if (p_keep_properties) {
		Node *default_oldnode = Object::cast_to<Node>(ClassDB::instantiate(n->get_class()));
		List<PropertyInfo> pinfo;
		n->get_property_list(&pinfo);

		for (const PropertyInfo &E : pinfo) {
			if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
				continue;
			}

			if (default_oldnode->get(E.name) != n->get(E.name)) {
				newnode->set(E.name, n->get(E.name));
			}
		}

		memdelete(default_oldnode);
	}

	_push_item(nullptr);

	//reconnect signals
	List<MethodInfo> sl;
Repository: godotengine/godot
File: editor/plugins/path_3d_editor_plugin.cpp (C++)

Code before:
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */
/**************************************************************************/

#include "path_3d_editor_plugin.h"

#include "core/math/geometry_2d.h"
#include "core/math/geometry_3d.h"
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "node_3d_editor_plugin.h"
#include "scene/gui/menu_button.h"
#include "scene/resources/curve.h"

static bool _is_in_handle(int p_id, int p_num_points) {
	int t = (p_id + 1) % 2;
	int idx = (p_id + 1) / 2;
	// order of points is [out_0, out_1, in_1, out_2, in_2, ... out_n-1, in_n-1, in_n]
	if (idx == 0) {
		return false;
	} else if (idx == (p_num_points - 1)) {
		return true;
	} else {
		return (t == 1);
	}
}

String Path3DGizmo::get_handle_name(int p_id, bool p_secondary) const {
	Ref<Curve3D> c = path->get_curve();
	if (c.is_null()) {
		return "";
	}

	if (!p_secondary) {
		return TTR("Curve Point #") + itos(p_id);
	}

	// (p_id + 1) Accounts for the first point only having an "out" handle
	int idx = (p_id + 1) / 2;
	String n = TTR("Curve Point #") + itos(idx);
	if (_is_in_handle(p_id, c->get_point_count())) {
		n += " In";
	} else {
		n += " Out";
	}

	return n;
}


Review comment (suggestion):
```suggestion
	HandleType type; // Type of this handle.
```

Code after:
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */
/**************************************************************************/

#include "path_3d_editor_plugin.h"

#include "core/math/geometry_2d.h"
#include "core/math/geometry_3d.h"
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "node_3d_editor_plugin.h"
#include "scene/gui/menu_button.h"
#include "scene/resources/curve.h"

String Path3DGizmo::get_handle_name(int p_id, bool p_secondary) const {
	Ref<Curve3D> c = path->get_curve();
	if (c.is_null()) {
		return "";
	}

	// Primary handles: position.
	if (!p_secondary) {
		return TTR("Curve Point #") + itos(p_id);
	}

	// Secondary handles: in, out, tilt.
	const HandleInfo info = _secondary_handles_info[p_id];
	switch (info.type) {
		case HandleType::HANDLE_TYPE_IN:
			return TTR("Handle In #") + itos(info.point_idx);
		case HandleType::HANDLE_TYPE_OUT:
			return TTR("Handle Out #") + itos(info.point_idx);
		case HandleType::HANDLE_TYPE_TILT:
			return TTR("Handle Tilt #") + itos(info.point_idx);
	}

	return "";
}

Variant Path3DGizmo::get_handle_value(int p_id, bool p_secondary) const {
	Ref<Curve3D> c = path->get_curve();
	if (c.is_null()) {
		return Variant();
	}

	// Primary handles: position.
	if (!p_secondary) {
		original = c->get_point_position(p_id);
		return original;
Repository: godotengine/godot
File: editor/plugins/path_3d_editor_plugin.cpp (C++)

Code before:
	}
}

String Path3DGizmo::get_handle_name(int p_id, bool p_secondary) const {
	Ref<Curve3D> c = path->get_curve();
	if (c.is_null()) {
		return "";
	}

	if (!p_secondary) {
		return TTR("Curve Point #") + itos(p_id);
	}

	// (p_id + 1) Accounts for the first point only having an "out" handle
	int idx = (p_id + 1) / 2;
	String n = TTR("Curve Point #") + itos(idx);
	if (_is_in_handle(p_id, c->get_point_count())) {
		n += " In";
	} else {
		n += " Out";
	}

	return n;
}

Variant Path3DGizmo::get_handle_value(int p_id, bool p_secondary) const {
	Ref<Curve3D> c = path->get_curve();
	if (c.is_null()) {
		return Variant();
	}

	if (!p_secondary) {
		original = c->get_point_position(p_id);
		return original;
	}

	// (p_id + 1) Accounts for the first point only having an "out" handle
	int idx = (p_id + 1) / 2;

	Vector3 ofs;
	if (_is_in_handle(p_id, c->get_point_count())) {
		ofs = c->get_point_in(idx);
	} else {
		ofs = c->get_point_out(idx);
	}

	original = ofs + c->get_point_position(idx);

	return ofs;
}


Review comment (suggestion):
```suggestion
	// Secondary handles: in, out, tilt.
```

Code after:

	// Secondary handles: in, out, tilt.
	const HandleInfo info = _secondary_handles_info[p_id];
	switch (info.type) {
		case HandleType::HANDLE_TYPE_IN:
			return TTR("Handle In #") + itos(info.point_idx);
		case HandleType::HANDLE_TYPE_OUT:
			return TTR("Handle Out #") + itos(info.point_idx);
		case HandleType::HANDLE_TYPE_TILT:
			return TTR("Handle Tilt #") + itos(info.point_idx);
	}

	return "";
}

Variant Path3DGizmo::get_handle_value(int p_id, bool p_secondary) const {
	Ref<Curve3D> c = path->get_curve();
	if (c.is_null()) {
		return Variant();
	}

	// Primary handles: position.
	if (!p_secondary) {
		original = c->get_point_position(p_id);
		return original;
	}

	// Secondary handles: in, out, tilt.
	const HandleInfo info = _secondary_handles_info[p_id];
	Vector3 ofs;
	switch (info.type) {
		case HandleType::HANDLE_TYPE_TILT:
			return c->get_point_tilt(info.point_idx);
		case HandleType::HANDLE_TYPE_IN:
			ofs = c->get_point_in(info.point_idx);
			break;
		case HandleType::HANDLE_TYPE_OUT:
			ofs = c->get_point_out(info.point_idx);
			break;
	}

	original = ofs + c->get_point_position(info.point_idx);
	return ofs;
}

void Path3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
	Ref<Curve3D> c = path->get_curve();
	if (c.is_null()) {
		return;
	}
Repository: godotengine/godot
File: editor/plugins/path_3d_editor_plugin.cpp (C++)

Code before:

Variant Path3DGizmo::get_handle_value(int p_id, bool p_secondary) const {
	Ref<Curve3D> c = path->get_curve();
	if (c.is_null()) {
		return Variant();
	}

	if (!p_secondary) {
		original = c->get_point_position(p_id);
		return original;
	}

	// (p_id + 1) Accounts for the first point only having an "out" handle
	int idx = (p_id + 1) / 2;

	Vector3 ofs;
	if (_is_in_handle(p_id, c->get_point_count())) {
		ofs = c->get_point_in(idx);
	} else {
		ofs = c->get_point_out(idx);
	}

	original = ofs + c->get_point_position(idx);

	return ofs;
}

void Path3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
	Ref<Curve3D> c = path->get_curve();
	if (c.is_null()) {
		return;
	}

	Transform3D gt = path->get_global_transform();
	Transform3D gi = gt.affine_inverse();
	Vector3 ray_from = p_camera->project_ray_origin(p_point);
	Vector3 ray_dir = p_camera->project_ray_normal(p_point);

	// Setting curve point positions
	if (!p_secondary) {
		const Plane p = Plane(p_camera->get_transform().basis.get_column(2), gt.xform(original));

		Vector3 inters;

		if (p.intersects_ray(ray_from, ray_dir, &inters)) {
			if (Node3DEditor::get_singleton()->is_snap_enabled()) {
				float snap = Node3DEditor::get_singleton()->get_translate_snap();
				inters.snap(Vector3(snap, snap, snap));
			}

			Vector3 local = gi.xform(inters);

Review comment (suggestion):
```suggestion
	// Secondary handles: in, out, tilt.
```

Code after:
		return original;
	}

	// Secondary handles: in, out, tilt.
	const HandleInfo info = _secondary_handles_info[p_id];
	Vector3 ofs;
	switch (info.type) {
		case HandleType::HANDLE_TYPE_TILT:
			return c->get_point_tilt(info.point_idx);
		case HandleType::HANDLE_TYPE_IN:
			ofs = c->get_point_in(info.point_idx);
			break;
		case HandleType::HANDLE_TYPE_OUT:
			ofs = c->get_point_out(info.point_idx);
			break;
	}

	original = ofs + c->get_point_position(info.point_idx);
	return ofs;
}

void Path3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
	Ref<Curve3D> c = path->get_curve();
	if (c.is_null()) {
		return;
	}

	const Transform3D gt = path->get_global_transform();
	const Transform3D gi = gt.affine_inverse();
	const Vector3 ray_from = p_camera->project_ray_origin(p_point);
	const Vector3 ray_dir = p_camera->project_ray_normal(p_point);
	const Plane p = Plane(p_camera->get_transform().basis.get_column(2), gt.xform(original));

	// Primary handles: position.
	if (!p_secondary) {
		Vector3 inters;
		// Special cas for primary handle, the handle id equals control point id.
		const int idx = p_id;
		if (p.intersects_ray(ray_from, ray_dir, &inters)) {
			if (Node3DEditor::get_singleton()->is_snap_enabled()) {
				float snap = Node3DEditor::get_singleton()->get_translate_snap();
				inters.snap(Vector3(snap, snap, snap));
			}

			Vector3 local = gi.xform(inters);
			c->set_point_position(idx, local);
		}

		return;
	}