diff options
Diffstat (limited to 'servers')
| -rw-r--r-- | servers/audio/audio_rb_resampler.cpp | 356 | ||||
| -rw-r--r-- | servers/audio/audio_rb_resampler.h | 133 | ||||
| -rw-r--r-- | servers/audio/audio_server_sw.cpp | 6 | ||||
| -rw-r--r-- | servers/physics/area_sw.cpp | 17 | ||||
| -rw-r--r-- | servers/physics/area_sw.h | 11 | ||||
| -rw-r--r-- | servers/physics/body_sw.cpp | 53 | ||||
| -rw-r--r-- | servers/physics/body_sw.h | 15 | ||||
| -rw-r--r-- | servers/physics_2d/area_2d_sw.cpp | 8 | ||||
| -rw-r--r-- | servers/physics_2d/body_2d_sw.h | 6 | ||||
| -rw-r--r-- | servers/physics_server.cpp | 24 | ||||
| -rw-r--r-- | servers/physics_server.h | 13 | ||||
| -rw-r--r-- | servers/visual/rasterizer.h | 1 | ||||
| -rw-r--r-- | servers/visual/rasterizer_dummy.cpp | 3 | ||||
| -rw-r--r-- | servers/visual/rasterizer_dummy.h | 1 | ||||
| -rw-r--r-- | servers/visual/visual_server_raster.cpp | 20 |
15 files changed, 634 insertions, 33 deletions
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<int C> +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<p_todo;i++) { + + offset = (offset + p_increment)&(((1<<(rb_bits+MIX_FRAC_BITS))-1)); + read+=p_increment; + uint32_t pos = offset >> 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<write_pos_cache) { + + rb_todo=write_pos_cache-rb_read_pos; //-1? + } else { + + rb_todo=(rb_len-rb_read_pos)+write_pos_cache; //-1? + } + + int todo = MIN( ((int64_t(rb_todo)<<MIX_FRAC_BITS)/increment)+1, p_frames ); +#if 0 + if (int(src_mix_rate)==target_mix_rate) { + + + if (channels==6) { + + for(int i=0;i<p_frames;i++) { + + int from = ((rb_read_pos+i)&rb_mask)*6; + int to = i*6; + + p_dest[from+0]=int32_t(rb[to+0])<<16; + p_dest[from+1]=int32_t(rb[to+1])<<16; + p_dest[from+2]=int32_t(rb[to+2])<<16; + p_dest[from+3]=int32_t(rb[to+3])<<16; + p_dest[from+4]=int32_t(rb[to+4])<<16; + p_dest[from+5]=int32_t(rb[to+5])<<16; + } + + } else { + int len=p_frames*channels; + int from=rb_read_pos*channels; + int mask=0; + switch(channels) { + case 1: mask=rb_len-1; break; + case 2: mask=(rb_len*2)-1; break; + case 4: mask=(rb_len*4)-1; break; + } + + for(int i=0;i<len;i++) { + + p_dest[i]=int32_t(rb[(from+i)&mask])<<16; + } + } + + rb_read_pos = (rb_read_pos+p_frames)&rb_mask; + } else +#endif + { + + uint32_t read=0; + switch(channels) { + case 1: read=_resample<1>(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<channels;c++) { + + for(int i=0;i<todo;i++) { + + int32_t samp = p_dest[i*channels+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<channels;c++) { + + int32_t from = p_dest[(todo-1)*channels+c]>>8; + + for(int i=0;i<remaining;i++) { + + uint32_t mul = (remaining-i) * 256 /remaining; + p_dest[(todo+i)*channels+c]=from*mul; + } + + } + + } +#endif + + //zero out what remains there to avoid glitches + for(int i=todo*channels;i<int(p_frames)*channels;i++) { + + p_dest[i]=0; + } + + if (read>rb_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<<rb_bits); + rb_mask=rb_len-1; + rb = memnew_arr( int16_t, rb_len * p_channels ); + read_buf = memnew_arr( int16_t, rb_len * p_channels ); + + } + + src_mix_rate=p_src_mix_rate; + target_mix_rate=p_target_mix_rate; + offset=0; + rb_read_pos=0; + rb_write_pos=0; + + //avoid maybe strange noises upon load + for (int i=0;i<(rb_len*channels);i++) { + + rb[i]=0; + read_buf[i]=0; + } + + return OK; + +} + +void AudioRBResampler::clear() { + + if (!rb) + return; + + //should be stopped at this point but just in case + if (rb) { + memdelete_arr(rb); + memdelete_arr(read_buf); + } + rb=NULL; + offset=0; + rb_read_pos=0; + rb_write_pos=0; + read_buf=NULL; +} + +AudioRBResampler::AudioRBResampler() { + + rb=NULL; + offset=0; + read_buf=NULL; + rb_read_pos=0; + rb_write_pos=0; + + rb_bits=0; + rb_len=0; + rb_mask=0; + read_buff_len=0; + channels=0; + src_mix_rate=0; + target_mix_rate=0; + +} + +AudioRBResampler::~AudioRBResampler() { + + if (rb) { + memdelete_arr(rb); + memdelete_arr(read_buf); + } + +} + diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h new file mode 100644 index 0000000000..3c686374f4 --- /dev/null +++ b/servers/audio/audio_rb_resampler.h @@ -0,0 +1,133 @@ +#ifndef AUDIO_RB_RESAMPLER_H +#define AUDIO_RB_RESAMPLER_H + +#include "typedefs.h" +#include "os/memory.h" + +struct AudioRBResampler { + + uint32_t rb_bits; + uint32_t rb_len; + uint32_t rb_mask; + uint32_t read_buff_len; + uint32_t channels; + uint32_t src_mix_rate; + uint32_t target_mix_rate; + + volatile int rb_read_pos; + volatile int rb_write_pos; + + int32_t offset; //contains the fractional remainder of the resampler + enum { + MIX_FRAC_BITS=13, + MIX_FRAC_LEN=(1<<MIX_FRAC_BITS), + MIX_FRAC_MASK=MIX_FRAC_LEN-1, + }; + + int16_t *read_buf; + int16_t *rb; + + + template<int C> + 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<p_frames;i++) { + + rb[ rb_write_pos ] = read_buf[i]; + rb_write_pos=(rb_write_pos+1)&rb_mask; + } + } break; + case 2: { + + for(uint32_t i=0;i<p_frames;i++) { + + rb[ (rb_write_pos<<1)+0 ] = read_buf[(i<<1)+0]; + rb[ (rb_write_pos<<1)+1 ] = read_buf[(i<<1)+1]; + rb_write_pos=(rb_write_pos+1)&rb_mask; + } + } break; + case 4: { + + for(uint32_t i=0;i<p_frames;i++) { + + rb[ (rb_write_pos<<2)+0 ] = read_buf[(i<<2)+0]; + rb[ (rb_write_pos<<2)+1 ] = read_buf[(i<<2)+1]; + rb[ (rb_write_pos<<2)+2 ] = read_buf[(i<<2)+2]; + rb[ (rb_write_pos<<2)+3 ] = read_buf[(i<<2)+3]; + rb_write_pos=(rb_write_pos+1)&rb_mask; + } + } break; + case 6: { + + for(uint32_t i=0;i<p_frames;i++) { + + rb[ (rb_write_pos*6)+0 ] = read_buf[(i*6)+0]; + rb[ (rb_write_pos*6)+1 ] = read_buf[(i*6)+1]; + rb[ (rb_write_pos*6)+2 ] = read_buf[(i*6)+2]; + rb[ (rb_write_pos*6)+3 ] = read_buf[(i*6)+3]; + rb[ (rb_write_pos*6)+4 ] = read_buf[(i*6)+4]; + rb[ (rb_write_pos*6)+5 ] = read_buf[(i*6)+5]; + rb_write_pos=(rb_write_pos+1)&rb_mask; + } + } break; + + + } + + } + + int get_channel_count() const; + + Error setup(int p_channels, int p_src_mix_rate, int p_target_mix_rate, int p_buffer_msec, int p_minbuff_needed=-1); + void clear(); + bool mix(int32_t *p_dest, int p_frames); + + AudioRBResampler(); + ~AudioRBResampler(); +}; + +#endif // AUDIO_RB_RESAMPLER_H diff --git a/servers/audio/audio_server_sw.cpp b/servers/audio/audio_server_sw.cpp index 8a3ab7ce70..09cb4eca5f 100644 --- a/servers/audio/audio_server_sw.cpp +++ b/servers/audio/audio_server_sw.cpp @@ -830,10 +830,14 @@ void AudioServerSW::finish() { void AudioServerSW::_update_streams(bool p_thread) { _THREAD_SAFE_METHOD_ - for(List<Stream*>::Element *E=active_audio_streams.front();E;E=E->next()) { + for(List<Stream*>::Element *E=active_audio_streams.front();E;) { //stream might be removed durnig this callback + + List<Stream*>::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; } } diff --git a/servers/physics/area_sw.cpp b/servers/physics/area_sw.cpp index 83be80f816..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); + + } @@ -123,7 +131,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 +148,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 +258,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..40ccdaf370 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; } @@ -202,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/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<BodySW> active_list; SelfList<BodySW> inertia_update_list; SelfList<BodySW> 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/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/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; 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/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(); diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index b51f59050d..155d10d85a 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(); }; @@ -7413,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; |