From 2d8866574dd2c06ac03e7055642b917a0a3c6dac Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 30 Aug 2015 18:57:17 -0300 Subject: Added gravity scale, and linear/angular damp override to 3D physics. --- servers/physics/area_sw.cpp | 9 ++++--- servers/physics/area_sw.h | 10 +++++--- servers/physics/body_sw.cpp | 53 ++++++++++++++++++++++++++++++++++++----- servers/physics/body_sw.h | 15 ++++++++---- servers/physics_2d/body_2d_sw.h | 6 ++--- servers/physics_server.cpp | 24 +++++++++++++------ servers/physics_server.h | 13 ++++++---- 7 files changed, 100 insertions(+), 30 deletions(-) (limited to 'servers') diff --git a/servers/physics/area_sw.cpp b/servers/physics/area_sw.cpp index 83be80f816..01dfdd633f 100644 --- a/servers/physics/area_sw.cpp +++ b/servers/physics/area_sw.cpp @@ -123,7 +123,8 @@ void AreaSW::set_param(PhysicsServer::AreaParameter p_param, const Variant& p_va case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT: gravity_is_point=p_value; ; break; case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE: gravity_distance_scale=p_value; ; break; case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: point_attenuation=p_value; ; break; - case PhysicsServer::AREA_PARAM_DENSITY: density=p_value; ; break; + case PhysicsServer::AREA_PARAM_LINEAR_DAMP: linear_damp=p_value; ; break; + case PhysicsServer::AREA_PARAM_ANGULAR_DAMP: angular_damp=p_value; ; break; case PhysicsServer::AREA_PARAM_PRIORITY: priority=p_value; ; break; } @@ -139,7 +140,8 @@ Variant AreaSW::get_param(PhysicsServer::AreaParameter p_param) const { case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT: return gravity_is_point; case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE: return gravity_distance_scale; case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: return point_attenuation; - case PhysicsServer::AREA_PARAM_DENSITY: return density; + case PhysicsServer::AREA_PARAM_LINEAR_DAMP: return linear_damp; + case PhysicsServer::AREA_PARAM_ANGULAR_DAMP: return angular_damp; case PhysicsServer::AREA_PARAM_PRIORITY: return priority; } @@ -248,7 +250,8 @@ AreaSW::AreaSW() : CollisionObjectSW(TYPE_AREA), monitor_query_list(this), move gravity_is_point=false; gravity_distance_scale=0; point_attenuation=1; - density=0.1; + angular_damp=1.0; + linear_damp=0.1; priority=0; set_ray_pickable(false); monitor_callback_id=0; diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h index 26d6a177db..0c5295d42a 100644 --- a/servers/physics/area_sw.h +++ b/servers/physics/area_sw.h @@ -47,7 +47,8 @@ class AreaSW : public CollisionObjectSW{ bool gravity_is_point; float gravity_distance_scale; float point_attenuation; - float density; + float linear_damp; + float angular_damp; int priority; bool monitorable; @@ -145,8 +146,11 @@ public: _FORCE_INLINE_ void set_point_attenuation(float p_point_attenuation) { point_attenuation=p_point_attenuation; } _FORCE_INLINE_ float get_point_attenuation() const { return point_attenuation; } - _FORCE_INLINE_ void set_density(float p_density) { density=p_density; } - _FORCE_INLINE_ float get_density() const { return density; } + _FORCE_INLINE_ void set_linear_damp(float p_linear_damp) { linear_damp=p_linear_damp; } + _FORCE_INLINE_ float get_linear_damp() const { return linear_damp; } + + _FORCE_INLINE_ void set_angular_damp(float p_angular_damp) { angular_damp=p_angular_damp; } + _FORCE_INLINE_ float get_angular_damp() const { return angular_damp; } _FORCE_INLINE_ void set_priority(int p_priority) { priority=p_priority; } _FORCE_INLINE_ int get_priority() const { return priority; } diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp index 5a528ecf94..8edbaf0b89 100644 --- a/servers/physics/body_sw.cpp +++ b/servers/physics/body_sw.cpp @@ -159,6 +159,17 @@ void BodySW::set_param(PhysicsServer::BodyParameter p_param, float p_value) { _update_inertia(); } break; + case PhysicsServer::BODY_PARAM_GRAVITY_SCALE: { + gravity_scale=p_value; + } break; + case PhysicsServer::BODY_PARAM_LINEAR_DAMP: { + + linear_damp=p_value; + } break; + case PhysicsServer::BODY_PARAM_ANGULAR_DAMP: { + + angular_damp=p_value; + } break; default:{} } } @@ -177,6 +188,18 @@ float BodySW::get_param(PhysicsServer::BodyParameter p_param) const { case PhysicsServer::BODY_PARAM_MASS: { return mass; } break; + case PhysicsServer::BODY_PARAM_GRAVITY_SCALE: { + return gravity_scale; + } break; + case PhysicsServer::BODY_PARAM_LINEAR_DAMP: { + + return linear_damp; + } break; + case PhysicsServer::BODY_PARAM_ANGULAR_DAMP: { + + return angular_damp; + } break; + default:{} } @@ -380,6 +403,8 @@ void BodySW::integrate_forces(real_t p_step) { return; AreaSW *def_area = get_space()->get_default_area(); + AreaSW *damp_area = def_area; + ERR_FAIL_COND(!def_area); int ac = areas.size(); @@ -388,7 +413,7 @@ void BodySW::integrate_forces(real_t p_step) { if (ac) { areas.sort(); const AreaCMP *aa = &areas[0]; - density = aa[ac-1].area->get_density(); + damp_area = aa[ac-1].area; for(int i=ac-1;i>=0;i--) { _compute_area_gravity(aa[i].area); if (aa[i].area->get_space_override_mode() == PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE) { @@ -396,13 +421,25 @@ void BodySW::integrate_forces(real_t p_step) { break; } } - } else { - density=def_area->get_density(); } + if( !replace ) { _compute_area_gravity(def_area); } + gravity*=gravity_scale; + + if (angular_damp>=0) + area_angular_damp=angular_damp; + else + area_angular_damp=damp_area->get_angular_damp(); + + if (linear_damp>=0) + area_linear_damp=linear_damp; + else + area_linear_damp=damp_area->get_linear_damp(); + + Vector3 motion; bool do_motion=false; @@ -431,12 +468,12 @@ void BodySW::integrate_forces(real_t p_step) { force+=applied_force; Vector3 torque=applied_torque; - real_t damp = 1.0 - p_step * density; + real_t damp = 1.0 - p_step * area_linear_damp; if (damp<0) // reached zero in the given time damp=0; - real_t angular_damp = 1.0 - p_step * density * get_space()->get_body_angular_velocity_damp_ratio(); + real_t angular_damp = 1.0 - p_step * area_angular_damp; if (angular_damp<0) // reached zero in the given time angular_damp=0; @@ -695,8 +732,12 @@ BodySW::BodySW() : CollisionObjectSW(TYPE_BODY), active_list(this), inertia_upda island_list_next=NULL; first_time_kinematic=false; _set_static(false); - density=0; + contact_count=0; + gravity_scale=1.0; + + area_angular_damp=0; + area_linear_damp=0; still_time=0; continuous_cd=false; diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h index 6491ba8f18..66d814bfd1 100644 --- a/servers/physics/body_sw.h +++ b/servers/physics/body_sw.h @@ -50,6 +50,10 @@ class BodySW : public CollisionObjectSW { real_t bounce; real_t friction; + real_t linear_damp; + real_t angular_damp; + real_t gravity_scale; + PhysicsServer::BodyAxisLock axis_lock; real_t _inv_mass; @@ -57,13 +61,16 @@ class BodySW : public CollisionObjectSW { Matrix3 _inv_inertia_tensor; Vector3 gravity; - real_t density; real_t still_time; Vector3 applied_force; Vector3 applied_torque; + float area_angular_damp; + float area_linear_damp; + + SelfList active_list; SelfList inertia_update_list; SelfList direct_state_query_list; @@ -233,7 +240,6 @@ public: _FORCE_INLINE_ Matrix3 get_inv_inertia_tensor() const { return _inv_inertia_tensor; } _FORCE_INLINE_ real_t get_friction() const { return friction; } _FORCE_INLINE_ Vector3 get_gravity() const { return gravity; } - _FORCE_INLINE_ real_t get_density() const { return density; } _FORCE_INLINE_ real_t get_bounce() const { return bounce; } _FORCE_INLINE_ void set_axis_lock(PhysicsServer::BodyAxisLock p_lock) { axis_lock=p_lock; } @@ -335,8 +341,9 @@ public: BodySW *body; real_t step; - virtual Vector3 get_total_gravity() const { return body->get_gravity(); } // get gravity vector working on this body space/area - virtual float get_total_density() const { return body->get_density(); } // get density of this body space/area + virtual Vector3 get_total_gravity() const { return body->gravity; } // get gravity vector working on this body space/area + virtual float get_total_angular_damp() const { return body->area_angular_damp; } // get density of this body space/area + virtual float get_total_linear_damp() const { return body->area_linear_damp; } // get density of this body space/area virtual float get_inverse_mass() const { return body->get_inv_mass(); } // get the mass virtual Vector3 get_inverse_inertia() const { return body->get_inv_inertia(); } // get density of this body space diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h index c86bb51f1d..2fbfcaca60 100644 --- a/servers/physics_2d/body_2d_sw.h +++ b/servers/physics_2d/body_2d_sw.h @@ -337,9 +337,9 @@ public: Body2DSW *body; real_t step; - virtual Vector2 get_total_gravity() const { return body->get_gravity(); } // get gravity vector working on this body space/area - virtual float get_total_angular_damp() const { return body->get_angular_damp(); } // get density of this body space/area - virtual float get_total_linear_damp() const { return body->get_linear_damp(); } // get density of this body space/area + virtual Vector2 get_total_gravity() const { return body->gravity; } // get gravity vector working on this body space/area + virtual float get_total_angular_damp() const { return body->area_angular_damp; } // get density of this body space/area + virtual float get_total_linear_damp() const { return body->area_linear_damp; } // get density of this body space/area virtual float get_inverse_mass() const { return body->get_inv_mass(); } // get the mass virtual real_t get_inverse_inertia() const { return body->get_inv_inertia(); } // get density of this body space diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index e02601af41..53409acdfb 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -39,13 +39,18 @@ void PhysicsDirectBodyState::integrate_forces() { Vector3 av = get_angular_velocity(); - float damp = 1.0 - step * get_total_density(); + float linear_damp = 1.0 - step * get_total_linear_damp(); - if (damp<0) // reached zero in the given time - damp=0; + if (linear_damp<0) // reached zero in the given time + linear_damp=0; - lv*=damp; - av*=damp; + float angular_damp = 1.0 - step * get_total_angular_damp(); + + if (angular_damp<0) // reached zero in the given time + angular_damp=0; + + lv*=linear_damp; + av*=angular_damp; set_linear_velocity(lv); set_angular_velocity(av); @@ -70,7 +75,8 @@ PhysicsServer * PhysicsServer::get_singleton() { void PhysicsDirectBodyState::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_total_gravity"),&PhysicsDirectBodyState::get_total_gravity); - ObjectTypeDB::bind_method(_MD("get_total_density"),&PhysicsDirectBodyState::get_total_density); + ObjectTypeDB::bind_method(_MD("get_total_linear_damp"),&PhysicsDirectBodyState::get_total_linear_damp); + ObjectTypeDB::bind_method(_MD("get_total_angular_damp"),&PhysicsDirectBodyState::get_total_angular_damp); ObjectTypeDB::bind_method(_MD("get_inverse_mass"),&PhysicsDirectBodyState::get_inverse_mass); ObjectTypeDB::bind_method(_MD("get_inverse_inertia"),&PhysicsDirectBodyState::get_inverse_inertia); @@ -683,7 +689,8 @@ void PhysicsServer::_bind_methods() { BIND_CONSTANT( AREA_PARAM_GRAVITY_IS_POINT ); BIND_CONSTANT( AREA_PARAM_GRAVITY_DISTANCE_SCALE ); BIND_CONSTANT( AREA_PARAM_GRAVITY_POINT_ATTENUATION ); - BIND_CONSTANT( AREA_PARAM_DENSITY ); + BIND_CONSTANT( AREA_PARAM_LINEAR_DAMP ); + BIND_CONSTANT( AREA_PARAM_ANGULAR_DAMP ); BIND_CONSTANT( AREA_PARAM_PRIORITY ); BIND_CONSTANT( AREA_SPACE_OVERRIDE_COMBINE ); @@ -698,6 +705,9 @@ void PhysicsServer::_bind_methods() { BIND_CONSTANT( BODY_PARAM_BOUNCE ); BIND_CONSTANT( BODY_PARAM_FRICTION ); BIND_CONSTANT( BODY_PARAM_MASS ); + BIND_CONSTANT( BODY_PARAM_GRAVITY_SCALE ); + BIND_CONSTANT( BODY_PARAM_ANGULAR_DAMP ); + BIND_CONSTANT( BODY_PARAM_LINEAR_DAMP ); BIND_CONSTANT( BODY_PARAM_MAX ); BIND_CONSTANT( BODY_STATE_TRANSFORM ); diff --git a/servers/physics_server.h b/servers/physics_server.h index f66ea590b8..b82d4cf5da 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -41,8 +41,9 @@ protected: static void _bind_methods(); public: - virtual Vector3 get_total_gravity() const=0; // get gravity vector working on this body space/area - virtual float get_total_density() const=0; // get density of this body space/area + virtual Vector3 get_total_gravity() const=0; + virtual float get_total_angular_damp() const=0; + virtual float get_total_linear_damp() const=0; virtual float get_inverse_mass() const=0; // get the mass virtual Vector3 get_inverse_inertia() const=0; // get density of this body space @@ -300,7 +301,8 @@ public: AREA_PARAM_GRAVITY_IS_POINT, AREA_PARAM_GRAVITY_DISTANCE_SCALE, AREA_PARAM_GRAVITY_POINT_ATTENUATION, - AREA_PARAM_DENSITY, + AREA_PARAM_LINEAR_DAMP, + AREA_PARAM_ANGULAR_DAMP, AREA_PARAM_PRIORITY }; @@ -398,6 +400,9 @@ public: BODY_PARAM_BOUNCE, BODY_PARAM_FRICTION, BODY_PARAM_MASS, ///< unused for static, always infinite + BODY_PARAM_GRAVITY_SCALE, + BODY_PARAM_LINEAR_DAMP, + BODY_PARAM_ANGULAR_DAMP, BODY_PARAM_MAX, }; @@ -411,7 +416,7 @@ public: BODY_STATE_LINEAR_VELOCITY, BODY_STATE_ANGULAR_VELOCITY, BODY_STATE_SLEEPING, - BODY_STATE_CAN_SLEEP + BODY_STATE_CAN_SLEEP }; virtual void body_set_state(RID p_body, BodyState p_state, const Variant& p_variant)=0; -- cgit v1.2.3 From b0aa49accbd7e45dae38f1bd43b0fbdd11714211 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Thu, 3 Sep 2015 23:24:55 -0300 Subject: merged some stuff for okam --- servers/physics/area_sw.cpp | 8 ++++++++ servers/physics/area_sw.h | 1 + servers/physics_2d/area_2d_sw.cpp | 8 ++++++++ servers/visual/visual_server_raster.cpp | 18 ++++++++++++++++-- 4 files changed, 33 insertions(+), 2 deletions(-) (limited to 'servers') diff --git a/servers/physics/area_sw.cpp b/servers/physics/area_sw.cpp index 01dfdd633f..e78f0699cb 100644 --- a/servers/physics/area_sw.cpp +++ b/servers/physics/area_sw.cpp @@ -83,6 +83,10 @@ void AreaSW::set_monitor_callback(ObjectID p_id, const StringName& p_method) { _shape_changed(); + if (!moved_list.in_list() && get_space()) + get_space()->area_add_to_moved_list(&moved_list); + + } void AreaSW::set_area_monitor_callback(ObjectID p_id, const StringName& p_method) { @@ -103,6 +107,10 @@ void AreaSW::set_area_monitor_callback(ObjectID p_id, const StringName& p_method _shape_changed(); + if (!moved_list.in_list() && get_space()) + get_space()->area_add_to_moved_list(&moved_list); + + } diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h index 0c5295d42a..40ccdaf370 100644 --- a/servers/physics/area_sw.h +++ b/servers/physics/area_sw.h @@ -206,6 +206,7 @@ void AreaSW::remove_area_from_query(AreaSW *p_area, uint32_t p_area_shape,uint32 monitored_areas[bk].dec(); if (!monitor_query_list.in_list()) _queue_monitor_update(); + } diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp index 1a41cda482..a5a132020a 100644 --- a/servers/physics_2d/area_2d_sw.cpp +++ b/servers/physics_2d/area_2d_sw.cpp @@ -82,6 +82,10 @@ void Area2DSW::set_monitor_callback(ObjectID p_id, const StringName& p_method) { _shape_changed(); + if (!moved_list.in_list() && get_space()) + get_space()->area_add_to_moved_list(&moved_list); + + } void Area2DSW::set_area_monitor_callback(ObjectID p_id, const StringName& p_method) { @@ -102,6 +106,10 @@ void Area2DSW::set_area_monitor_callback(ObjectID p_id, const StringName& p_meth _shape_changed(); + if (!moved_list.in_list() && get_space()) + get_space()->area_add_to_moved_list(&moved_list); + + } diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index b51f59050d..8b47596d7e 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -7351,6 +7351,8 @@ void VisualServerRaster::_draw_cursors_and_margins() { rasterizer->canvas_draw_rect(Rect2(cursors[i].pos, size), 0, Rect2(), tex, Color(1, 1, 1, 1)); }; + + if (black_image[MARGIN_LEFT].is_valid()) { Size2 sz(rasterizer->texture_get_width(black_image[MARGIN_LEFT]),rasterizer->texture_get_height(black_image[MARGIN_LEFT])); rasterizer->canvas_draw_rect(Rect2(0,0,black_margin[MARGIN_LEFT],window_h),0,Rect2(0,0,sz.x,sz.y),black_image[MARGIN_LEFT],Color(1,1,1)); @@ -7362,10 +7364,22 @@ void VisualServerRaster::_draw_cursors_and_margins() { rasterizer->canvas_draw_rect(Rect2(window_w-black_margin[MARGIN_RIGHT],0,black_margin[MARGIN_RIGHT],window_h),0,Rect2(0,0,sz.x,sz.y),black_image[MARGIN_RIGHT],Color(1,1,1)); } else if (black_margin[MARGIN_RIGHT]) rasterizer->canvas_draw_rect(Rect2(window_w-black_margin[MARGIN_RIGHT],0,black_margin[MARGIN_RIGHT],window_h),0,Rect2(0,0,1,1),RID(),Color(0,0,0)); - if (black_margin[MARGIN_TOP]) + + if (black_image[MARGIN_TOP].is_valid()) { + Size2 sz(rasterizer->texture_get_width(black_image[MARGIN_TOP]),rasterizer->texture_get_height(black_image[MARGIN_TOP])); + rasterizer->canvas_draw_rect(Rect2(0,0,window_w,black_margin[MARGIN_TOP]),0,Rect2(0,0,sz.x,sz.y),black_image[MARGIN_TOP],Color(1,1,1)); + + } else if (black_margin[MARGIN_TOP]) { rasterizer->canvas_draw_rect(Rect2(0,0,window_w,black_margin[MARGIN_TOP]),0,Rect2(0,0,1,1),RID(),Color(0,0,0)); - if (black_margin[MARGIN_BOTTOM]) + } + + if (black_image[MARGIN_BOTTOM].is_valid()) { + + Size2 sz(rasterizer->texture_get_width(black_image[MARGIN_BOTTOM]),rasterizer->texture_get_height(black_image[MARGIN_BOTTOM])); + rasterizer->canvas_draw_rect(Rect2(0,window_h-black_margin[MARGIN_BOTTOM],window_w,black_margin[MARGIN_BOTTOM]),0,Rect2(0,0,sz.x,sz.y),black_image[MARGIN_BOTTOM],Color(1,1,1)); + } else if (black_margin[MARGIN_BOTTOM]) { rasterizer->canvas_draw_rect(Rect2(0,window_h-black_margin[MARGIN_BOTTOM],window_w,black_margin[MARGIN_BOTTOM]),0,Rect2(0,0,1,1),RID(),Color(0,0,0)); + } rasterizer->canvas_end_rect(); }; -- cgit v1.2.3 From 97413746173b4f872e8c72eba0e58d7092a93269 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Wed, 9 Sep 2015 18:50:52 -0300 Subject: Rewrite of the AudioStream API -Fixes long-standing issues regarding to playing a single stream multiple times simultanteously -Fixes wrong-looping, starting, caching, etc. Issues resulting from bad original design -Allows more interesting kinds of streams (stream graphs with streams inside streams!) in the future --- servers/audio/audio_rb_resampler.cpp | 356 +++++++++++++++++++++++++++++++++++ servers/audio/audio_rb_resampler.h | 133 +++++++++++++ servers/audio/audio_server_sw.cpp | 6 +- 3 files changed, 494 insertions(+), 1 deletion(-) create mode 100644 servers/audio/audio_rb_resampler.cpp create mode 100644 servers/audio/audio_rb_resampler.h (limited to 'servers') diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp new file mode 100644 index 0000000000..d07d55f1b5 --- /dev/null +++ b/servers/audio/audio_rb_resampler.cpp @@ -0,0 +1,356 @@ +#include "audio_rb_resampler.h" + + +int AudioRBResampler::get_channel_count() const { + + if (!rb) + return 0; + + return channels; +} + + +template +uint32_t AudioRBResampler::_resample(int32_t *p_dest,int p_todo,int32_t p_increment) { + + uint32_t read=offset&MIX_FRAC_MASK; + + for (int i=0;i> MIX_FRAC_BITS; + uint32_t frac = offset & MIX_FRAC_MASK; +#ifndef FAST_AUDIO + ERR_FAIL_COND_V(pos>=rb_len,0); +#endif + uint32_t pos_next = (pos+1)&rb_mask; + //printf("rb pos %i\n",pos); + + // since this is a template with a known compile time value (C), conditionals go away when compiling. + if (C==1) { + + int32_t v0 = rb[pos]; + int32_t v0n=rb[pos_next]; +#ifndef FAST_AUDIO + v0+=(v0n-v0)*(int32_t)frac >> MIX_FRAC_BITS; +#endif + v0<<=16; + p_dest[i]=v0; + + } + if (C==2) { + + int32_t v0 = rb[(pos<<1)+0]; + int32_t v1 = rb[(pos<<1)+1]; + int32_t v0n=rb[(pos_next<<1)+0]; + int32_t v1n=rb[(pos_next<<1)+1]; + +#ifndef FAST_AUDIO + v0+=(v0n-v0)*(int32_t)frac >> MIX_FRAC_BITS; + v1+=(v1n-v1)*(int32_t)frac >> MIX_FRAC_BITS; +#endif + v0<<=16; + v1<<=16; + p_dest[(i<<1)+0]=v0; + p_dest[(i<<1)+1]=v1; + + } + + if (C==4) { + + int32_t v0 = rb[(pos<<2)+0]; + int32_t v1 = rb[(pos<<2)+1]; + int32_t v2 = rb[(pos<<2)+2]; + int32_t v3 = rb[(pos<<2)+3]; + int32_t v0n = rb[(pos_next<<2)+0]; + int32_t v1n=rb[(pos_next<<2)+1]; + int32_t v2n=rb[(pos_next<<2)+2]; + int32_t v3n=rb[(pos_next<<2)+3]; + +#ifndef FAST_AUDIO + v0+=(v0n-v0)*(int32_t)frac >> MIX_FRAC_BITS; + v1+=(v1n-v1)*(int32_t)frac >> MIX_FRAC_BITS; + v2+=(v2n-v2)*(int32_t)frac >> MIX_FRAC_BITS; + v3+=(v3n-v3)*(int32_t)frac >> MIX_FRAC_BITS; +#endif + v0<<=16; + v1<<=16; + v2<<=16; + v3<<=16; + p_dest[(i<<2)+0]=v0; + p_dest[(i<<2)+1]=v1; + p_dest[(i<<2)+2]=v2; + p_dest[(i<<2)+3]=v3; + + } + + if (C==6) { + + int32_t v0 = rb[(pos*6)+0]; + int32_t v1 = rb[(pos*6)+1]; + int32_t v2 = rb[(pos*6)+2]; + int32_t v3 = rb[(pos*6)+3]; + int32_t v4 = rb[(pos*6)+4]; + int32_t v5 = rb[(pos*6)+5]; + int32_t v0n = rb[(pos_next*6)+0]; + int32_t v1n=rb[(pos_next*6)+1]; + int32_t v2n=rb[(pos_next*6)+2]; + int32_t v3n=rb[(pos_next*6)+3]; + int32_t v4n=rb[(pos_next*6)+4]; + int32_t v5n=rb[(pos_next*6)+5]; + +#ifndef FAST_AUDIO + v0+=(v0n-v0)*(int32_t)frac >> MIX_FRAC_BITS; + v1+=(v1n-v1)*(int32_t)frac >> MIX_FRAC_BITS; + v2+=(v2n-v2)*(int32_t)frac >> MIX_FRAC_BITS; + v3+=(v3n-v3)*(int32_t)frac >> MIX_FRAC_BITS; + v4+=(v4n-v4)*(int32_t)frac >> MIX_FRAC_BITS; + v5+=(v5n-v5)*(int32_t)frac >> MIX_FRAC_BITS; +#endif + v0<<=16; + v1<<=16; + v2<<=16; + v3<<=16; + v4<<=16; + v5<<=16; + p_dest[(i*6)+0]=v0; + p_dest[(i*6)+1]=v1; + p_dest[(i*6)+2]=v2; + p_dest[(i*6)+3]=v3; + p_dest[(i*6)+4]=v4; + p_dest[(i*6)+5]=v5; + + } + + + } + + + return read>>MIX_FRAC_BITS;//rb_read_pos=offset>>MIX_FRAC_BITS; + +} + + +bool AudioRBResampler::mix(int32_t *p_dest, int p_frames) { + + + if (!rb) + return false; + + int write_pos_cache=rb_write_pos; + + int32_t increment=(src_mix_rate*MIX_FRAC_LEN)/target_mix_rate; + + int rb_todo; + + if (write_pos_cache==rb_read_pos) { + return false; //out of buffer + + } else if (rb_read_pos(p_dest,todo,increment); break; + case 2: read=_resample<2>(p_dest,todo,increment); break; + case 4: read=_resample<4>(p_dest,todo,increment); break; + case 6: read=_resample<6>(p_dest,todo,increment); break; + } +#if 1 + //end of stream, fadeout + int remaining = p_frames-todo; + if (remaining && todo>0) { + + //print_line("fadeout"); + for(int c=0;c>8; + uint32_t mul = (todo-i) * 256 /todo; + //print_line("mul: "+itos(i)+" "+itos(mul)); + p_dest[i*channels+c]=samp*mul; + } + + } + + } + +#else + int remaining = p_frames-todo; + if (remaining && todo>0) { + + + for(int c=0;c>8; + + for(int i=0;irb_todo) + read=rb_todo; + + rb_read_pos = (rb_read_pos+read)&rb_mask; + + + + + } + + return true; +} + + +Error AudioRBResampler::setup(int p_channels,int p_src_mix_rate,int p_target_mix_rate,int p_buffer_msec,int p_minbuff_needed) { + + ERR_FAIL_COND_V(p_channels!=1 && p_channels!=2 && p_channels!=4 && p_channels!=6,ERR_INVALID_PARAMETER); + + + //float buffering_sec = int(GLOBAL_DEF("audio/stream_buffering_ms",500))/1000.0; + int desired_rb_bits =nearest_shift(MAX((p_buffer_msec/1000.0)*p_src_mix_rate,p_minbuff_needed)); + + bool recreate=!rb; + + if (rb && (uint32_t(desired_rb_bits)!=rb_bits || channels!=uint32_t(p_channels))) { + //recreate + + memdelete_arr(rb); + memdelete_arr(read_buf); + recreate=true; + + } + + if (recreate) { + + channels=p_channels; + rb_bits=desired_rb_bits; + rb_len=(1< + uint32_t _resample(int32_t *p_dest,int p_todo,int32_t p_increment); + + +public: + + _FORCE_INLINE_ void flush() { + rb_read_pos=0; + rb_write_pos=0; + } + + _FORCE_INLINE_ bool is_ready() const{ + return rb!=NULL; + } + + + _FORCE_INLINE_ int get_total() const { + + return rb_len-1; + } + + _FORCE_INLINE_ int get_todo() const { //return amount of frames to mix + + int todo; + int read_pos_cache=rb_read_pos; + + if (read_pos_cache==rb_write_pos) { + todo=rb_len-1; + } else if (read_pos_cache>rb_write_pos) { + + todo=read_pos_cache-rb_write_pos-1; + } else { + + todo=(rb_len-rb_write_pos)+read_pos_cache-1; + } + + return todo; + } + + _FORCE_INLINE_ int16_t *get_write_buffer() { return read_buf; } + _FORCE_INLINE_ void write(uint32_t p_frames) { + + ERR_FAIL_COND(p_frames >= rb_len); + + switch(channels) { + case 1: { + + for(uint32_t i=0;i::Element *E=active_audio_streams.front();E;E=E->next()) { + for(List::Element *E=active_audio_streams.front();E;) { //stream might be removed durnig this callback + + List::Element *N=E->next(); if (E->get()->audio_stream && p_thread == E->get()->audio_stream->can_update_mt()) E->get()->audio_stream->update(); + + E=N; } } -- cgit v1.2.3 From b0e5031f1fb417ea087f08649afe9a9fdf072932 Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 10 Sep 2015 15:01:02 -0700 Subject: ios now displays splash screen between launch image and main scene, instead of a black screen --- servers/visual/rasterizer.h | 1 + servers/visual/visual_server_raster.cpp | 2 ++ 2 files changed, 3 insertions(+) (limited to 'servers') diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 0b115a4d1d..15c757665b 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -1022,6 +1022,7 @@ public: virtual bool has_feature(VS::Features p_feature) const=0; + virtual void restore_framebuffer()=0; virtual int get_render_info(VS::RenderInfo p_info)=0; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 8b47596d7e..155d10d85a 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -7427,6 +7427,8 @@ void VisualServerRaster::set_boot_image(const Image& p_image, const Color& p_col if (p_image.empty()) return; + rasterizer->restore_framebuffer(); + rasterizer->begin_frame(); int window_w = OS::get_singleton()->get_video_mode(0).width; -- cgit v1.2.3 From e5730c1c7c8da29ea85a04daf7479f293329d39c Mon Sep 17 00:00:00 2001 From: romulox_x Date: Sat, 12 Sep 2015 19:15:02 -0700 Subject: fixed server breaking error in previous splash screen commit --- servers/visual/rasterizer_dummy.cpp | 3 +++ servers/visual/rasterizer_dummy.h | 1 + 2 files changed, 4 insertions(+) (limited to 'servers') diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp index e32f47b3d8..c05438aef3 100644 --- a/servers/visual/rasterizer_dummy.cpp +++ b/servers/visual/rasterizer_dummy.cpp @@ -1948,6 +1948,9 @@ bool RasterizerDummy::has_feature(VS::Features p_feature) const { } +void RasterizerDummy::restore_framebuffer() { + +} RasterizerDummy::RasterizerDummy() { diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h index cc3c1724a4..9249ad6256 100644 --- a/servers/visual/rasterizer_dummy.h +++ b/servers/visual/rasterizer_dummy.h @@ -779,6 +779,7 @@ public: virtual bool has_feature(VS::Features p_feature) const; + virtual void restore_framebuffer(); RasterizerDummy(); virtual ~RasterizerDummy(); -- cgit v1.2.3 From afbb6c064c88d743d8a7d04b5dbfb4b0b1b2db7f Mon Sep 17 00:00:00 2001 From: firefly2442 Date: Wed, 16 Sep 2015 15:35:30 -0500 Subject: ran cppcheck, found unused variables --- servers/physics/body_pair_sw.cpp | 1 - servers/visual/visual_server_raster.cpp | 1 - 2 files changed, 2 deletions(-) (limited to 'servers') diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp index e2b2fa2051..16e5a1be92 100644 --- a/servers/physics/body_pair_sw.cpp +++ b/servers/physics/body_pair_sw.cpp @@ -194,7 +194,6 @@ bool BodyPairSW::_test_ccd(float p_step,BodySW *p_A, int p_shape_A,const Transfo //cast a segment from support in motion normal, in the same direction of motion by motion length //support is the worst case collision point, so real collision happened before - int a; Vector3 s=p_A->get_shape(p_shape_A)->get_support(p_xform_A.basis.xform(mnormal).normalized()); Vector3 from = p_xform_A.xform(s); Vector3 to = from + motion; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 155d10d85a..3ae7cfeaf8 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -5211,7 +5211,6 @@ void VisualServerRaster::_light_instance_update_lispsm_shadow(Instance *p_light, AABB proj_space_aabb; - float max_d,min_d; { -- cgit v1.2.3 From c858515785e2406bfc07da587ffc3bb353b7504c Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sat, 26 Sep 2015 14:50:42 -0300 Subject: Fixed theora playback. Removed theoraplayer. Still need to get proper audio output latency in some platforms. --- servers/audio/audio_server_sw.cpp | 2 +- servers/audio/audio_server_sw.h | 2 ++ servers/audio_server.cpp | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'servers') diff --git a/servers/audio/audio_server_sw.cpp b/servers/audio/audio_server_sw.cpp index 09cb4eca5f..9aaaa240c3 100644 --- a/servers/audio/audio_server_sw.cpp +++ b/servers/audio/audio_server_sw.cpp @@ -920,7 +920,7 @@ float AudioServerSW::get_event_voice_global_volume_scale() const { double AudioServerSW::get_output_delay() const { - return _output_delay; + return _output_delay+AudioDriverSW::get_singleton()->get_latency(); } double AudioServerSW::get_mix_time() const { diff --git a/servers/audio/audio_server_sw.h b/servers/audio/audio_server_sw.h index 77d2f2e8dd..91146e64e6 100644 --- a/servers/audio/audio_server_sw.h +++ b/servers/audio/audio_server_sw.h @@ -256,6 +256,8 @@ public: virtual void unlock()=0; virtual void finish()=0; + virtual float get_latency() { return 0; } + diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 7c4f8b185a..c155f5204a 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -164,6 +164,7 @@ void AudioServer::_bind_methods() { BIND_CONSTANT( REVERB_HALL ); GLOBAL_DEF("audio/stream_buffering_ms",500); + GLOBAL_DEF("audio/video_delay_compensation_ms",300); } -- cgit v1.2.3 From 092f84642c89a4257176535da61e6050a8cc6dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Sat, 26 Sep 2015 22:42:43 +0200 Subject: Rename voice_set_volume argument to p_volume to avoid confusion This argument is indeed expected to be a volume on a linear scale (not dB), typically from 0.0 to 1.0, though it can go higher than 1.0. --- servers/audio/audio_server_sw.cpp | 4 ++-- servers/audio/audio_server_sw.h | 2 +- servers/audio_server.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'servers') diff --git a/servers/audio/audio_server_sw.cpp b/servers/audio/audio_server_sw.cpp index 09cb4eca5f..141c940615 100644 --- a/servers/audio/audio_server_sw.cpp +++ b/servers/audio/audio_server_sw.cpp @@ -455,12 +455,12 @@ void AudioServerSW::voice_play(RID p_voice, RID p_sample) { } -void AudioServerSW::voice_set_volume(RID p_voice, float p_db) { +void AudioServerSW::voice_set_volume(RID p_voice, float p_volume) { VoiceRBSW::Command cmd; cmd.type=VoiceRBSW::Command::CMD_SET_VOLUME; cmd.voice=p_voice; - cmd.volume.volume=p_db; + cmd.volume.volume=p_volume; voice_rb.push_command(cmd); } diff --git a/servers/audio/audio_server_sw.h b/servers/audio/audio_server_sw.h index 77d2f2e8dd..250855a43e 100644 --- a/servers/audio/audio_server_sw.h +++ b/servers/audio/audio_server_sw.h @@ -146,7 +146,7 @@ public: virtual void voice_play(RID p_voice, RID p_sample); - virtual void voice_set_volume(RID p_voice, float p_db); + virtual void voice_set_volume(RID p_voice, float p_volume); virtual void voice_set_pan(RID p_voice, float p_pan, float p_depth=0,float height=0); //pan and depth go from -1 to 1 virtual void voice_set_filter(RID p_voice, FilterType p_type, float p_cutoff, float p_resonance,float p_gain=0); virtual void voice_set_chorus(RID p_voice, float p_chorus ); diff --git a/servers/audio_server.h b/servers/audio_server.h index f54698a1e3..cd3e920f31 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -210,7 +210,7 @@ public: virtual void voice_play(RID p_voice, RID p_sample)=0; - virtual void voice_set_volume(RID p_voice, float p_gain)=0; + virtual void voice_set_volume(RID p_voice, float p_volume)=0; virtual void voice_set_pan(RID p_voice, float p_pan, float p_depth=0,float height=0)=0; //pan and depth go from -1 to 1 virtual void voice_set_filter(RID p_voice, FilterType p_type, float p_cutoff, float p_resonance, float p_gain=0)=0; virtual void voice_set_chorus(RID p_voice, float p_chorus )=0; -- cgit v1.2.3 From 7f001a2c762d50d7502fefde477487b911ddee47 Mon Sep 17 00:00:00 2001 From: Zher Huei Lee Date: Mon, 5 Oct 2015 11:50:16 +0100 Subject: nested clipping of canvas items now works --- servers/visual/visual_server_raster.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'servers') diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index fbea60c3a6..cf840c1be3 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -6824,7 +6824,11 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat copymem(child_items,ci->child_items.ptr(),child_item_count*sizeof(CanvasItem*)); if (ci->clip) { - ci->final_clip_rect=global_rect; + if (p_canvas_clip != NULL) { + ci->final_clip_rect=p_canvas_clip->final_clip_rect.clip(global_rect); + } else { + ci->final_clip_rect=global_rect; + } ci->final_clip_owner=ci; } else { -- cgit v1.2.3 From 3514a87b371385cdc71a2ed36deb40cd0275fff5 Mon Sep 17 00:00:00 2001 From: reduz Date: Thu, 8 Oct 2015 14:50:18 -0300 Subject: fixed uninitialized memory issues in audio code --- servers/audio/audio_mixer_sw.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'servers') diff --git a/servers/audio/audio_mixer_sw.cpp b/servers/audio/audio_mixer_sw.cpp index 788eec0d4a..791f31719e 100644 --- a/servers/audio/audio_mixer_sw.cpp +++ b/servers/audio/audio_mixer_sw.cpp @@ -765,6 +765,10 @@ AudioMixer::ChannelID AudioMixerSW::channel_alloc(RID p_sample) { c.mix.increment=1; //zero everything when this errors for(int i=0;i<4;i++) { + c.mix.vol[i]=0; + c.mix.reverb_vol[i]=0; + c.mix.chorus_vol[i]=0; + c.mix.old_vol[i]=0; c.mix.old_reverb_vol[i]=0; c.mix.old_chorus_vol[i]=0; -- cgit v1.2.3 From aad2bbdb6fb7c8217d7e75480b38e45f00cb3abd Mon Sep 17 00:00:00 2001 From: reduz Date: Thu, 8 Oct 2015 15:00:40 -0300 Subject: newline fixes --- servers/physics/space_sw.cpp | 1492 +++++++++++++++++++++--------------------- servers/physics/space_sw.h | 374 +++++------ 2 files changed, 933 insertions(+), 933 deletions(-) (limited to 'servers') diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index a4fe1dd3fc..d36b004989 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -1,746 +1,746 @@ -/*************************************************************************/ -/* space_sw.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "globals.h" -#include "space_sw.h" -#include "collision_solver_sw.h" -#include "physics_server_sw.h" - - -_FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object, uint32_t p_layer_mask, uint32_t p_type_mask) { - - if ((p_object->get_layer_mask()&p_layer_mask)==0) - return false; - - if (p_object->get_type()==CollisionObjectSW::TYPE_AREA && !(p_type_mask&PhysicsDirectSpaceState::TYPE_MASK_AREA)) - return false; - - BodySW *body = static_cast(p_object); - - return (1<get_mode())&p_type_mask; - -} - - -bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3& p_from, const Vector3& p_to,RayResult &r_result,const Set& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) { - - - ERR_FAIL_COND_V(space->locked,false); - - Vector3 begin,end; - Vector3 normal; - begin=p_from; - end=p_to; - normal=(end-begin).normalized(); - - - int amount = space->broadphase->cull_segment(begin,end,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); - - - //todo, create another array tha references results, compute AABBs and check closest point to ray origin, sort, and stop evaluating results when beyond first collision - - bool collided=false; - Vector3 res_point,res_normal; - int res_shape; - const CollisionObjectSW *res_obj; - real_t min_d=1e10; - - - - for(int i=0;iintersection_query_results[i],p_layer_mask,p_object_type_mask)) - continue; - - if (!(static_cast(space->intersection_query_results[i])->is_ray_pickable())) - continue; - - if (p_exclude.has( space->intersection_query_results[i]->get_self())) - continue; - - const CollisionObjectSW *col_obj=space->intersection_query_results[i]; - - int shape_idx=space->intersection_query_subindex_results[i]; - Transform inv_xform = col_obj->get_shape_inv_transform(shape_idx) * col_obj->get_inv_transform(); - - Vector3 local_from = inv_xform.xform(begin); - Vector3 local_to = inv_xform.xform(end); - - const ShapeSW *shape = col_obj->get_shape(shape_idx); - - Vector3 shape_point,shape_normal; - - - if (shape->intersect_segment(local_from,local_to,shape_point,shape_normal)) { - - - - Transform xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); - shape_point=xform.xform(shape_point); - - real_t ld = normal.dot(shape_point); - - - if (ldget_instance_id(); - if (r_result.collider_id!=0) - r_result.collider=ObjectDB::get_instance(r_result.collider_id); - else - r_result.collider=NULL; - r_result.normal=res_normal; - r_result.position=res_point; - r_result.rid=res_obj->get_self(); - r_result.shape=res_shape; - - return true; - -} - - -int PhysicsDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Transform& p_xform,float p_margin,ShapeResult *r_results,int p_result_max,const Set& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) { - - if (p_result_max<=0) - return 0; - - ShapeSW *shape = static_cast(PhysicsServer::get_singleton())->shape_owner.get(p_shape); - ERR_FAIL_COND_V(!shape,0); - - AABB aabb = p_xform.xform(shape->get_aabb()); - - int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); - - bool collided=false; - int cc=0; - - //Transform ai = p_xform.affine_inverse(); - - for(int i=0;i=p_result_max) - break; - - if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask)) - continue; - - //area cant be picked by ray (default) - - if (p_exclude.has( space->intersection_query_results[i]->get_self())) - continue; - - - const CollisionObjectSW *col_obj=space->intersection_query_results[i]; - int shape_idx=space->intersection_query_subindex_results[i]; - - if (!CollisionSolverSW::solve_static(shape,p_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), NULL,NULL,NULL,p_margin,0)) - continue; - - r_results[cc].collider_id=col_obj->get_instance_id(); - if (r_results[cc].collider_id!=0) - r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id); - else - r_results[cc].collider=NULL; - r_results[cc].rid=col_obj->get_self(); - r_results[cc].shape=shape_idx; - - cc++; - - } - - return cc; - -} - - -bool PhysicsDirectSpaceStateSW::cast_motion(const RID& p_shape, const Transform& p_xform,const Vector3& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask,ShapeRestInfo *r_info) { - - - - ShapeSW *shape = static_cast(PhysicsServer::get_singleton())->shape_owner.get(p_shape); - ERR_FAIL_COND_V(!shape,false); - - AABB aabb = p_xform.xform(shape->get_aabb()); - aabb=aabb.merge(AABB(aabb.pos+p_motion,aabb.size)); //motion - aabb=aabb.grow(p_margin); - - //if (p_motion!=Vector3()) - // print_line(p_motion); - - int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); - - float best_safe=1; - float best_unsafe=1; - - Transform xform_inv = p_xform.affine_inverse(); - MotionShapeSW mshape; - mshape.shape=shape; - mshape.motion=xform_inv.basis.xform(p_motion); - - bool best_first=true; - - Vector3 closest_A,closest_B; - - for(int i=0;iintersection_query_results[i],p_layer_mask,p_object_type_mask)) - continue; - - if (p_exclude.has( space->intersection_query_results[i]->get_self())) - continue; //ignore excluded - - - const CollisionObjectSW *col_obj=space->intersection_query_results[i]; - int shape_idx=space->intersection_query_subindex_results[i]; - - Vector3 point_A,point_B; - Vector3 sep_axis=p_motion.normalized(); - - Transform col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); - //test initial overlap, does it collide if going all the way? - if (CollisionSolverSW::solve_distance(&mshape,p_xform,col_obj->get_shape(shape_idx),col_obj_xform,point_A,point_B,aabb,&sep_axis)) { - //print_line("failed motion cast (no collision)"); - continue; - } - - - //test initial overlap -#if 0 - if (CollisionSolverSW::solve_static(shape,p_xform,col_obj->get_shape(shape_idx),col_obj_xform,NULL,NULL,&sep_axis)) { - print_line("failed initial cast (collision at begining)"); - return false; - } -#else - sep_axis=p_motion.normalized(); - - if (!CollisionSolverSW::solve_distance(shape,p_xform,col_obj->get_shape(shape_idx),col_obj_xform,point_A,point_B,aabb,&sep_axis)) { - //print_line("failed motion cast (no collision)"); - return false; - } -#endif - - - //just do kinematic solving - float low=0; - float hi=1; - Vector3 mnormal=p_motion.normalized(); - - for(int i=0;i<8;i++) { //steps should be customizable.. - - Transform xfa = p_xform; - float ofs = (low+hi)*0.5; - - Vector3 sep=mnormal; //important optimization for this to work fast enough - - mshape.motion=xform_inv.basis.xform(p_motion*ofs); - - Vector3 lA,lB; - - bool collided = !CollisionSolverSW::solve_distance(&mshape,p_xform,col_obj->get_shape(shape_idx),col_obj_xform,lA,lB,aabb,&sep); - - if (collided) { - - //print_line(itos(i)+": "+rtos(ofs)); - hi=ofs; - } else { - - point_A=lA; - point_B=lB; - low=ofs; - } - } - - if (lowcollider_id=col_obj->get_instance_id(); - r_info->rid=col_obj->get_self(); - r_info->shape=shape_idx; - r_info->point=closest_B; - r_info->normal=(closest_A-closest_B).normalized(); - best_first=false; - if (col_obj->get_type()==CollisionObjectSW::TYPE_BODY) { - const BodySW *body=static_cast(col_obj); - r_info->linear_velocity= body->get_linear_velocity() + (body->get_angular_velocity()).cross(body->get_transform().origin - closest_B); - } - - } - - - } - - p_closest_safe=best_safe; - p_closest_unsafe=best_unsafe; - - return true; -} - -bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform& p_shape_xform,float p_margin,Vector3 *r_results,int p_result_max,int &r_result_count, const Set& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask){ - - if (p_result_max<=0) - return 0; - - ShapeSW *shape = static_cast(PhysicsServer::get_singleton())->shape_owner.get(p_shape); - ERR_FAIL_COND_V(!shape,0); - - AABB aabb = p_shape_xform.xform(shape->get_aabb()); - aabb=aabb.grow(p_margin); - - int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); - - bool collided=false; - int cc=0; - r_result_count=0; - - PhysicsServerSW::CollCbkData cbk; - cbk.max=p_result_max; - cbk.amount=0; - cbk.ptr=r_results; - CollisionSolverSW::CallbackResult cbkres=NULL; - - PhysicsServerSW::CollCbkData *cbkptr=NULL; - if (p_result_max>0) { - cbkptr=&cbk; - cbkres=PhysicsServerSW::_shape_col_cbk; - } - - - for(int i=0;iintersection_query_results[i],p_layer_mask,p_object_type_mask)) - continue; - - const CollisionObjectSW *col_obj=space->intersection_query_results[i]; - int shape_idx=space->intersection_query_subindex_results[i]; - - if (p_exclude.has( col_obj->get_self() )) { - continue; - } - - //print_line("AGAINST: "+itos(col_obj->get_self().get_id())+":"+itos(shape_idx)); - //print_line("THE ABBB: "+(col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).xform(col_obj->get_shape(shape_idx)->get_aabb())); - - if (CollisionSolverSW::solve_static(shape,p_shape_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),cbkres,cbkptr,NULL,p_margin)) { - collided=true; - } - - } - - r_result_count=cbk.amount; - - return collided; - -} - - -struct _RestCallbackData { - - const CollisionObjectSW *object; - const CollisionObjectSW *best_object; - int shape; - int best_shape; - Vector3 best_contact; - Vector3 best_normal; - float best_len; -}; - -static void _rest_cbk_result(const Vector3& p_point_A,const Vector3& p_point_B,void *p_userdata) { - - - _RestCallbackData *rd=(_RestCallbackData*)p_userdata; - - Vector3 contact_rel = p_point_B - p_point_A; - float len = contact_rel.length(); - if (len <= rd->best_len) - return; - - rd->best_len=len; - rd->best_contact=p_point_B; - rd->best_normal=contact_rel/len; - rd->best_object=rd->object; - rd->best_shape=rd->shape; - -} -bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform& p_shape_xform,float p_margin,ShapeRestInfo *r_info, const Set& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) { - - - ShapeSW *shape = static_cast(PhysicsServer::get_singleton())->shape_owner.get(p_shape); - ERR_FAIL_COND_V(!shape,0); - - AABB aabb = p_shape_xform.xform(shape->get_aabb()); - aabb=aabb.grow(p_margin); - - int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); - - _RestCallbackData rcd; - rcd.best_len=0; - rcd.best_object=NULL; - rcd.best_shape=0; - - for(int i=0;iintersection_query_results[i],p_layer_mask,p_object_type_mask)) - continue; - - const CollisionObjectSW *col_obj=space->intersection_query_results[i]; - int shape_idx=space->intersection_query_subindex_results[i]; - - if (p_exclude.has( col_obj->get_self() )) - continue; - - rcd.object=col_obj; - rcd.shape=shape_idx; - bool sc = CollisionSolverSW::solve_static(shape,p_shape_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),_rest_cbk_result,&rcd,NULL,p_margin); - if (!sc) - continue; - - - } - - if (rcd.best_len==0) - return false; - - r_info->collider_id=rcd.best_object->get_instance_id(); - r_info->shape=rcd.best_shape; - r_info->normal=rcd.best_normal; - r_info->point=rcd.best_contact; - r_info->rid=rcd.best_object->get_self(); - if (rcd.best_object->get_type()==CollisionObjectSW::TYPE_BODY) { - - const BodySW *body = static_cast(rcd.best_object); - Vector3 rel_vec = r_info->point-body->get_transform().get_origin(); - r_info->linear_velocity = body->get_linear_velocity() + - (body->get_angular_velocity()).cross(body->get_transform().origin-rcd.best_contact);// * mPos); - - - } else { - r_info->linear_velocity=Vector3(); - } - - return true; -} - - -PhysicsDirectSpaceStateSW::PhysicsDirectSpaceStateSW() { - - - space=NULL; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////// - - - - - - - - - - -void* SpaceSW::_broadphase_pair(CollisionObjectSW *A,int p_subindex_A,CollisionObjectSW *B,int p_subindex_B,void *p_self) { - - CollisionObjectSW::Type type_A=A->get_type(); - CollisionObjectSW::Type type_B=B->get_type(); - if (type_A>type_B) { - - SWAP(A,B); - SWAP(p_subindex_A,p_subindex_B); - SWAP(type_A,type_B); - } - - SpaceSW *self = (SpaceSW*)p_self; - - self->collision_pairs++; - - if (type_A==CollisionObjectSW::TYPE_AREA) { - - AreaSW *area=static_cast(A); - if (type_B==CollisionObjectSW::TYPE_AREA) { - - AreaSW *area_b=static_cast(B); - Area2PairSW *area2_pair = memnew(Area2PairSW(area_b,p_subindex_B,area,p_subindex_A) ); - return area2_pair; - } else { - - BodySW *body=static_cast(B); - AreaPairSW *area_pair = memnew(AreaPairSW(body,p_subindex_B,area,p_subindex_A) ); - return area_pair; - } - } else { - - - BodyPairSW *b = memnew( BodyPairSW((BodySW*)A,p_subindex_A,(BodySW*)B,p_subindex_B) ); - return b; - - } - - return NULL; -} - -void SpaceSW::_broadphase_unpair(CollisionObjectSW *A,int p_subindex_A,CollisionObjectSW *B,int p_subindex_B,void *p_data,void *p_self) { - - - - SpaceSW *self = (SpaceSW*)p_self; - self->collision_pairs--; - ConstraintSW *c = (ConstraintSW*)p_data; - memdelete(c); -} - - -const SelfList::List& SpaceSW::get_active_body_list() const { - - return active_list; -} -void SpaceSW::body_add_to_active_list(SelfList* p_body) { - - active_list.add(p_body); -} -void SpaceSW::body_remove_from_active_list(SelfList* p_body) { - - active_list.remove(p_body); - -} - -void SpaceSW::body_add_to_inertia_update_list(SelfList* p_body) { - - - inertia_update_list.add(p_body); -} - -void SpaceSW::body_remove_from_inertia_update_list(SelfList* p_body) { - - inertia_update_list.remove(p_body); -} - -BroadPhaseSW *SpaceSW::get_broadphase() { - - return broadphase; -} - -void SpaceSW::add_object(CollisionObjectSW *p_object) { - - ERR_FAIL_COND( objects.has(p_object) ); - objects.insert(p_object); -} - -void SpaceSW::remove_object(CollisionObjectSW *p_object) { - - ERR_FAIL_COND( !objects.has(p_object) ); - objects.erase(p_object); -} - -const Set &SpaceSW::get_objects() const { - - return objects; -} - -void SpaceSW::body_add_to_state_query_list(SelfList* p_body) { - - state_query_list.add(p_body); -} -void SpaceSW::body_remove_from_state_query_list(SelfList* p_body) { - - state_query_list.remove(p_body); -} - -void SpaceSW::area_add_to_monitor_query_list(SelfList* p_area) { - - monitor_query_list.add(p_area); -} -void SpaceSW::area_remove_from_monitor_query_list(SelfList* p_area) { - - monitor_query_list.remove(p_area); -} - -void SpaceSW::area_add_to_moved_list(SelfList* p_area) { - - area_moved_list.add(p_area); -} - -void SpaceSW::area_remove_from_moved_list(SelfList* p_area) { - - area_moved_list.remove(p_area); -} - -const SelfList::List& SpaceSW::get_moved_area_list() const { - - return area_moved_list; -} - - - - -void SpaceSW::call_queries() { - - while(state_query_list.first()) { - - BodySW * b = state_query_list.first()->self(); - b->call_queries(); - state_query_list.remove(state_query_list.first()); - } - - while(monitor_query_list.first()) { - - AreaSW * a = monitor_query_list.first()->self(); - a->call_queries(); - monitor_query_list.remove(monitor_query_list.first()); - } - -} - -void SpaceSW::setup() { - - contact_debug_count=0; - while(inertia_update_list.first()) { - inertia_update_list.first()->self()->update_inertias(); - inertia_update_list.remove(inertia_update_list.first()); - } - - -} - -void SpaceSW::update() { - - - broadphase->update(); - -} - - -void SpaceSW::set_param(PhysicsServer::SpaceParameter p_param, real_t p_value) { - - switch(p_param) { - - case PhysicsServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: contact_recycle_radius=p_value; break; - case PhysicsServer::SPACE_PARAM_CONTACT_MAX_SEPARATION: contact_max_separation=p_value; break; - case PhysicsServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: contact_max_allowed_penetration=p_value; break; - case PhysicsServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD: body_linear_velocity_sleep_threshold=p_value; break; - case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD: body_angular_velocity_sleep_threshold=p_value; break; - case PhysicsServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: body_time_to_sleep=p_value; break; - case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: body_angular_velocity_damp_ratio=p_value; break; - case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: constraint_bias=p_value; break; - } -} - -real_t SpaceSW::get_param(PhysicsServer::SpaceParameter p_param) const { - - switch(p_param) { - - case PhysicsServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: return contact_recycle_radius; - case PhysicsServer::SPACE_PARAM_CONTACT_MAX_SEPARATION: return contact_max_separation; - case PhysicsServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: return contact_max_allowed_penetration; - case PhysicsServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD: return body_linear_velocity_sleep_threshold; - case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD: return body_angular_velocity_sleep_threshold; - case PhysicsServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: return body_time_to_sleep; - case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: return body_angular_velocity_damp_ratio; - case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: return constraint_bias; - } - return 0; -} - -void SpaceSW::lock() { - - locked=true; -} - -void SpaceSW::unlock() { - - locked=false; -} - -bool SpaceSW::is_locked() const { - - return locked; -} - -PhysicsDirectSpaceStateSW *SpaceSW::get_direct_state() { - - return direct_access; -} - -SpaceSW::SpaceSW() { - - collision_pairs=0; - active_objects=0; - island_count=0; - contact_debug_count=0; - - locked=false; - contact_recycle_radius=0.01; - contact_max_separation=0.05; - contact_max_allowed_penetration= 0.01; - - constraint_bias = 0.01; - body_linear_velocity_sleep_threshold=GLOBAL_DEF("physics/sleep_threshold_linear",0.1); - body_angular_velocity_sleep_threshold=GLOBAL_DEF("physics/sleep_threshold_angular", (8.0 / 180.0 * Math_PI) ); - body_time_to_sleep=0.5; - body_angular_velocity_damp_ratio=10; - - - broadphase = BroadPhaseSW::create_func(); - broadphase->set_pair_callback(_broadphase_pair,this); - broadphase->set_unpair_callback(_broadphase_unpair,this); - area=NULL; - - direct_access = memnew( PhysicsDirectSpaceStateSW ); - direct_access->space=this; -} - -SpaceSW::~SpaceSW() { - - memdelete(broadphase); - memdelete( direct_access ); -} - - - +/*************************************************************************/ +/* space_sw.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "globals.h" +#include "space_sw.h" +#include "collision_solver_sw.h" +#include "physics_server_sw.h" + + +_FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object, uint32_t p_layer_mask, uint32_t p_type_mask) { + + if ((p_object->get_layer_mask()&p_layer_mask)==0) + return false; + + if (p_object->get_type()==CollisionObjectSW::TYPE_AREA && !(p_type_mask&PhysicsDirectSpaceState::TYPE_MASK_AREA)) + return false; + + BodySW *body = static_cast(p_object); + + return (1<get_mode())&p_type_mask; + +} + + +bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3& p_from, const Vector3& p_to,RayResult &r_result,const Set& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) { + + + ERR_FAIL_COND_V(space->locked,false); + + Vector3 begin,end; + Vector3 normal; + begin=p_from; + end=p_to; + normal=(end-begin).normalized(); + + + int amount = space->broadphase->cull_segment(begin,end,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); + + + //todo, create another array tha references results, compute AABBs and check closest point to ray origin, sort, and stop evaluating results when beyond first collision + + bool collided=false; + Vector3 res_point,res_normal; + int res_shape; + const CollisionObjectSW *res_obj; + real_t min_d=1e10; + + + + for(int i=0;iintersection_query_results[i],p_layer_mask,p_object_type_mask)) + continue; + + if (!(static_cast(space->intersection_query_results[i])->is_ray_pickable())) + continue; + + if (p_exclude.has( space->intersection_query_results[i]->get_self())) + continue; + + const CollisionObjectSW *col_obj=space->intersection_query_results[i]; + + int shape_idx=space->intersection_query_subindex_results[i]; + Transform inv_xform = col_obj->get_shape_inv_transform(shape_idx) * col_obj->get_inv_transform(); + + Vector3 local_from = inv_xform.xform(begin); + Vector3 local_to = inv_xform.xform(end); + + const ShapeSW *shape = col_obj->get_shape(shape_idx); + + Vector3 shape_point,shape_normal; + + + if (shape->intersect_segment(local_from,local_to,shape_point,shape_normal)) { + + + + Transform xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); + shape_point=xform.xform(shape_point); + + real_t ld = normal.dot(shape_point); + + + if (ldget_instance_id(); + if (r_result.collider_id!=0) + r_result.collider=ObjectDB::get_instance(r_result.collider_id); + else + r_result.collider=NULL; + r_result.normal=res_normal; + r_result.position=res_point; + r_result.rid=res_obj->get_self(); + r_result.shape=res_shape; + + return true; + +} + + +int PhysicsDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Transform& p_xform,float p_margin,ShapeResult *r_results,int p_result_max,const Set& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) { + + if (p_result_max<=0) + return 0; + + ShapeSW *shape = static_cast(PhysicsServer::get_singleton())->shape_owner.get(p_shape); + ERR_FAIL_COND_V(!shape,0); + + AABB aabb = p_xform.xform(shape->get_aabb()); + + int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); + + bool collided=false; + int cc=0; + + //Transform ai = p_xform.affine_inverse(); + + for(int i=0;i=p_result_max) + break; + + if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask)) + continue; + + //area cant be picked by ray (default) + + if (p_exclude.has( space->intersection_query_results[i]->get_self())) + continue; + + + const CollisionObjectSW *col_obj=space->intersection_query_results[i]; + int shape_idx=space->intersection_query_subindex_results[i]; + + if (!CollisionSolverSW::solve_static(shape,p_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), NULL,NULL,NULL,p_margin,0)) + continue; + + r_results[cc].collider_id=col_obj->get_instance_id(); + if (r_results[cc].collider_id!=0) + r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id); + else + r_results[cc].collider=NULL; + r_results[cc].rid=col_obj->get_self(); + r_results[cc].shape=shape_idx; + + cc++; + + } + + return cc; + +} + + +bool PhysicsDirectSpaceStateSW::cast_motion(const RID& p_shape, const Transform& p_xform,const Vector3& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask,ShapeRestInfo *r_info) { + + + + ShapeSW *shape = static_cast(PhysicsServer::get_singleton())->shape_owner.get(p_shape); + ERR_FAIL_COND_V(!shape,false); + + AABB aabb = p_xform.xform(shape->get_aabb()); + aabb=aabb.merge(AABB(aabb.pos+p_motion,aabb.size)); //motion + aabb=aabb.grow(p_margin); + + //if (p_motion!=Vector3()) + // print_line(p_motion); + + int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); + + float best_safe=1; + float best_unsafe=1; + + Transform xform_inv = p_xform.affine_inverse(); + MotionShapeSW mshape; + mshape.shape=shape; + mshape.motion=xform_inv.basis.xform(p_motion); + + bool best_first=true; + + Vector3 closest_A,closest_B; + + for(int i=0;iintersection_query_results[i],p_layer_mask,p_object_type_mask)) + continue; + + if (p_exclude.has( space->intersection_query_results[i]->get_self())) + continue; //ignore excluded + + + const CollisionObjectSW *col_obj=space->intersection_query_results[i]; + int shape_idx=space->intersection_query_subindex_results[i]; + + Vector3 point_A,point_B; + Vector3 sep_axis=p_motion.normalized(); + + Transform col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); + //test initial overlap, does it collide if going all the way? + if (CollisionSolverSW::solve_distance(&mshape,p_xform,col_obj->get_shape(shape_idx),col_obj_xform,point_A,point_B,aabb,&sep_axis)) { + //print_line("failed motion cast (no collision)"); + continue; + } + + + //test initial overlap +#if 0 + if (CollisionSolverSW::solve_static(shape,p_xform,col_obj->get_shape(shape_idx),col_obj_xform,NULL,NULL,&sep_axis)) { + print_line("failed initial cast (collision at begining)"); + return false; + } +#else + sep_axis=p_motion.normalized(); + + if (!CollisionSolverSW::solve_distance(shape,p_xform,col_obj->get_shape(shape_idx),col_obj_xform,point_A,point_B,aabb,&sep_axis)) { + //print_line("failed motion cast (no collision)"); + return false; + } +#endif + + + //just do kinematic solving + float low=0; + float hi=1; + Vector3 mnormal=p_motion.normalized(); + + for(int i=0;i<8;i++) { //steps should be customizable.. + + Transform xfa = p_xform; + float ofs = (low+hi)*0.5; + + Vector3 sep=mnormal; //important optimization for this to work fast enough + + mshape.motion=xform_inv.basis.xform(p_motion*ofs); + + Vector3 lA,lB; + + bool collided = !CollisionSolverSW::solve_distance(&mshape,p_xform,col_obj->get_shape(shape_idx),col_obj_xform,lA,lB,aabb,&sep); + + if (collided) { + + //print_line(itos(i)+": "+rtos(ofs)); + hi=ofs; + } else { + + point_A=lA; + point_B=lB; + low=ofs; + } + } + + if (lowcollider_id=col_obj->get_instance_id(); + r_info->rid=col_obj->get_self(); + r_info->shape=shape_idx; + r_info->point=closest_B; + r_info->normal=(closest_A-closest_B).normalized(); + best_first=false; + if (col_obj->get_type()==CollisionObjectSW::TYPE_BODY) { + const BodySW *body=static_cast(col_obj); + r_info->linear_velocity= body->get_linear_velocity() + (body->get_angular_velocity()).cross(body->get_transform().origin - closest_B); + } + + } + + + } + + p_closest_safe=best_safe; + p_closest_unsafe=best_unsafe; + + return true; +} + +bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform& p_shape_xform,float p_margin,Vector3 *r_results,int p_result_max,int &r_result_count, const Set& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask){ + + if (p_result_max<=0) + return 0; + + ShapeSW *shape = static_cast(PhysicsServer::get_singleton())->shape_owner.get(p_shape); + ERR_FAIL_COND_V(!shape,0); + + AABB aabb = p_shape_xform.xform(shape->get_aabb()); + aabb=aabb.grow(p_margin); + + int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); + + bool collided=false; + int cc=0; + r_result_count=0; + + PhysicsServerSW::CollCbkData cbk; + cbk.max=p_result_max; + cbk.amount=0; + cbk.ptr=r_results; + CollisionSolverSW::CallbackResult cbkres=NULL; + + PhysicsServerSW::CollCbkData *cbkptr=NULL; + if (p_result_max>0) { + cbkptr=&cbk; + cbkres=PhysicsServerSW::_shape_col_cbk; + } + + + for(int i=0;iintersection_query_results[i],p_layer_mask,p_object_type_mask)) + continue; + + const CollisionObjectSW *col_obj=space->intersection_query_results[i]; + int shape_idx=space->intersection_query_subindex_results[i]; + + if (p_exclude.has( col_obj->get_self() )) { + continue; + } + + //print_line("AGAINST: "+itos(col_obj->get_self().get_id())+":"+itos(shape_idx)); + //print_line("THE ABBB: "+(col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).xform(col_obj->get_shape(shape_idx)->get_aabb())); + + if (CollisionSolverSW::solve_static(shape,p_shape_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),cbkres,cbkptr,NULL,p_margin)) { + collided=true; + } + + } + + r_result_count=cbk.amount; + + return collided; + +} + + +struct _RestCallbackData { + + const CollisionObjectSW *object; + const CollisionObjectSW *best_object; + int shape; + int best_shape; + Vector3 best_contact; + Vector3 best_normal; + float best_len; +}; + +static void _rest_cbk_result(const Vector3& p_point_A,const Vector3& p_point_B,void *p_userdata) { + + + _RestCallbackData *rd=(_RestCallbackData*)p_userdata; + + Vector3 contact_rel = p_point_B - p_point_A; + float len = contact_rel.length(); + if (len <= rd->best_len) + return; + + rd->best_len=len; + rd->best_contact=p_point_B; + rd->best_normal=contact_rel/len; + rd->best_object=rd->object; + rd->best_shape=rd->shape; + +} +bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform& p_shape_xform,float p_margin,ShapeRestInfo *r_info, const Set& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) { + + + ShapeSW *shape = static_cast(PhysicsServer::get_singleton())->shape_owner.get(p_shape); + ERR_FAIL_COND_V(!shape,0); + + AABB aabb = p_shape_xform.xform(shape->get_aabb()); + aabb=aabb.grow(p_margin); + + int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,SpaceSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); + + _RestCallbackData rcd; + rcd.best_len=0; + rcd.best_object=NULL; + rcd.best_shape=0; + + for(int i=0;iintersection_query_results[i],p_layer_mask,p_object_type_mask)) + continue; + + const CollisionObjectSW *col_obj=space->intersection_query_results[i]; + int shape_idx=space->intersection_query_subindex_results[i]; + + if (p_exclude.has( col_obj->get_self() )) + continue; + + rcd.object=col_obj; + rcd.shape=shape_idx; + bool sc = CollisionSolverSW::solve_static(shape,p_shape_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),_rest_cbk_result,&rcd,NULL,p_margin); + if (!sc) + continue; + + + } + + if (rcd.best_len==0) + return false; + + r_info->collider_id=rcd.best_object->get_instance_id(); + r_info->shape=rcd.best_shape; + r_info->normal=rcd.best_normal; + r_info->point=rcd.best_contact; + r_info->rid=rcd.best_object->get_self(); + if (rcd.best_object->get_type()==CollisionObjectSW::TYPE_BODY) { + + const BodySW *body = static_cast(rcd.best_object); + Vector3 rel_vec = r_info->point-body->get_transform().get_origin(); + r_info->linear_velocity = body->get_linear_velocity() + + (body->get_angular_velocity()).cross(body->get_transform().origin-rcd.best_contact);// * mPos); + + + } else { + r_info->linear_velocity=Vector3(); + } + + return true; +} + + +PhysicsDirectSpaceStateSW::PhysicsDirectSpaceStateSW() { + + + space=NULL; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + + + + + + +void* SpaceSW::_broadphase_pair(CollisionObjectSW *A,int p_subindex_A,CollisionObjectSW *B,int p_subindex_B,void *p_self) { + + CollisionObjectSW::Type type_A=A->get_type(); + CollisionObjectSW::Type type_B=B->get_type(); + if (type_A>type_B) { + + SWAP(A,B); + SWAP(p_subindex_A,p_subindex_B); + SWAP(type_A,type_B); + } + + SpaceSW *self = (SpaceSW*)p_self; + + self->collision_pairs++; + + if (type_A==CollisionObjectSW::TYPE_AREA) { + + AreaSW *area=static_cast(A); + if (type_B==CollisionObjectSW::TYPE_AREA) { + + AreaSW *area_b=static_cast(B); + Area2PairSW *area2_pair = memnew(Area2PairSW(area_b,p_subindex_B,area,p_subindex_A) ); + return area2_pair; + } else { + + BodySW *body=static_cast(B); + AreaPairSW *area_pair = memnew(AreaPairSW(body,p_subindex_B,area,p_subindex_A) ); + return area_pair; + } + } else { + + + BodyPairSW *b = memnew( BodyPairSW((BodySW*)A,p_subindex_A,(BodySW*)B,p_subindex_B) ); + return b; + + } + + return NULL; +} + +void SpaceSW::_broadphase_unpair(CollisionObjectSW *A,int p_subindex_A,CollisionObjectSW *B,int p_subindex_B,void *p_data,void *p_self) { + + + + SpaceSW *self = (SpaceSW*)p_self; + self->collision_pairs--; + ConstraintSW *c = (ConstraintSW*)p_data; + memdelete(c); +} + + +const SelfList::List& SpaceSW::get_active_body_list() const { + + return active_list; +} +void SpaceSW::body_add_to_active_list(SelfList* p_body) { + + active_list.add(p_body); +} +void SpaceSW::body_remove_from_active_list(SelfList* p_body) { + + active_list.remove(p_body); + +} + +void SpaceSW::body_add_to_inertia_update_list(SelfList* p_body) { + + + inertia_update_list.add(p_body); +} + +void SpaceSW::body_remove_from_inertia_update_list(SelfList* p_body) { + + inertia_update_list.remove(p_body); +} + +BroadPhaseSW *SpaceSW::get_broadphase() { + + return broadphase; +} + +void SpaceSW::add_object(CollisionObjectSW *p_object) { + + ERR_FAIL_COND( objects.has(p_object) ); + objects.insert(p_object); +} + +void SpaceSW::remove_object(CollisionObjectSW *p_object) { + + ERR_FAIL_COND( !objects.has(p_object) ); + objects.erase(p_object); +} + +const Set &SpaceSW::get_objects() const { + + return objects; +} + +void SpaceSW::body_add_to_state_query_list(SelfList* p_body) { + + state_query_list.add(p_body); +} +void SpaceSW::body_remove_from_state_query_list(SelfList* p_body) { + + state_query_list.remove(p_body); +} + +void SpaceSW::area_add_to_monitor_query_list(SelfList* p_area) { + + monitor_query_list.add(p_area); +} +void SpaceSW::area_remove_from_monitor_query_list(SelfList* p_area) { + + monitor_query_list.remove(p_area); +} + +void SpaceSW::area_add_to_moved_list(SelfList* p_area) { + + area_moved_list.add(p_area); +} + +void SpaceSW::area_remove_from_moved_list(SelfList* p_area) { + + area_moved_list.remove(p_area); +} + +const SelfList::List& SpaceSW::get_moved_area_list() const { + + return area_moved_list; +} + + + + +void SpaceSW::call_queries() { + + while(state_query_list.first()) { + + BodySW * b = state_query_list.first()->self(); + b->call_queries(); + state_query_list.remove(state_query_list.first()); + } + + while(monitor_query_list.first()) { + + AreaSW * a = monitor_query_list.first()->self(); + a->call_queries(); + monitor_query_list.remove(monitor_query_list.first()); + } + +} + +void SpaceSW::setup() { + + contact_debug_count=0; + while(inertia_update_list.first()) { + inertia_update_list.first()->self()->update_inertias(); + inertia_update_list.remove(inertia_update_list.first()); + } + + +} + +void SpaceSW::update() { + + + broadphase->update(); + +} + + +void SpaceSW::set_param(PhysicsServer::SpaceParameter p_param, real_t p_value) { + + switch(p_param) { + + case PhysicsServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: contact_recycle_radius=p_value; break; + case PhysicsServer::SPACE_PARAM_CONTACT_MAX_SEPARATION: contact_max_separation=p_value; break; + case PhysicsServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: contact_max_allowed_penetration=p_value; break; + case PhysicsServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD: body_linear_velocity_sleep_threshold=p_value; break; + case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD: body_angular_velocity_sleep_threshold=p_value; break; + case PhysicsServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: body_time_to_sleep=p_value; break; + case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: body_angular_velocity_damp_ratio=p_value; break; + case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: constraint_bias=p_value; break; + } +} + +real_t SpaceSW::get_param(PhysicsServer::SpaceParameter p_param) const { + + switch(p_param) { + + case PhysicsServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: return contact_recycle_radius; + case PhysicsServer::SPACE_PARAM_CONTACT_MAX_SEPARATION: return contact_max_separation; + case PhysicsServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: return contact_max_allowed_penetration; + case PhysicsServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD: return body_linear_velocity_sleep_threshold; + case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD: return body_angular_velocity_sleep_threshold; + case PhysicsServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: return body_time_to_sleep; + case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: return body_angular_velocity_damp_ratio; + case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: return constraint_bias; + } + return 0; +} + +void SpaceSW::lock() { + + locked=true; +} + +void SpaceSW::unlock() { + + locked=false; +} + +bool SpaceSW::is_locked() const { + + return locked; +} + +PhysicsDirectSpaceStateSW *SpaceSW::get_direct_state() { + + return direct_access; +} + +SpaceSW::SpaceSW() { + + collision_pairs=0; + active_objects=0; + island_count=0; + contact_debug_count=0; + + locked=false; + contact_recycle_radius=0.01; + contact_max_separation=0.05; + contact_max_allowed_penetration= 0.01; + + constraint_bias = 0.01; + body_linear_velocity_sleep_threshold=GLOBAL_DEF("physics/sleep_threshold_linear",0.1); + body_angular_velocity_sleep_threshold=GLOBAL_DEF("physics/sleep_threshold_angular", (8.0 / 180.0 * Math_PI) ); + body_time_to_sleep=0.5; + body_angular_velocity_damp_ratio=10; + + + broadphase = BroadPhaseSW::create_func(); + broadphase->set_pair_callback(_broadphase_pair,this); + broadphase->set_unpair_callback(_broadphase_unpair,this); + area=NULL; + + direct_access = memnew( PhysicsDirectSpaceStateSW ); + direct_access->space=this; +} + +SpaceSW::~SpaceSW() { + + memdelete(broadphase); + memdelete( direct_access ); +} + + + diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h index e88f61d881..ac788ba93f 100644 --- a/servers/physics/space_sw.h +++ b/servers/physics/space_sw.h @@ -1,187 +1,187 @@ -/*************************************************************************/ -/* space_sw.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef SPACE_SW_H -#define SPACE_SW_H - -#include "typedefs.h" -#include "hash_map.h" -#include "body_sw.h" -#include "area_sw.h" -#include "body_pair_sw.h" -#include "area_pair_sw.h" -#include "broad_phase_sw.h" -#include "collision_object_sw.h" - - -class PhysicsDirectSpaceStateSW : public PhysicsDirectSpaceState { - - OBJ_TYPE( PhysicsDirectSpaceStateSW, PhysicsDirectSpaceState ); -public: - - SpaceSW *space; - - virtual bool intersect_ray(const Vector3& p_from, const Vector3& p_to,RayResult &r_result,const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); - virtual int intersect_shape(const RID& p_shape, const Transform& p_xform,float p_margin,ShapeResult *r_results,int p_result_max,const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); - virtual bool cast_motion(const RID& p_shape, const Transform& p_xform,const Vector3& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION,ShapeRestInfo *r_info=NULL); - virtual bool collide_shape(RID p_shape, const Transform& p_shape_xform,float p_margin,Vector3 *r_results,int p_result_max,int &r_result_count, const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); - virtual bool rest_info(RID p_shape, const Transform& p_shape_xform,float p_margin,ShapeRestInfo *r_info, const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); - - PhysicsDirectSpaceStateSW(); -}; - - - -class SpaceSW { - - - PhysicsDirectSpaceStateSW *direct_access; - RID self; - - BroadPhaseSW *broadphase; - SelfList::List active_list; - SelfList::List inertia_update_list; - SelfList::List state_query_list; - SelfList::List monitor_query_list; - SelfList::List area_moved_list; - - static void* _broadphase_pair(CollisionObjectSW *A,int p_subindex_A,CollisionObjectSW *B,int p_subindex_B,void *p_self); - static void _broadphase_unpair(CollisionObjectSW *A,int p_subindex_A,CollisionObjectSW *B,int p_subindex_B,void *p_data,void *p_self); - - Set objects; - - AreaSW *area; - - real_t contact_recycle_radius; - real_t contact_max_separation; - real_t contact_max_allowed_penetration; - real_t constraint_bias; - - enum { - - INTERSECTION_QUERY_MAX=2048 - }; - - CollisionObjectSW *intersection_query_results[INTERSECTION_QUERY_MAX]; - int intersection_query_subindex_results[INTERSECTION_QUERY_MAX]; - - float body_linear_velocity_sleep_threshold; - float body_angular_velocity_sleep_threshold; - float body_time_to_sleep; - float body_angular_velocity_damp_ratio; - - bool locked; - - int island_count; - int active_objects; - int collision_pairs; - - RID static_global_body; - - Vector contact_debug; - int contact_debug_count; - -friend class PhysicsDirectSpaceStateSW; - -public: - - _FORCE_INLINE_ void set_self(const RID& p_self) { self=p_self; } - _FORCE_INLINE_ RID get_self() const { return self; } - - void set_default_area(AreaSW *p_area) { area=p_area; } - AreaSW *get_default_area() const { return area; } - - const SelfList::List& get_active_body_list() const; - void body_add_to_active_list(SelfList* p_body); - void body_remove_from_active_list(SelfList* p_body); - void body_add_to_inertia_update_list(SelfList* p_body); - void body_remove_from_inertia_update_list(SelfList* p_body); - - void body_add_to_state_query_list(SelfList* p_body); - void body_remove_from_state_query_list(SelfList* p_body); - - void area_add_to_monitor_query_list(SelfList* p_area); - void area_remove_from_monitor_query_list(SelfList* p_area); - void area_add_to_moved_list(SelfList* p_area); - void area_remove_from_moved_list(SelfList* p_area); - const SelfList::List& get_moved_area_list() const; - - BroadPhaseSW *get_broadphase(); - - void add_object(CollisionObjectSW *p_object); - void remove_object(CollisionObjectSW *p_object); - const Set &get_objects() const; - - _FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; } - _FORCE_INLINE_ real_t get_contact_max_separation() const { return contact_max_separation; } - _FORCE_INLINE_ real_t get_contact_max_allowed_penetration() const { return contact_max_allowed_penetration; } - _FORCE_INLINE_ real_t get_constraint_bias() const { return constraint_bias; } - _FORCE_INLINE_ real_t get_body_linear_velocity_sleep_treshold() const { return body_linear_velocity_sleep_threshold; } - _FORCE_INLINE_ real_t get_body_angular_velocity_sleep_treshold() const { return body_angular_velocity_sleep_threshold; } - _FORCE_INLINE_ real_t get_body_time_to_sleep() const { return body_time_to_sleep; } - _FORCE_INLINE_ real_t get_body_angular_velocity_damp_ratio() const { return body_angular_velocity_damp_ratio; } - - - void update(); - void setup(); - void call_queries(); - - - bool is_locked() const; - void lock(); - void unlock(); - - void set_param(PhysicsServer::SpaceParameter p_param, real_t p_value); - real_t get_param(PhysicsServer::SpaceParameter p_param) const; - - void set_island_count(int p_island_count) { island_count=p_island_count; } - int get_island_count() const { return island_count; } - - void set_active_objects(int p_active_objects) { active_objects=p_active_objects; } - int get_active_objects() const { return active_objects; } - - int get_collision_pairs() const { return collision_pairs; } - - PhysicsDirectSpaceStateSW *get_direct_state(); - - void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); } - _FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); } - _FORCE_INLINE_ void add_debug_contact(const Vector3& p_contact) { if (contact_debug_count get_debug_contacts() { return contact_debug; } - _FORCE_INLINE_ int get_debug_contact_count() { return contact_debug_count; } - - void set_static_global_body(RID p_body) { static_global_body=p_body; } - RID get_static_global_body() { return static_global_body; } - - - SpaceSW(); - ~SpaceSW(); -}; - - -#endif // SPACE__SW_H +/*************************************************************************/ +/* space_sw.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef SPACE_SW_H +#define SPACE_SW_H + +#include "typedefs.h" +#include "hash_map.h" +#include "body_sw.h" +#include "area_sw.h" +#include "body_pair_sw.h" +#include "area_pair_sw.h" +#include "broad_phase_sw.h" +#include "collision_object_sw.h" + + +class PhysicsDirectSpaceStateSW : public PhysicsDirectSpaceState { + + OBJ_TYPE( PhysicsDirectSpaceStateSW, PhysicsDirectSpaceState ); +public: + + SpaceSW *space; + + virtual bool intersect_ray(const Vector3& p_from, const Vector3& p_to,RayResult &r_result,const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); + virtual int intersect_shape(const RID& p_shape, const Transform& p_xform,float p_margin,ShapeResult *r_results,int p_result_max,const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); + virtual bool cast_motion(const RID& p_shape, const Transform& p_xform,const Vector3& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION,ShapeRestInfo *r_info=NULL); + virtual bool collide_shape(RID p_shape, const Transform& p_shape_xform,float p_margin,Vector3 *r_results,int p_result_max,int &r_result_count, const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); + virtual bool rest_info(RID p_shape, const Transform& p_shape_xform,float p_margin,ShapeRestInfo *r_info, const Set& p_exclude=Set(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); + + PhysicsDirectSpaceStateSW(); +}; + + + +class SpaceSW { + + + PhysicsDirectSpaceStateSW *direct_access; + RID self; + + BroadPhaseSW *broadphase; + SelfList::List active_list; + SelfList::List inertia_update_list; + SelfList::List state_query_list; + SelfList::List monitor_query_list; + SelfList::List area_moved_list; + + static void* _broadphase_pair(CollisionObjectSW *A,int p_subindex_A,CollisionObjectSW *B,int p_subindex_B,void *p_self); + static void _broadphase_unpair(CollisionObjectSW *A,int p_subindex_A,CollisionObjectSW *B,int p_subindex_B,void *p_data,void *p_self); + + Set objects; + + AreaSW *area; + + real_t contact_recycle_radius; + real_t contact_max_separation; + real_t contact_max_allowed_penetration; + real_t constraint_bias; + + enum { + + INTERSECTION_QUERY_MAX=2048 + }; + + CollisionObjectSW *intersection_query_results[INTERSECTION_QUERY_MAX]; + int intersection_query_subindex_results[INTERSECTION_QUERY_MAX]; + + float body_linear_velocity_sleep_threshold; + float body_angular_velocity_sleep_threshold; + float body_time_to_sleep; + float body_angular_velocity_damp_ratio; + + bool locked; + + int island_count; + int active_objects; + int collision_pairs; + + RID static_global_body; + + Vector contact_debug; + int contact_debug_count; + +friend class PhysicsDirectSpaceStateSW; + +public: + + _FORCE_INLINE_ void set_self(const RID& p_self) { self=p_self; } + _FORCE_INLINE_ RID get_self() const { return self; } + + void set_default_area(AreaSW *p_area) { area=p_area; } + AreaSW *get_default_area() const { return area; } + + const SelfList::List& get_active_body_list() const; + void body_add_to_active_list(SelfList* p_body); + void body_remove_from_active_list(SelfList* p_body); + void body_add_to_inertia_update_list(SelfList* p_body); + void body_remove_from_inertia_update_list(SelfList* p_body); + + void body_add_to_state_query_list(SelfList* p_body); + void body_remove_from_state_query_list(SelfList* p_body); + + void area_add_to_monitor_query_list(SelfList* p_area); + void area_remove_from_monitor_query_list(SelfList* p_area); + void area_add_to_moved_list(SelfList* p_area); + void area_remove_from_moved_list(SelfList* p_area); + const SelfList::List& get_moved_area_list() const; + + BroadPhaseSW *get_broadphase(); + + void add_object(CollisionObjectSW *p_object); + void remove_object(CollisionObjectSW *p_object); + const Set &get_objects() const; + + _FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; } + _FORCE_INLINE_ real_t get_contact_max_separation() const { return contact_max_separation; } + _FORCE_INLINE_ real_t get_contact_max_allowed_penetration() const { return contact_max_allowed_penetration; } + _FORCE_INLINE_ real_t get_constraint_bias() const { return constraint_bias; } + _FORCE_INLINE_ real_t get_body_linear_velocity_sleep_treshold() const { return body_linear_velocity_sleep_threshold; } + _FORCE_INLINE_ real_t get_body_angular_velocity_sleep_treshold() const { return body_angular_velocity_sleep_threshold; } + _FORCE_INLINE_ real_t get_body_time_to_sleep() const { return body_time_to_sleep; } + _FORCE_INLINE_ real_t get_body_angular_velocity_damp_ratio() const { return body_angular_velocity_damp_ratio; } + + + void update(); + void setup(); + void call_queries(); + + + bool is_locked() const; + void lock(); + void unlock(); + + void set_param(PhysicsServer::SpaceParameter p_param, real_t p_value); + real_t get_param(PhysicsServer::SpaceParameter p_param) const; + + void set_island_count(int p_island_count) { island_count=p_island_count; } + int get_island_count() const { return island_count; } + + void set_active_objects(int p_active_objects) { active_objects=p_active_objects; } + int get_active_objects() const { return active_objects; } + + int get_collision_pairs() const { return collision_pairs; } + + PhysicsDirectSpaceStateSW *get_direct_state(); + + void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); } + _FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); } + _FORCE_INLINE_ void add_debug_contact(const Vector3& p_contact) { if (contact_debug_count get_debug_contacts() { return contact_debug; } + _FORCE_INLINE_ int get_debug_contact_count() { return contact_debug_count; } + + void set_static_global_body(RID p_body) { static_global_body=p_body; } + RID get_static_global_body() { return static_global_body; } + + + SpaceSW(); + ~SpaceSW(); +}; + + +#endif // SPACE__SW_H -- cgit v1.2.3 From 13ff4bde650149577185d6d4c61b924cf0896d98 Mon Sep 17 00:00:00 2001 From: eska Date: Fri, 9 Oct 2015 21:54:16 +0200 Subject: Fix Area2D type mask matching --- servers/physics_2d/space_2d_sw.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'servers') diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index a71e6c4bf5..9f2f03baec 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -36,8 +36,8 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_objec if ((p_object->get_layer_mask()&p_layer_mask)==0) return false; - if (p_object->get_type()==CollisionObject2DSW::TYPE_AREA && !(p_type_mask&Physics2DDirectSpaceState::TYPE_MASK_AREA)) - return false; + if (p_object->get_type()==CollisionObject2DSW::TYPE_AREA) + return p_type_mask&Physics2DDirectSpaceState::TYPE_MASK_AREA; Body2DSW *body = static_cast(p_object); -- cgit v1.2.3 From 375a7a727f215a1d790de9caf82cb2a5e89cf711 Mon Sep 17 00:00:00 2001 From: eska Date: Sat, 10 Oct 2015 02:33:26 +0200 Subject: Fix 3D Area mask matching --- servers/physics/space_sw.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'servers') diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index d36b004989..ba1c737530 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -34,10 +34,10 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object, uint32_t p_layer_mask, uint32_t p_type_mask) { - if ((p_object->get_layer_mask()&p_layer_mask)==0) - return false; + if (p_object->get_type()==CollisionObjectSW::TYPE_AREA) + return p_type_mask&PhysicsDirectSpaceState::TYPE_MASK_AREA; - if (p_object->get_type()==CollisionObjectSW::TYPE_AREA && !(p_type_mask&PhysicsDirectSpaceState::TYPE_MASK_AREA)) + if ((p_object->get_layer_mask()&p_layer_mask)==0) return false; BodySW *body = static_cast(p_object); -- cgit v1.2.3 From 2ffc90d8b4d3f420e57adefbc880183ac0635a7e Mon Sep 17 00:00:00 2001 From: Biliogadafr Date: Sat, 10 Oct 2015 23:28:05 +0300 Subject: Expose softness parameter of pin joint to the editor. --- servers/physics_2d/joints_2d_sw.cpp | 12 ++++++++++++ servers/physics_2d/joints_2d_sw.h | 2 ++ servers/physics_2d/physics_2d_server_sw.cpp | 19 +++++++++++++++++++ servers/physics_2d/physics_2d_server_sw.h | 2 ++ servers/physics_2d/physics_2d_server_wrap_mt.h | 3 +++ servers/physics_2d_server.h | 7 +++++++ 6 files changed, 45 insertions(+) (limited to 'servers') diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/joints_2d_sw.cpp index b4c149e7e0..7c12000084 100644 --- a/servers/physics_2d/joints_2d_sw.cpp +++ b/servers/physics_2d/joints_2d_sw.cpp @@ -279,6 +279,18 @@ void PinJoint2DSW::solve(float p_step){ P += impulse; } +void PinJoint2DSW::set_param(Physics2DServer::PinJointParam p_param, real_t p_value) { + + if(p_param == Physics2DServer::PIN_JOINT_SOFTNESS) + softness = p_value; +} + +real_t PinJoint2DSW::get_param(Physics2DServer::PinJointParam p_param) const { + + if(p_param == Physics2DServer::PIN_JOINT_SOFTNESS) + return softness; + ERR_FAIL_V(0); +} PinJoint2DSW::PinJoint2DSW(const Vector2& p_pos,Body2DSW* p_body_a,Body2DSW* p_body_b) : Joint2DSW(_arr,p_body_b?2:1) { diff --git a/servers/physics_2d/joints_2d_sw.h b/servers/physics_2d/joints_2d_sw.h index 2093be88c9..e43f8eee33 100644 --- a/servers/physics_2d/joints_2d_sw.h +++ b/servers/physics_2d/joints_2d_sw.h @@ -121,6 +121,8 @@ public: virtual bool setup(float p_step); virtual void solve(float p_step); + void set_param(Physics2DServer::PinJointParam p_param, real_t p_value); + real_t get_param(Physics2DServer::PinJointParam p_param) const; PinJoint2DSW(const Vector2& p_pos,Body2DSW* p_body_a,Body2DSW* p_body_b=NULL); ~PinJoint2DSW(); diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index 14b4c09ebc..6a1c790da8 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -1096,6 +1096,25 @@ RID Physics2DServerSW::damped_spring_joint_create(const Vector2& p_anchor_a,cons } +void Physics2DServerSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { + + Joint2DSW *j = joint_owner.get(p_joint); + ERR_FAIL_COND(!j); + ERR_FAIL_COND(j->get_type()!=JOINT_PIN); + + PinJoint2DSW *pin_joint = static_cast(j); + pin_joint->set_param(p_param, p_value); +} + +real_t Physics2DServerSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { + Joint2DSW *j = joint_owner.get(p_joint); + ERR_FAIL_COND_V(!j,0); + ERR_FAIL_COND_V(j->get_type()!=JOINT_PIN,0); + + PinJoint2DSW *pin_joint = static_cast(j); + return pin_joint->get_param(p_param); +} + void Physics2DServerSW::damped_string_joint_set_param(RID p_joint, DampedStringParam p_param, real_t p_value) { diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index 605e04ead8..b2c58b788e 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -243,6 +243,8 @@ public: virtual RID pin_joint_create(const Vector2& p_pos,RID p_body_a,RID p_body_b=RID()); virtual RID groove_joint_create(const Vector2& p_a_groove1,const Vector2& p_a_groove2, const Vector2& p_b_anchor, RID p_body_a,RID p_body_b); virtual RID damped_spring_joint_create(const Vector2& p_anchor_a,const Vector2& p_anchor_b,RID p_body_a,RID p_body_b=RID()); + virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value); + virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const; virtual void damped_string_joint_set_param(RID p_joint, DampedStringParam p_param, real_t p_value); virtual real_t damped_string_joint_get_param(RID p_joint, DampedStringParam p_param) const; diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h index 54af3eeb99..60f8a4c879 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.h +++ b/servers/physics_2d/physics_2d_server_wrap_mt.h @@ -258,6 +258,9 @@ public: FUNC5R(RID,groove_joint_create,const Vector2&,const Vector2&,const Vector2&,RID,RID); FUNC4R(RID,damped_spring_joint_create,const Vector2&,const Vector2&,RID,RID); + FUNC3(pin_joint_set_param,RID,PinJointParam,real_t); + FUNC2RC(real_t,pin_joint_get_param,RID,PinJointParam); + FUNC3(damped_string_joint_set_param,RID,DampedStringParam,real_t); FUNC2RC(real_t,damped_string_joint_get_param,RID,DampedStringParam); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 2d70337dc8..6845c7dfe1 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -516,6 +516,13 @@ public: virtual RID groove_joint_create(const Vector2& p_a_groove1,const Vector2& p_a_groove2, const Vector2& p_b_anchor, RID p_body_a,RID p_body_b)=0; virtual RID damped_spring_joint_create(const Vector2& p_anchor_a,const Vector2& p_anchor_b,RID p_body_a,RID p_body_b=RID())=0; + enum PinJointParam { + PIN_JOINT_SOFTNESS + }; + + virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value)=0; + virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const=0; + enum DampedStringParam { DAMPED_STRING_REST_LENGTH, DAMPED_STRING_STIFFNESS, -- cgit v1.2.3 From ab22203791489df160c36a29a3cd8aa8b32bec04 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sat, 17 Oct 2015 10:29:54 -0300 Subject: misc cleanup --- servers/visual/visual_server_raster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'servers') diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index fbea60c3a6..1da536c124 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -1375,7 +1375,7 @@ void VisualServerRaster::_update_baked_light_sampler_dp_cache(BakedLightSampler void VisualServerRaster::baked_light_sampler_set_resolution(RID p_baked_light_sampler,int p_resolution){ - ERR_FAIL_COND(p_resolution<4 && p_resolution>64); + ERR_FAIL_COND(p_resolution<4 || p_resolution>64); VS_CHANGED; BakedLightSampler * blsamp = baked_light_sampler_owner.get(p_baked_light_sampler); ERR_FAIL_COND(!blsamp); -- cgit v1.2.3 From b59c86f6f953ce6957bccbcc1ec6f3ce4c55572d Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Wed, 21 Oct 2015 09:50:44 -0300 Subject: -Ability to debug video memory usage -Small fix to xml saver (swapping > and <) --- servers/register_server_types.cpp | 20 ++++++++++++++++++++ servers/visual/rasterizer.h | 5 ++++- servers/visual/rasterizer_dummy.h | 4 ++++ servers/visual/visual_server_raster.cpp | 15 +++++++++++++++ servers/visual/visual_server_raster.h | 5 +++++ servers/visual/visual_server_wrap_mt.h | 9 +++++++++ servers/visual_server.h | 12 ++++++++++++ 7 files changed, 69 insertions(+), 1 deletion(-) (limited to 'servers') diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 3634a03dbc..2af2a79d07 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -35,6 +35,25 @@ #include "physics_2d_server.h" #include "spatial_sound_server.h" #include "spatial_sound_2d_server.h" +#include "script_debugger_remote.h" + +static void _debugger_get_resource_usage(List* r_usage) { + + List tinfo; + VS::get_singleton()->texture_debug_usage(&tinfo); + + for (List::Element *E=tinfo.front();E;E=E->next()) { + + ScriptDebuggerRemote::ResourceUsage usage; + usage.path=E->get().path; + usage.vram=E->get().bytes; + usage.id=E->get().texture; + usage.type="Texture"; + usage.format=itos(E->get().size.width)+"x"+itos(E->get().size.height)+" "+Image::get_format_name(E->get().format); + r_usage->push_back(usage); + } + +} void register_server_types() { @@ -63,6 +82,7 @@ void register_server_types() { ObjectTypeDB::register_virtual_type(); ObjectTypeDB::register_virtual_type(); + ScriptDebuggerRemote::resource_usage_func=_debugger_get_resource_usage; } void unregister_server_types(){ diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 15c757665b..e22b3c3a6c 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -190,9 +190,12 @@ public: virtual bool texture_has_alpha(RID p_texture) const=0; virtual void texture_set_size_override(RID p_texture,int p_width, int p_height)=0; - virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const=0; + virtual void texture_set_path(RID p_texture,const String& p_path)=0; + virtual String texture_get_path(RID p_texture) const=0; + virtual void texture_debug_usage(List *r_info)=0; + /* SHADER API */ virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL)=0; diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h index 9249ad6256..f582fbd8ee 100644 --- a/servers/visual/rasterizer_dummy.h +++ b/servers/visual/rasterizer_dummy.h @@ -415,6 +415,10 @@ public: virtual void texture_set_size_override(RID p_texture,int p_width, int p_height); virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const; + virtual void texture_set_path(RID p_texture,const String& p_path) {} + virtual String texture_get_path(RID p_texture) const { return String(); } + virtual void texture_debug_usage(List *r_info) {} + /* SHADER API */ virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL); diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 01af2d86ad..a94d4f64c7 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -112,6 +112,21 @@ void VisualServerRaster::texture_set_reload_hook(RID p_texture,ObjectID p_owner, rasterizer->texture_set_reload_hook(p_texture,p_owner,p_function); } +void VisualServerRaster::texture_set_path(RID p_texture,const String& p_path) { + + rasterizer->texture_set_path(p_texture,p_path); +} + +String VisualServerRaster::texture_get_path(RID p_texture) const{ + + return rasterizer->texture_get_path(p_texture); +} + +void VisualServerRaster::texture_debug_usage(List *r_info){ + + rasterizer->texture_debug_usage(r_info); +} + /* SHADER API */ RID VisualServerRaster::shader_create(ShaderMode p_mode) { diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 3d8331984a..b6a5ca6308 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -668,6 +668,11 @@ public: virtual bool texture_can_stream(RID p_texture) const; virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const; + virtual void texture_set_path(RID p_texture,const String& p_path); + virtual String texture_get_path(RID p_texture) const; + + virtual void texture_debug_usage(List *r_info); + /* SHADER API */ diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index af88c9bdc9..57d691ae68 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -98,6 +98,15 @@ public: FUNC1RC(bool,texture_can_stream,RID); FUNC3C(texture_set_reload_hook,RID,ObjectID,const StringName&); + FUNC2(texture_set_path,RID,const String&); + FUNC1RC(String,texture_get_path,RID); + + virtual void texture_debug_usage(List *r_info) { + //pass directly, should lock the server anyway + visual_server->texture_debug_usage(r_info); + } + + /* SHADER API */ FUNC1R(RID,shader_create,ShaderMode); diff --git a/servers/visual_server.h b/servers/visual_server.h index ece61ec701..96c3e15cde 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -135,6 +135,18 @@ public: virtual bool texture_can_stream(RID p_texture) const=0; virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const=0; + virtual void texture_set_path(RID p_texture,const String& p_path)=0; + virtual String texture_get_path(RID p_texture) const=0; + + struct TextureInfo { + RID texture; + Size2 size; + Image::Format format; + int bytes; + String path; + }; + + virtual void texture_debug_usage(List *r_info)=0; /* SHADER API */ -- cgit v1.2.3 From 281d6fac1edd4a5b06692b850c00db6a5a9bbb46 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 1 Nov 2015 01:55:22 -0300 Subject: -some fixes to audio --- servers/audio/audio_rb_resampler.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'servers') diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h index 3c686374f4..3c08c79797 100644 --- a/servers/audio/audio_rb_resampler.h +++ b/servers/audio/audio_rb_resampler.h @@ -67,6 +67,11 @@ public: return todo; } + + _FORCE_INLINE_ bool has_data() const { + return rb && rb_read_pos!=rb_write_pos; + } + _FORCE_INLINE_ int16_t *get_write_buffer() { return read_buf; } _FORCE_INLINE_ void write(uint32_t p_frames) { -- cgit v1.2.3