diff options
Diffstat (limited to 'scene/3d/camera_3d.cpp')
-rw-r--r-- | scene/3d/camera_3d.cpp | 157 |
1 files changed, 85 insertions, 72 deletions
diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index f0623c625e..3ada9072c2 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -31,10 +31,8 @@ #include "camera_3d.h" #include "collision_object_3d.h" -#include "core/config/engine.h" #include "core/math/camera_matrix.h" -#include "scene/resources/material.h" -#include "scene/resources/surface_tool.h" +#include "scene/main/viewport.h" void Camera3D::_update_audio_listener_state() { } @@ -85,32 +83,28 @@ void Camera3D::_update_camera() { // here goes listener stuff /* if (viewport_ptr && is_inside_scene() && is_current()) - get_viewport()->_camera_transform_changed_notify(); + get_viewport()->_camera_3d_transform_changed_notify(); */ if (get_tree()->is_node_being_edited(this) || !is_current()) { return; } - get_viewport()->_camera_transform_changed_notify(); - - if (get_world_3d().is_valid()) { - get_world_3d()->_update_camera(this); - } + get_viewport()->_camera_3d_transform_changed_notify(); } void Camera3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { - // Needs to track the Viewport because it's needed on NOTIFICATION_EXIT_WORLD + // Needs to track the Viewport because it's needed on NOTIFICATION_EXIT_WORLD // and Spatial will handle it first, including clearing its reference to the Viewport, // therefore making it impossible to subclasses to access it viewport = get_viewport(); ERR_FAIL_COND(!viewport); - bool first_camera = viewport->_camera_add(this); + bool first_camera = viewport->_camera_3d_add(this); if (current || first_camera) { - viewport->_camera_set(this); + viewport->_camera_3d_set(this); } } break; @@ -132,7 +126,7 @@ void Camera3D::_notification(int p_what) { } if (viewport) { - viewport->_camera_remove(this); + viewport->_camera_3d_remove(this); viewport = nullptr; } @@ -150,14 +144,14 @@ void Camera3D::_notification(int p_what) { } } -Transform Camera3D::get_camera_transform() const { - Transform tr = get_global_transform().orthonormalized(); +Transform3D Camera3D::get_camera_transform() const { + Transform3D tr = get_global_transform().orthonormalized(); tr.origin += tr.basis.get_axis(1) * v_offset; tr.origin += tr.basis.get_axis(0) * h_offset; return tr; } -void Camera3D::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far) { +void Camera3D::set_perspective(real_t p_fovy_degrees, real_t p_z_near, real_t p_z_far) { if (!force_change && fov == p_fovy_degrees && p_z_near == near && p_z_far == far && mode == PROJECTION_PERSPECTIVE) { return; } @@ -168,11 +162,11 @@ void Camera3D::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_f mode = PROJECTION_PERSPECTIVE; RenderingServer::get_singleton()->camera_set_perspective(camera, fov, near, far); - update_gizmo(); + update_gizmos(); force_change = false; } -void Camera3D::set_orthogonal(float p_size, float p_z_near, float p_z_far) { +void Camera3D::set_orthogonal(real_t p_size, real_t p_z_near, real_t p_z_far) { if (!force_change && size == p_size && p_z_near == near && p_z_far == far && mode == PROJECTION_ORTHOGONAL) { return; } @@ -185,10 +179,10 @@ void Camera3D::set_orthogonal(float p_size, float p_z_near, float p_z_far) { force_change = false; RenderingServer::get_singleton()->camera_set_orthogonal(camera, size, near, far); - update_gizmo(); + update_gizmos(); } -void Camera3D::set_frustum(float p_size, Vector2 p_offset, float p_z_near, float p_z_far) { +void Camera3D::set_frustum(real_t p_size, Vector2 p_offset, real_t p_z_near, real_t p_z_far) { if (!force_change && size == p_size && frustum_offset == p_offset && p_z_near == near && p_z_far == far && mode == PROJECTION_FRUSTUM) { return; } @@ -202,7 +196,7 @@ void Camera3D::set_frustum(float p_size, Vector2 p_offset, float p_z_near, float force_change = false; RenderingServer::get_singleton()->camera_set_frustum(camera, size, frustum_offset, near, far); - update_gizmo(); + update_gizmos(); } void Camera3D::set_projection(Camera3D::Projection p_mode) { @@ -224,7 +218,7 @@ void Camera3D::make_current() { return; } - get_viewport()->_camera_set(this); + get_viewport()->_camera_3d_set(this); //get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,camera_group,"_camera_make_current",this); } @@ -235,11 +229,11 @@ void Camera3D::clear_current(bool p_enable_next) { return; } - if (get_viewport()->get_camera() == this) { - get_viewport()->_camera_set(nullptr); + if (get_viewport()->get_camera_3d() == this) { + get_viewport()->_camera_3d_set(nullptr); if (p_enable_next) { - get_viewport()->_camera_make_next_current(this); + get_viewport()->_camera_3d_make_next_current(this); } } } @@ -254,7 +248,7 @@ void Camera3D::set_current(bool p_current) { bool Camera3D::is_current() const { if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) { - return get_viewport()->get_camera() == this; + return get_viewport()->get_camera_3d() == this; } else { return current; } @@ -299,7 +293,7 @@ Vector3 Camera3D::project_ray_origin(const Point2 &p_pos) const { return get_camera_transform().origin; } else { Vector2 pos = cpos / viewport_size; - float vsize, hsize; + real_t vsize, hsize; if (keep_aspect == KEEP_WIDTH) { vsize = size / viewport_size.aspect(); hsize = size; @@ -318,7 +312,7 @@ Vector3 Camera3D::project_ray_origin(const Point2 &p_pos) const { }; bool Camera3D::is_position_behind(const Vector3 &p_pos) const { - Transform t = get_global_transform(); + Transform3D t = get_global_transform(); Vector3 eyedir = -t.basis.get_axis(2).normalized(); return eyedir.dot(p_pos - t.origin) < near; } @@ -337,7 +331,7 @@ Vector<Vector3> Camera3D::get_near_plane_points() const { } Vector3 endpoints[8]; - cm.get_endpoints(Transform(), endpoints); + cm.get_endpoints(Transform3D(), endpoints); Vector<Vector3> points; points.push_back(Vector3()); @@ -372,7 +366,7 @@ Point2 Camera3D::unproject_position(const Vector3 &p_pos) const { return res; } -Vector3 Camera3D::project_position(const Point2 &p_point, float p_z_depth) const { +Vector3 Camera3D::project_position(const Point2 &p_point, real_t p_z_depth) const { ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene."); if (p_z_depth == 0 && mode != PROJECTION_ORTHOGONAL) { @@ -500,10 +494,11 @@ void Camera3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera3D::set_doppler_tracking); ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &Camera3D::get_doppler_tracking); ClassDB::bind_method(D_METHOD("get_frustum"), &Camera3D::get_frustum); + ClassDB::bind_method(D_METHOD("is_position_in_frustum", "world_point"), &Camera3D::is_position_in_frustum); ClassDB::bind_method(D_METHOD("get_camera_rid"), &Camera3D::get_camera); - ClassDB::bind_method(D_METHOD("set_cull_mask_bit", "layer", "enable"), &Camera3D::set_cull_mask_bit); - ClassDB::bind_method(D_METHOD("get_cull_mask_bit", "layer"), &Camera3D::get_cull_mask_bit); + ClassDB::bind_method(D_METHOD("set_cull_mask_value", "layer_number", "value"), &Camera3D::set_cull_mask_value); + ClassDB::bind_method(D_METHOD("get_cull_mask_value", "layer_number"), &Camera3D::get_cull_mask_value); //ClassDB::bind_method(D_METHOD("_camera_make_current"),&Camera::_camera_make_current ); @@ -516,11 +511,11 @@ void Camera3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking"); ADD_PROPERTY(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal,Frustum"), "set_projection", "get_projection"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov", PROPERTY_HINT_RANGE, "1,179,0.1"), "set_fov", "get_fov"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov", PROPERTY_HINT_RANGE, "1,179,0.1,degrees"), "set_fov", "get_fov"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.1,16384,0.01"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frustum_offset"), "set_frustum_offset", "get_frustum_offset"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "near", PROPERTY_HINT_EXP_RANGE, "0.001,10,0.001,or_greater"), "set_near", "get_near"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_EXP_RANGE, "0.01,4000,0.01,or_greater"), "set_far", "get_far"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "near", PROPERTY_HINT_RANGE, "0.001,10,0.001,or_greater,exp"), "set_near", "get_near"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_RANGE, "0.01,4000,0.01,or_greater,exp"), "set_far", "get_far"); BIND_ENUM_CONSTANT(PROJECTION_PERSPECTIVE); BIND_ENUM_CONSTANT(PROJECTION_ORTHOGONAL); @@ -534,15 +529,15 @@ void Camera3D::_bind_methods() { BIND_ENUM_CONSTANT(DOPPLER_TRACKING_PHYSICS_STEP); } -float Camera3D::get_fov() const { +real_t Camera3D::get_fov() const { return fov; } -float Camera3D::get_size() const { +real_t Camera3D::get_size() const { return size; } -float Camera3D::get_near() const { +real_t Camera3D::get_near() const { return near; } @@ -550,7 +545,7 @@ Vector2 Camera3D::get_frustum_offset() const { return frustum_offset; } -float Camera3D::get_far() const { +real_t Camera3D::get_far() const { return far; } @@ -558,19 +553,19 @@ Camera3D::Projection Camera3D::get_projection() const { return mode; } -void Camera3D::set_fov(float p_fov) { +void Camera3D::set_fov(real_t p_fov) { ERR_FAIL_COND(p_fov < 1 || p_fov > 179); fov = p_fov; _update_camera_mode(); } -void Camera3D::set_size(float p_size) { +void Camera3D::set_size(real_t p_size) { ERR_FAIL_COND(p_size < 0.1 || p_size > 16384); size = p_size; _update_camera_mode(); } -void Camera3D::set_near(float p_near) { +void Camera3D::set_near(real_t p_near) { near = p_near; _update_camera_mode(); } @@ -580,7 +575,7 @@ void Camera3D::set_frustum_offset(Vector2 p_offset) { _update_camera_mode(); } -void Camera3D::set_far(float p_far) { +void Camera3D::set_far(real_t p_far) { far = p_far; _update_camera_mode(); } @@ -595,18 +590,22 @@ uint32_t Camera3D::get_cull_mask() const { return layers; } -void Camera3D::set_cull_mask_bit(int p_layer, bool p_enable) { - ERR_FAIL_INDEX(p_layer, 32); - if (p_enable) { - set_cull_mask(layers | (1 << p_layer)); +void Camera3D::set_cull_mask_value(int p_layer_number, bool p_value) { + ERR_FAIL_COND_MSG(p_layer_number < 1, "Render layer number must be between 1 and 20 inclusive."); + ERR_FAIL_COND_MSG(p_layer_number > 20, "Render layer number must be between 1 and 20 inclusive."); + uint32_t mask = get_cull_mask(); + if (p_value) { + mask |= 1 << (p_layer_number - 1); } else { - set_cull_mask(layers & (~(1 << p_layer))); + mask &= ~(1 << (p_layer_number - 1)); } + set_cull_mask(mask); } -bool Camera3D::get_cull_mask_bit(int p_layer) const { - ERR_FAIL_INDEX_V(p_layer, 32, false); - return (layers & (1 << p_layer)); +bool Camera3D::get_cull_mask_value(int p_layer_number) const { + ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Render layer number must be between 1 and 20 inclusive."); + ERR_FAIL_COND_V_MSG(p_layer_number > 20, false, "Render layer number must be between 1 and 20 inclusive."); + return layers & (1 << (p_layer_number - 1)); } Vector<Plane> Camera3D::get_frustum() const { @@ -623,21 +622,31 @@ Vector<Plane> Camera3D::get_frustum() const { return cm.get_projection_planes(get_camera_transform()); } -void Camera3D::set_v_offset(float p_offset) { +bool Camera3D::is_position_in_frustum(const Vector3 &p_position) const { + Vector<Plane> frustum = get_frustum(); + for (int i = 0; i < frustum.size(); i++) { + if (frustum[i].is_point_over(p_position)) { + return false; + } + } + return true; +} + +void Camera3D::set_v_offset(real_t p_offset) { v_offset = p_offset; _update_camera(); } -float Camera3D::get_v_offset() const { +real_t Camera3D::get_v_offset() const { return v_offset; } -void Camera3D::set_h_offset(float p_offset) { +void Camera3D::set_h_offset(real_t p_offset) { h_offset = p_offset; _update_camera(); } -float Camera3D::get_h_offset() const { +real_t Camera3D::get_h_offset() const { return h_offset; } @@ -654,7 +663,7 @@ Camera3D::Camera3D() { set_perspective(75.0, 0.05, 4000.0); RenderingServer::get_singleton()->camera_set_cull_mask(camera, layers); //active=false; - velocity_tracker.instance(); + velocity_tracker.instantiate(); set_notify_transform(true); set_disable_scale(true); } @@ -665,11 +674,11 @@ Camera3D::~Camera3D() { //////////////////////////////////////// -void ClippedCamera3D::set_margin(float p_margin) { +void ClippedCamera3D::set_margin(real_t p_margin) { margin = p_margin; } -float ClippedCamera3D::get_margin() const { +real_t ClippedCamera3D::get_margin() const { return margin; } @@ -686,8 +695,8 @@ ClippedCamera3D::ClipProcessCallback ClippedCamera3D::get_process_callback() con return process_callback; } -Transform ClippedCamera3D::get_camera_transform() const { - Transform t = Camera3D::get_camera_transform(); +Transform3D ClippedCamera3D::get_camera_transform() const { + Transform3D t = Camera3D::get_camera_transform(); t.origin += -t.basis.get_axis(Vector3::AXIS_Z).normalized() * clip_offset; return t; } @@ -715,7 +724,7 @@ void ClippedCamera3D::_notification(int p_what) { Vector3 ray_from = parent_plane.project(cam_pos); - clip_offset = 0; //reset by defau;t + clip_offset = 0; //reset by default { //check if points changed Vector<Vector3> local_points = get_near_plane_points(); @@ -735,11 +744,11 @@ void ClippedCamera3D::_notification(int p_what) { } } - Transform xf = get_global_transform(); + Transform3D xf = get_global_transform(); xf.origin = ray_from; xf.orthonormalize(); - float closest_safe = 1.0f, closest_unsafe = 1.0f; + real_t closest_safe = 1.0f, closest_unsafe = 1.0f; if (dspace->cast_motion(pyramid_shape, xf, cam_pos - ray_from, margin, closest_safe, closest_unsafe, exclude, collision_mask, clip_to_bodies, clip_to_areas)) { clip_offset = cam_pos.distance_to(ray_from + (cam_pos - ray_from) * closest_safe); } @@ -748,7 +757,7 @@ void ClippedCamera3D::_notification(int p_what) { } if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) { - update_gizmo(); + update_gizmos(); } } @@ -760,18 +769,22 @@ uint32_t ClippedCamera3D::get_collision_mask() const { return collision_mask; } -void ClippedCamera3D::set_collision_mask_bit(int p_bit, bool p_value) { +void ClippedCamera3D::set_collision_mask_value(int p_layer_number, bool p_value) { + ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive."); uint32_t mask = get_collision_mask(); if (p_value) { - mask |= 1 << p_bit; + mask |= 1 << (p_layer_number - 1); } else { - mask &= ~(1 << p_bit); + mask &= ~(1 << (p_layer_number - 1)); } set_collision_mask(mask); } -bool ClippedCamera3D::get_collision_mask_bit(int p_bit) const { - return get_collision_mask() & (1 << p_bit); +bool ClippedCamera3D::get_collision_mask_value(int p_layer_number) const { + ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive."); + return get_collision_mask() & (1 << (p_layer_number - 1)); } void ClippedCamera3D::add_exception_rid(const RID &p_rid) { @@ -804,7 +817,7 @@ void ClippedCamera3D::clear_exceptions() { exclude.clear(); } -float ClippedCamera3D::get_clip_offset() const { +real_t ClippedCamera3D::get_clip_offset() const { return clip_offset; } @@ -834,8 +847,8 @@ void ClippedCamera3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &ClippedCamera3D::set_collision_mask); ClassDB::bind_method(D_METHOD("get_collision_mask"), &ClippedCamera3D::get_collision_mask); - ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &ClippedCamera3D::set_collision_mask_bit); - ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &ClippedCamera3D::get_collision_mask_bit); + ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &ClippedCamera3D::set_collision_mask_value); + ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &ClippedCamera3D::get_collision_mask_value); ClassDB::bind_method(D_METHOD("add_exception_rid", "rid"), &ClippedCamera3D::add_exception_rid); ClassDB::bind_method(D_METHOD("add_exception", "node"), &ClippedCamera3D::add_exception); |