diff options
Diffstat (limited to 'servers')
-rw-r--r-- | servers/audio_server.cpp | 97 | ||||
-rw-r--r-- | servers/audio_server.h | 31 | ||||
-rw-r--r-- | servers/physics_2d/collision_solver_2d_sw.cpp | 11 | ||||
-rw-r--r-- | servers/physics_2d/collision_solver_2d_sw.h | 2 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_sw.cpp | 24 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_sw.h | 3 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_wrap_mt.h | 10 | ||||
-rw-r--r-- | servers/physics_2d/space_2d_sw.cpp | 163 | ||||
-rw-r--r-- | servers/physics_2d/space_2d_sw.h | 3 | ||||
-rw-r--r-- | servers/physics_2d_server.h | 17 | ||||
-rw-r--r-- | servers/visual/rasterizer.h | 1 | ||||
-rw-r--r-- | servers/visual/shader_language.cpp | 8 | ||||
-rw-r--r-- | servers/visual/visual_server_raster.cpp | 5 | ||||
-rw-r--r-- | servers/visual/visual_server_raster.h | 2 | ||||
-rw-r--r-- | servers/visual/visual_server_wrap_mt.h | 2 | ||||
-rw-r--r-- | servers/visual_server.h | 1 |
16 files changed, 360 insertions, 20 deletions
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index f2df7119e7..ef794ac380 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -117,6 +117,10 @@ AudioDriver::AudioDriver() { _last_mix_time = 0; _mix_amount = 0; + +#ifdef DEBUG_ENABLED + prof_time = 0; +#endif } AudioDriver *AudioDriverManager::drivers[MAX_DRIVERS]; @@ -184,6 +188,10 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { int todo = p_frames; +#ifdef DEBUG_ENABLED + uint64_t prof_ticks = OS::get_singleton()->get_ticks_usec(); +#endif + if (channel_count != get_channel_count()) { // Amount of channels changed due to a device change // reinitialize the buses channels and buffers @@ -234,6 +242,17 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { todo -= to_copy; to_mix -= to_copy; } + + // Calculate latency for Performance.AUDIO_OUTPUT_LATENCY + if (OS::get_singleton()) { + uint64_t ticks = OS::get_singleton()->get_ticks_usec(); + output_latency = (ticks - output_latency_ticks) / 1000000.f; + output_latency_ticks = ticks; + } + +#ifdef DEBUG_ENABLED + prof_time += OS::get_singleton()->get_ticks_usec() - prof_ticks; +#endif } void AudioServer::_mix_step() { @@ -307,6 +326,10 @@ void AudioServer::_mix_step() { if (!bus->effects[j].enabled) continue; +#ifdef DEBUG_ENABLED + uint64_t ticks = OS::get_singleton()->get_ticks_usec(); +#endif + for (int k = 0; k < bus->channels.size(); k++) { if (!bus->channels[k].active) @@ -321,6 +344,10 @@ void AudioServer::_mix_step() { continue; SWAP(bus->channels[k].buffer, temp_buffer[k]); } + +#ifdef DEBUG_ENABLED + bus->effects[j].prof_time += OS::get_singleton()->get_ticks_usec() - ticks; +#endif } } @@ -761,6 +788,9 @@ void AudioServer::add_bus_effect(int p_bus, const Ref<AudioEffect> &p_effect, in fx.effect = p_effect; //fx.instance=p_effect->instance(); fx.enabled = true; +#ifdef DEBUG_ENABLED + fx.prof_time = 0; +#endif if (p_at_pos >= buses[p_bus]->effects.size() || p_at_pos < 0) { buses[p_bus]->effects.push_back(fx); @@ -893,6 +923,68 @@ void AudioServer::init() { GLOBAL_DEF("audio/video_delay_compensation_ms", 0); } +void AudioServer::update() { +#ifdef DEBUG_ENABLED + if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_profiling()) { + + // Driver time includes server time + effects times + // Server time includes effects times + uint64_t driver_time = AudioDriver::get_singleton()->get_profiling_time(); + uint64_t server_time = prof_time; + + // Substract the server time from the driver time + if (driver_time > server_time) + driver_time -= server_time; + + Array values; + + for (int i = buses.size() - 1; i >= 0; i--) { + Bus *bus = buses[i]; + if (bus->bypass) + continue; + + for (int j = 0; j < bus->effects.size(); j++) { + if (!bus->effects[j].enabled) + continue; + + values.push_back(String(bus->name) + bus->effects[j].effect->get_name()); + values.push_back(USEC_TO_SEC(bus->effects[j].prof_time)); + + // Substract the effect time from the driver and server times + if (driver_time > bus->effects[j].prof_time) + driver_time -= bus->effects[j].prof_time; + if (server_time > bus->effects[j].prof_time) + server_time -= bus->effects[j].prof_time; + } + } + + values.push_back("audio_server"); + values.push_back(USEC_TO_SEC(server_time)); + values.push_back("audio_driver"); + values.push_back(USEC_TO_SEC(driver_time)); + + ScriptDebugger::get_singleton()->add_profiling_frame_data("audio_thread", values); + } + + // Reset profiling times + for (int i = buses.size() - 1; i >= 0; i--) { + Bus *bus = buses[i]; + if (bus->bypass) + continue; + + for (int j = 0; j < bus->effects.size(); j++) { + if (!bus->effects[j].enabled) + continue; + + bus->effects[j].prof_time = 0; + } + } + + AudioDriver::get_singleton()->reset_profiling_time(); + prof_time = 0; +#endif +} + void AudioServer::load_default_bus_layout() { if (FileAccess::exists("res://default_bus_layout.tres")) { @@ -1178,6 +1270,11 @@ AudioServer::AudioServer() { mix_frames = 0; channel_count = 0; to_mix = 0; + output_latency = 0; + output_latency_ticks = 0; +#ifdef DEBUG_ENABLED + prof_time = 0; +#endif } AudioServer::~AudioServer() { diff --git a/servers/audio_server.h b/servers/audio_server.h index b7fcd9c093..258fd1d9b0 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -33,6 +33,7 @@ #include "audio_frame.h" #include "object.h" +#include "os/os.h" #include "servers/audio/audio_effect.h" #include "variant.h" @@ -44,10 +45,23 @@ class AudioDriver { uint64_t _last_mix_time; uint64_t _mix_amount; +#ifdef DEBUG_ENABLED + uint64_t prof_ticks; + uint64_t prof_time; +#endif + protected: void audio_server_process(int p_frames, int32_t *p_buffer, bool p_update_mix_time = true); void update_mix_time(int p_frames); +#ifdef DEBUG_ENABLED + _FORCE_INLINE_ void start_counting_ticks() { prof_ticks = OS::get_singleton()->get_ticks_usec(); } + _FORCE_INLINE_ void stop_counting_ticks() { prof_time += OS::get_singleton()->get_ticks_usec() - prof_ticks; } +#else + _FORCE_INLINE_ void start_counting_ticks() {} + _FORCE_INLINE_ void stop_counting_ticks() {} +#endif + public: double get_mix_time() const; //useful for video -> audio sync @@ -82,6 +96,11 @@ public: SpeakerMode get_speaker_mode_by_total_channels(int p_channels) const; int get_total_channels_by_speaker_mode(SpeakerMode) const; +#ifdef DEBUG_ENABLED + uint64_t get_profiling_time() const { return prof_time; } + void reset_profiling_time() { prof_time = 0; } +#endif + AudioDriver(); virtual ~AudioDriver() {} }; @@ -129,6 +148,9 @@ private: uint32_t buffer_size; uint64_t mix_count; uint64_t mix_frames; +#ifdef DEBUG_ENABLED + uint64_t prof_time; +#endif float channel_disable_threshold_db; uint32_t channel_disable_frames; @@ -166,6 +188,9 @@ private: struct Effect { Ref<AudioEffect> effect; bool enabled; +#ifdef DEBUG_ENABLED + uint64_t prof_time; +#endif }; Vector<Effect> effects; @@ -190,6 +215,9 @@ private: Mutex *audio_data_lock; + float output_latency; + uint64_t output_latency_ticks; + void init_channels_and_buffers(); void _mix_step(); @@ -273,6 +301,7 @@ public: virtual void init(); virtual void finish(); + virtual void update(); virtual void load_default_bus_layout(); /* MISC config */ @@ -306,6 +335,8 @@ public: String get_device(); void set_device(String device); + float get_output_latency() { return output_latency; } + AudioServer(); virtual ~AudioServer(); }; diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp index efee98a35a..6ce019f36e 100644 --- a/servers/physics_2d/collision_solver_2d_sw.cpp +++ b/servers/physics_2d/collision_solver_2d_sw.cpp @@ -72,7 +72,7 @@ bool CollisionSolver2DSW::solve_static_line(const Shape2DSW *p_shape_A, const Tr return found; } -bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis) { +bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis) { const RayShape2DSW *ray = static_cast<const RayShape2DSW *>(p_shape_A); if (p_shape_B->get_type() == Physics2DServer::SHAPE_RAY) @@ -80,6 +80,11 @@ bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Transf Vector2 from = p_transform_A.get_origin(); Vector2 to = from + p_transform_A[1] * ray->get_length(); + if (p_motion_A != Vector2()) { + //not the best but should be enough + Vector2 normal = (to - from).normalized(); + to += normal * MAX(0.0, normal.dot(p_motion_A)); + } Vector2 support_A = to; Transform2D invb = p_transform_B.affine_inverse(); @@ -270,9 +275,9 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p } if (swap) { - return solve_raycast(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true, sep_axis); + return solve_raycast(p_shape_B, p_motion_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true, sep_axis); } else { - return solve_raycast(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, sep_axis); + return solve_raycast(p_shape_A, p_motion_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, sep_axis); } } else if (concave_B) { diff --git a/servers/physics_2d/collision_solver_2d_sw.h b/servers/physics_2d/collision_solver_2d_sw.h index e39c41fb75..6faa166115 100644 --- a/servers/physics_2d/collision_solver_2d_sw.h +++ b/servers/physics_2d/collision_solver_2d_sw.h @@ -41,7 +41,7 @@ private: static bool solve_static_line(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); static void concave_callback(void *p_userdata, Shape2DSW *p_convex); static bool solve_concave(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis = NULL, real_t p_margin_A = 0, real_t p_margin_B = 0); - static bool solve_raycast(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis = NULL); + static bool solve_raycast(const Shape2DSW *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis = NULL); public: static bool solve(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, Vector2 *sep_axis = NULL, real_t p_margin_A = 0, real_t p_margin_B = 0); diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index a14fed8184..a473e0beb2 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -962,22 +962,40 @@ void Physics2DServerSW::body_set_pickable(RID p_body, bool p_pickable) { body->set_pickable(p_pickable); } -bool Physics2DServerSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, MotionResult *r_result) { +bool Physics2DServerSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, MotionResult *r_result, bool p_exclude_raycast_shapes) { Body2DSW *body = body_owner.get(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); ERR_FAIL_COND_V(body->get_space()->is_locked(), false); - return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result); + return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes); +} + +int Physics2DServerSW::body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) { + + Body2DSW *body = body_owner.get(p_body); + ERR_FAIL_COND_V(!body, false); + ERR_FAIL_COND_V(!body->get_space(), false); + ERR_FAIL_COND_V(body->get_space()->is_locked(), false); + + return body->get_space()->test_body_ray_separation(body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin); } Physics2DDirectBodyState *Physics2DServerSW::body_get_direct_state(RID p_body) { + if ((using_threads && !doing_sync)) { + ERR_EXPLAIN("Body state is inaccessible right now, wait for iteration or physics process notification."); + ERR_FAIL_V(NULL); + } + + if (!body_owner.owns(p_body)) + return NULL; + Body2DSW *body = body_owner.get(p_body); ERR_FAIL_COND_V(!body, NULL); - if ((using_threads && !doing_sync) || body->get_space()->is_locked()) { + if (body->get_space()->is_locked()) { ERR_EXPLAIN("Body state is inaccessible right now, wait for iteration or physics process notification."); ERR_FAIL_V(NULL); diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index 036eb934e1..e5961b9011 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -232,7 +232,8 @@ public: virtual void body_set_pickable(RID p_body, bool p_pickable); - virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = NULL); + virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true); + virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001); // this function only works on physics process, errors and returns null otherwise virtual Physics2DDirectBodyState *body_get_direct_state(RID p_body); diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h index a15e8bde8b..3119b930d7 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.h +++ b/servers/physics_2d/physics_2d_server_wrap_mt.h @@ -245,10 +245,16 @@ public: FUNC2(body_set_pickable, RID, bool); - bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = NULL) { + bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true) { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); - return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result); + return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes); + } + + int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) { + + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); + return physics_2d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin); } // this function only works on physics process, errors and returns null otherwise diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 0e1f74d8d0..6e45951f42 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -487,7 +487,156 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) { return amount; } -bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, Physics2DServer::MotionResult *r_result) { +int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, Physics2DServer::SeparationResult *r_results, int p_result_max, real_t p_margin) { + + Rect2 body_aabb; + + for (int i = 0; i < p_body->get_shape_count(); i++) { + + if (i == 0) + body_aabb = p_body->get_shape_aabb(i); + else + body_aabb = body_aabb.merge(p_body->get_shape_aabb(i)); + } + + // Undo the currently transform the physics server is aware of and apply the provided one + body_aabb = p_transform.xform(p_body->get_inv_transform().xform(body_aabb)); + body_aabb = body_aabb.grow(p_margin); + + Transform2D body_transform = p_transform; + + for (int i = 0; i < p_result_max; i++) { + //reset results + r_results[i].collision_depth = 0; + } + + int rays_found = 0; + + { + // raycast AND separate + + const int max_results = 32; + int recover_attempts = 4; + Vector2 sr[max_results * 2]; + Physics2DServerSW::CollCbkData cbk; + cbk.max = max_results; + Physics2DServerSW::CollCbkData *cbkptr = &cbk; + CollisionSolver2DSW::CallbackResult cbkres = Physics2DServerSW::_shape_col_cbk; + + do { + + Vector2 recover_motion; + + bool collided = false; + + int amount = _cull_aabb_for_body(p_body, body_aabb); + int ray_index = 0; + + for (int j = 0; j < p_body->get_shape_count(); j++) { + if (p_body->is_shape_set_as_disabled(j)) + continue; + + Shape2DSW *body_shape = p_body->get_shape(j); + + if (body_shape->get_type() != Physics2DServer::SHAPE_RAY) + continue; + + Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j); + + for (int i = 0; i < amount; i++) { + + const CollisionObject2DSW *col_obj = intersection_query_results[i]; + int shape_idx = intersection_query_subindex_results[i]; + + cbk.amount = 0; + cbk.ptr = sr; + cbk.invalid_by_dir = 0; + + if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) { + const Body2DSW *b = static_cast<const Body2DSW *>(col_obj); + if (p_infinite_inertia && Physics2DServer::BODY_MODE_STATIC != b->get_mode() && Physics2DServer::BODY_MODE_KINEMATIC != b->get_mode()) { + continue; + } + } + + if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) { + + cbk.valid_dir = body_shape_xform.get_axis(1).normalized(); + cbk.valid_depth = p_margin; //only valid depth is the collision margin + cbk.invalid_by_dir = 0; + + } else { + cbk.valid_dir = Vector2(); + cbk.valid_depth = 0; + cbk.invalid_by_dir = 0; + } + + Shape2DSW *against_shape = col_obj->get_shape(shape_idx); + if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) { + if (cbk.amount > 0) { + collided = true; + } + + if (ray_index < p_result_max) { + Physics2DServer::SeparationResult &result = r_results[ray_index]; + + for (int k = 0; k < cbk.amount; k++) { + Vector2 a = sr[k * 2 + 0]; + Vector2 b = sr[k * 2 + 1]; + + recover_motion += (b - a) * 0.4; + + float depth = a.distance_to(b); + if (depth > result.collision_depth) { + + result.collision_depth = depth; + result.collision_point = b; + result.collision_normal = (b - a).normalized(); + result.collision_local_shape = shape_idx; + result.collider = col_obj->get_self(); + result.collider_id = col_obj->get_instance_id(); + result.collider_metadata = col_obj->get_shape_metadata(shape_idx); + if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) { + Body2DSW *body = (Body2DSW *)col_obj; + + Vector2 rel_vec = b - body->get_transform().get_origin(); + result.collider_velocity = Vector2(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity(); + } + } + } + } + } + } + + ray_index++; + } + + rays_found = MAX(ray_index, rays_found); + + if (!collided || recover_motion == Vector2()) { + break; + } + + body_transform.elements[2] += recover_motion; + body_aabb.position += recover_motion; + + recover_attempts--; + } while (recover_attempts); + } + + //optimize results (remove non colliding) + for (int i = 0; i < rays_found; i++) { + if (r_results[i].collision_depth == 0) { + rays_found--; + SWAP(r_results[i], r_results[rays_found]); + } + } + + r_recover_motion = body_transform.elements[2] - p_transform.elements[2]; + return rays_found; +} + +bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, Physics2DServer::MotionResult *r_result, bool p_exclude_raycast_shapes) { //give me back regular physics engine logic //this is madness @@ -547,8 +696,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co if (p_body->is_shape_set_as_disabled(j)) continue; - Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j); Shape2DSW *body_shape = p_body->get_shape(j); + if (p_exclude_raycast_shapes && body_shape->get_type() == Physics2DServer::SHAPE_RAY) { + continue; + } + + Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j); for (int i = 0; i < amount; i++) { const CollisionObject2DSW *col_obj = intersection_query_results[i]; @@ -635,8 +788,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co if (p_body->is_shape_set_as_disabled(body_shape_idx)) continue; - Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(body_shape_idx); Shape2DSW *body_shape = p_body->get_shape(body_shape_idx); + if (p_exclude_raycast_shapes && body_shape->get_type() == Physics2DServer::SHAPE_RAY) { + continue; + } + + Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(body_shape_idx); bool stuck = false; diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index 79349c46f3..959e15e12d 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -182,7 +182,8 @@ public: int get_collision_pairs() const { return collision_pairs; } - bool test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, Physics2DServer::MotionResult *r_result); + bool test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, Physics2DServer::MotionResult *r_result, bool p_exclude_raycast_shapes = true); + int test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, Physics2DServer::SeparationResult *r_results, int p_result_max, real_t p_margin); void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); } _FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); } diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index ba5232f7fe..1d04fbc5c6 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -479,7 +479,22 @@ public: Variant collider_metadata; }; - virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.001, MotionResult *r_result = NULL) = 0; + virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.001, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true) = 0; + + struct SeparationResult { + + float collision_depth; + Vector2 collision_point; + Vector2 collision_normal; + Vector2 collider_velocity; + int collision_local_shape; + ObjectID collider_id; + RID collider; + int collider_shape; + Variant collider_metadata; + }; + + virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) = 0; /* JOINT API */ diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 3245e7be70..0b37d266e7 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -201,6 +201,7 @@ public: virtual void textures_keep_original(bool p_enable) = 0; virtual void texture_set_proxy(RID p_proxy, RID p_base) = 0; + virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0; /* SKY API */ diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 346b04f070..fd1eb77143 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -2545,7 +2545,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons TkPos pos = _get_tkpos(); tk = _get_token(); - if (tk.type == TK_PERIOD) { + if (tk.type == TK_CURSOR) { + //do nothing + } else if (tk.type == TK_PERIOD) { StringName identifier; if (_get_completable_identifier(p_block, COMPLETION_INDEX, identifier)) { @@ -4130,8 +4132,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct switch (completion_type) { case COMPLETION_NONE: { - //do none - return ERR_PARSE_ERROR; + //do nothing + return OK; } break; case COMPLETION_RENDER_MODE: { for (int i = 0; i < p_render_modes.size(); i++) { diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 163aa9bb07..5f207b1d3f 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -95,10 +95,11 @@ void VisualServerRaster::request_frame_drawn_callback(Object *p_where, const Str void VisualServerRaster::draw(bool p_swap_buffers) { - changes = 0; - + //needs to be done before changes is reset to 0, to not force the editor to redraw VS::get_singleton()->emit_signal("frame_pre_draw"); + changes = 0; + VSG::rasterizer->begin_frame(); VSG::scene->update_dirty_instances(); //update scene stuff diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index c03005592f..ec0d02ed2a 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -173,6 +173,8 @@ public: BIND2(texture_set_proxy, RID, RID) + BIND2(texture_set_force_redraw_if_visible, RID, bool) + /* SKY API */ BIND0R(RID, sky_create) diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 54fcd166c9..48f0ec46f3 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -107,6 +107,8 @@ public: FUNC2(texture_set_proxy, RID, RID) + FUNC2(texture_set_force_redraw_if_visible, RID, bool) + /* SKY API */ FUNCRID(sky) diff --git a/servers/visual_server.h b/servers/visual_server.h index 5027009634..968cb852ed 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -144,6 +144,7 @@ public: virtual void textures_keep_original(bool p_enable) = 0; virtual void texture_set_proxy(RID p_proxy, RID p_base) = 0; + virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0; /* SKY API */ |