Kaynağa Gözat

Merge pull request #11187 from SaracenOne/subscene_box_selection

Box selection for MeshInstances and subscene nodes.
Rémi Verschelde 8 yıl önce
ebeveyn
işleme
5c76e638ab

+ 10 - 5
editor/plugins/spatial_editor_plugin.cpp

@@ -465,7 +465,6 @@ void SpatialEditorViewport::_select_region() {
 	Vector<Plane> frustum;
 
 	Vector3 cam_pos = _get_camera_position();
-	Set<Ref<SpatialEditorGizmo> > found_gizmos;
 
 	for (int i = 0; i < 4; i++) {
 
@@ -485,6 +484,9 @@ void SpatialEditorViewport::_select_region() {
 	frustum.push_back(far);
 
 	Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world()->get_scenario());
+	Vector<Spatial *> selected;
+
+	Node *edited_scene = get_tree()->get_edited_scene_root();
 
 	for (int i = 0; i < instances.size(); i++) {
 
@@ -497,11 +499,14 @@ void SpatialEditorViewport::_select_region() {
 		if (!seg.is_valid())
 			continue;
 
-		if (found_gizmos.has(seg))
-			continue;
+		Spatial *root_sp = sp;
+		while (root_sp && root_sp != edited_scene && root_sp->get_owner() != edited_scene && !edited_scene->is_editable_instance(root_sp->get_owner())) {
+			root_sp = Object::cast_to<Spatial>(root_sp->get_owner());
+		}
 
-		if (seg->intersect_frustum(camera, frustum))
-			_select(sp, true, false);
+		if (selected.find(root_sp) == -1)
+			if (seg->intersect_frustum(camera, frustum))
+				_select(root_sp, true, false);
 	}
 }
 

+ 30 - 4
editor/spatial_editor_gizmos.cpp

@@ -211,9 +211,10 @@ void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material> &p_material,
 	instances.push_back(ins);
 }
 
-void EditorSpatialGizmo::add_collision_triangles(const Ref<TriangleMesh> &p_tmesh) {
+void EditorSpatialGizmo::add_collision_triangles(const Ref<TriangleMesh> &p_tmesh, const Rect3 &p_bounds) {
 
 	collision_mesh = p_tmesh;
+	collision_mesh_bounds = p_bounds;
 }
 
 void EditorSpatialGizmo::add_collision_segments(const Vector<Vector3> &p_lines) {
@@ -359,6 +360,29 @@ bool EditorSpatialGizmo::intersect_frustum(const Camera *p_camera, const Vector<
 		return false;
 	}
 
+	if (collision_mesh_bounds.size != Vector3(0.0, 0.0, 0.0)) {
+		Transform t = spatial_node->get_global_transform();
+		const Plane *p = p_frustum.ptr();
+		int fc = p_frustum.size();
+
+		Vector3 mins = t.xform(collision_mesh_bounds.get_position());
+		Vector3 max = t.xform(collision_mesh_bounds.get_position() + collision_mesh_bounds.get_size());
+
+		bool any_out = false;
+
+		for (int j = 0; j < fc; j++) {
+
+			if (p[j].distance_to(mins) > 0 || p[j].distance_to(max) > 0) {
+
+				any_out = true;
+				break;
+			}
+		}
+
+		if (!any_out)
+			return true;
+	}
+
 	return false;
 }
 
@@ -637,7 +661,7 @@ void EditorSpatialGizmo::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("add_lines", "lines", "material", "billboard"), &EditorSpatialGizmo::add_lines, DEFVAL(false));
 	ClassDB::bind_method(D_METHOD("add_mesh", "mesh", "billboard", "skeleton"), &EditorSpatialGizmo::add_mesh, DEFVAL(false), DEFVAL(RID()));
 	ClassDB::bind_method(D_METHOD("add_collision_segments", "segments"), &EditorSpatialGizmo::add_collision_segments);
-	ClassDB::bind_method(D_METHOD("add_collision_triangles", "triangles"), &EditorSpatialGizmo::add_collision_triangles);
+	ClassDB::bind_method(D_METHOD("add_collision_triangles", "triangles", "bounds"), &EditorSpatialGizmo::add_collision_triangles);
 	ClassDB::bind_method(D_METHOD("add_unscaled_billboard", "material", "default_scale"), &EditorSpatialGizmo::add_unscaled_billboard, DEFVAL(1));
 	ClassDB::bind_method(D_METHOD("add_handles", "handles", "billboard", "secondary"), &EditorSpatialGizmo::add_handles, DEFVAL(false), DEFVAL(false));
 	ClassDB::bind_method(D_METHOD("set_spatial_node", "node"), &EditorSpatialGizmo::_set_spatial_node);
@@ -1249,8 +1273,10 @@ void MeshInstanceSpatialGizmo::redraw() {
 		return; //none
 
 	Ref<TriangleMesh> tm = m->generate_triangle_mesh();
-	if (tm.is_valid())
-		add_collision_triangles(tm);
+	if (tm.is_valid()) {
+		Rect3 aabb;
+		add_collision_triangles(tm, aabb);
+	}
 }
 
 MeshInstanceSpatialGizmo::MeshInstanceSpatialGizmo(MeshInstance *p_mesh) {

+ 2 - 1
editor/spatial_editor_gizmos.h

@@ -78,6 +78,7 @@ class EditorSpatialGizmo : public SpatialEditorGizmo {
 
 	Vector<Vector3> collision_segments;
 	Ref<TriangleMesh> collision_mesh;
+	Rect3 collision_mesh_bounds;
 
 	struct Handle {
 		Vector3 pos;
@@ -99,7 +100,7 @@ protected:
 	void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false);
 	void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID());
 	void add_collision_segments(const Vector<Vector3> &p_lines);
-	void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh);
+	void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh, const Rect3 &p_bounds = Rect3());
 	void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1);
 	void add_handles(const Vector<Vector3> &p_handles, bool p_billboard = false, bool p_secondary = false);
 	void add_solid_box(Ref<Material> &p_material, Vector3 size);