Merge pull request #11187 from SaracenOne/subscene_box_selection

Box selection for MeshInstances and subscene nodes.
This commit is contained in:
Rémi Verschelde 2017-09-21 10:24:40 +02:00 committed by GitHub
commit 5c76e638ab
3 changed files with 42 additions and 10 deletions

View File

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

View File

@ -211,9 +211,10 @@ void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material> &p_material,
instances.push_back(ins); 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 = p_tmesh;
collision_mesh_bounds = p_bounds;
} }
void EditorSpatialGizmo::add_collision_segments(const Vector<Vector3> &p_lines) { 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; 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; 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_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_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_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_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("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); ClassDB::bind_method(D_METHOD("set_spatial_node", "node"), &EditorSpatialGizmo::_set_spatial_node);
@ -1249,8 +1273,10 @@ void MeshInstanceSpatialGizmo::redraw() {
return; //none return; //none
Ref<TriangleMesh> tm = m->generate_triangle_mesh(); Ref<TriangleMesh> tm = m->generate_triangle_mesh();
if (tm.is_valid()) if (tm.is_valid()) {
add_collision_triangles(tm); Rect3 aabb;
add_collision_triangles(tm, aabb);
}
} }
MeshInstanceSpatialGizmo::MeshInstanceSpatialGizmo(MeshInstance *p_mesh) { MeshInstanceSpatialGizmo::MeshInstanceSpatialGizmo(MeshInstance *p_mesh) {

View File

@ -78,6 +78,7 @@ class EditorSpatialGizmo : public SpatialEditorGizmo {
Vector<Vector3> collision_segments; Vector<Vector3> collision_segments;
Ref<TriangleMesh> collision_mesh; Ref<TriangleMesh> collision_mesh;
Rect3 collision_mesh_bounds;
struct Handle { struct Handle {
Vector3 pos; 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_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_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_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_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_handles(const Vector<Vector3> &p_handles, bool p_billboard = false, bool p_secondary = false);
void add_solid_box(Ref<Material> &p_material, Vector3 size); void add_solid_box(Ref<Material> &p_material, Vector3 size);