summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/audio/audio_rb_resampler.cpp356
-rw-r--r--servers/audio/audio_rb_resampler.h133
-rw-r--r--servers/audio/audio_server_sw.cpp6
-rw-r--r--servers/physics/area_sw.cpp17
-rw-r--r--servers/physics/area_sw.h11
-rw-r--r--servers/physics/body_sw.cpp53
-rw-r--r--servers/physics/body_sw.h15
-rw-r--r--servers/physics_2d/area_2d_sw.cpp8
-rw-r--r--servers/physics_2d/body_2d_sw.h6
-rw-r--r--servers/physics_server.cpp24
-rw-r--r--servers/physics_server.h13
-rw-r--r--servers/visual/rasterizer.h1
-rw-r--r--servers/visual/rasterizer_dummy.cpp3
-rw-r--r--servers/visual/rasterizer_dummy.h1
-rw-r--r--servers/visual/visual_server_raster.cpp20
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;