diff options
Diffstat (limited to 'servers')
23 files changed, 636 insertions, 3 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/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp index e2b2fa2051..da4c1b48d8 100644 --- a/servers/physics/body_pair_sw.cpp +++ b/servers/physics/body_pair_sw.cpp @@ -299,6 +299,16 @@ bool BodyPairSW::setup(float p_step) { c.active=true; +#ifdef DEBUG_ENABLED + + + if (space->is_debugging_contacts()) { + space->add_debug_contact(global_A+offset_A); + space->add_debug_contact(global_B+offset_A); + } +#endif + + int gather_A = A->can_report_contacts(); int gather_B = B->can_report_contacts(); diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 521ffae0ea..a9a8042c19 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -201,6 +201,30 @@ PhysicsDirectSpaceState* PhysicsServerSW::space_get_direct_state(RID p_space) { return space->get_direct_state(); } +void PhysicsServerSW::space_set_debug_contacts(RID p_space,int p_max_contacts) { + + SpaceSW *space = space_owner.get(p_space); + ERR_FAIL_COND(!space); + space->set_debug_contacts(p_max_contacts); + +} + +Vector<Vector3> PhysicsServerSW::space_get_contacts(RID p_space) const { + + SpaceSW *space = space_owner.get(p_space); + ERR_FAIL_COND_V(!space,Vector<Vector3>()); + return space->get_debug_contacts(); + +} + +int PhysicsServerSW::space_get_contact_count(RID p_space) const { + + SpaceSW *space = space_owner.get(p_space); + ERR_FAIL_COND_V(!space,0); + return space->get_debug_contact_count(); + +} + RID PhysicsServerSW::area_create() { AreaSW *area = memnew( AreaSW ); diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h index 80007b8499..abbb057616 100644 --- a/servers/physics/physics_server_sw.h +++ b/servers/physics/physics_server_sw.h @@ -94,6 +94,9 @@ public: // this function only works on fixed process, errors and returns null otherwise virtual PhysicsDirectSpaceState* space_get_direct_state(RID p_space); + virtual void space_set_debug_contacts(RID p_space,int p_max_contacts); + virtual Vector<Vector3> space_get_contacts(RID p_space) const; + virtual int space_get_contact_count(RID p_space) const; /* AREA API */ diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index d329a10f04..a4fe1dd3fc 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -640,7 +640,7 @@ void SpaceSW::call_queries() { 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());
@@ -651,6 +651,7 @@ void SpaceSW::setup() { void SpaceSW::update() {
+
broadphase->update();
}
@@ -712,6 +713,7 @@ SpaceSW::SpaceSW() { collision_pairs=0;
active_objects=0;
island_count=0;
+ contact_debug_count=0;
locked=false;
contact_recycle_radius=0.01;
diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h index 16f5ad3c81..e88f61d881 100644 --- a/servers/physics/space_sw.h +++ b/servers/physics/space_sw.h @@ -103,6 +103,9 @@ class SpaceSW { RID static_global_body;
+ Vector<Vector3> contact_debug;
+ int contact_debug_count;
+
friend class PhysicsDirectSpaceStateSW;
public:
@@ -166,6 +169,11 @@ public: 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<contact_debug.size()) contact_debug[contact_debug_count++]=p_contact; }
+ _FORCE_INLINE_ Vector<Vector3> 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; }
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp index 6bfed134e6..eb3abbb267 100644 --- a/servers/physics_2d/body_pair_2d_sw.cpp +++ b/servers/physics_2d/body_pair_2d_sw.cpp @@ -379,7 +379,12 @@ bool BodyPair2DSW::setup(float p_step) { } c.active=true; - +#ifdef DEBUG_ENABLED + if (space->is_debugging_contacts()) { + space->add_debug_contact(global_A+offset_A); + space->add_debug_contact(global_B+offset_A); + } +#endif int gather_A = A->can_report_contacts(); int gather_B = B->can_report_contacts(); diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index b446f4928a..14b4c09ebc 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -257,6 +257,30 @@ real_t Physics2DServerSW::space_get_param(RID p_space,SpaceParameter p_param) co return space->get_param(p_param); } +void Physics2DServerSW::space_set_debug_contacts(RID p_space,int p_max_contacts) { + + Space2DSW *space = space_owner.get(p_space); + ERR_FAIL_COND(!space); + space->set_debug_contacts(p_max_contacts); + +} + +Vector<Vector2> Physics2DServerSW::space_get_contacts(RID p_space) const { + + Space2DSW *space = space_owner.get(p_space); + ERR_FAIL_COND_V(!space,Vector<Vector2>()); + return space->get_debug_contacts(); + +} + +int Physics2DServerSW::space_get_contact_count(RID p_space) const { + + Space2DSW *space = space_owner.get(p_space); + ERR_FAIL_COND_V(!space,0); + return space->get_debug_contact_count(); + +} + Physics2DDirectSpaceState* Physics2DServerSW::space_get_direct_state(RID p_space) { Space2DSW *space = space_owner.get(p_space); diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index 6e875701b8..605e04ead8 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -102,6 +102,11 @@ public: virtual void space_set_param(RID p_space,SpaceParameter p_param, real_t p_value); virtual real_t space_get_param(RID p_space,SpaceParameter p_param) const; + virtual void space_set_debug_contacts(RID p_space,int p_max_contacts); + virtual Vector<Vector2> space_get_contacts(RID p_space) const; + virtual int space_get_contact_count(RID p_space) const; + + // this function only works on fixed process, errors and returns null otherwise virtual Physics2DDirectSpaceState* space_get_direct_state(RID p_space); diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h index 0ddc8f16ec..54af3eeb99 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.h +++ b/servers/physics_2d/physics_2d_server_wrap_mt.h @@ -94,6 +94,22 @@ public: return physics_2d_server->space_get_direct_state(p_space); } + FUNC2(space_set_debug_contacts,RID,int); + virtual Vector<Vector2> space_get_contacts(RID p_space) const { + + ERR_FAIL_COND_V(main_thread!=Thread::get_caller_ID(),Vector<Vector2>()); + return physics_2d_server->space_get_contacts(p_space); + + } + + virtual int space_get_contact_count(RID p_space) const { + + ERR_FAIL_COND_V(main_thread!=Thread::get_caller_ID(),0); + return physics_2d_server->space_get_contact_count(p_space); + + } + + /* AREA API */ diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 767ad9038d..a71e6c4bf5 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -1230,6 +1230,7 @@ void Space2DSW::call_queries() { void Space2DSW::setup() { + contact_debug_count=0; while(inertia_update_list.first()) { inertia_update_list.first()->self()->update_inertias(); @@ -1302,6 +1303,8 @@ Space2DSW::Space2DSW() { active_objects=0; island_count=0; + contact_debug_count=0; + locked=false; contact_recycle_radius=0.01; contact_max_separation=0.05; @@ -1320,6 +1323,10 @@ Space2DSW::Space2DSW() { direct_access = memnew( Physics2DDirectSpaceStateSW ); direct_access->space=this; + + + + } Space2DSW::~Space2DSW() { diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index abee8628fc..97ad3d7f80 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -103,6 +103,9 @@ class Space2DSW { int _cull_aabb_for_body(Body2DSW *p_body,const Rect2& p_aabb); + Vector<Vector2> contact_debug; + int contact_debug_count; + friend class Physics2DDirectSpaceStateSW; public: @@ -169,6 +172,14 @@ public: bool test_body_motion(Body2DSW *p_body, const Vector2&p_motion, float p_margin, Physics2DServer::MotionResult *r_result); + + 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 Vector2& p_contact) { if (contact_debug_count<contact_debug.size()) contact_debug[contact_debug_count++]=p_contact; } + _FORCE_INLINE_ Vector<Vector2> get_debug_contacts() { return contact_debug; } + _FORCE_INLINE_ int get_debug_contact_count() { return contact_debug_count; } + + Physics2DDirectSpaceStateSW *get_direct_state(); Space2DSW(); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index b24496880e..2d70337dc8 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -293,6 +293,9 @@ public: // this function only works on fixed process, errors and returns null otherwise virtual Physics2DDirectSpaceState* space_get_direct_state(RID p_space)=0; + virtual void space_set_debug_contacts(RID p_space,int p_max_contacts)=0; + virtual Vector<Vector2> space_get_contacts(RID p_space) const=0; + virtual int space_get_contact_count(RID p_space) const=0; //missing space parameters diff --git a/servers/physics_server.h b/servers/physics_server.h index b82d4cf5da..75584966bb 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -286,6 +286,9 @@ public: // this function only works on fixed process, errors and returns null otherwise virtual PhysicsDirectSpaceState* space_get_direct_state(RID p_space)=0; + virtual void space_set_debug_contacts(RID p_space,int p_max_contacts)=0; + virtual Vector<Vector3> space_get_contacts(RID p_space) const=0; + virtual int space_get_contact_count(RID p_space) const=0; //missing space parameters 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 8b47596d7e..fbea60c3a6 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -454,6 +454,14 @@ AABB VisualServerRaster::mesh_get_custom_aabb(RID p_mesh) const { return rasterizer->mesh_get_custom_aabb(p_mesh); } +void VisualServerRaster::mesh_clear(RID p_mesh) { + + ERR_FAIL_COND(!rasterizer->is_mesh(p_mesh)); + while(rasterizer->mesh_get_surface_count(p_mesh)) { + rasterizer->mesh_remove_surface(p_mesh,0); + } +} + /* MULTIMESH */ @@ -7427,6 +7435,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; diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 73298d58cd..3d8331984a 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -765,6 +765,7 @@ public: virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb); virtual AABB mesh_get_custom_aabb(RID p_mesh) const; + virtual void mesh_clear(RID p_mesh); /* MULTIMESH API */ diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index db03d82829..af88c9bdc9 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -199,6 +199,7 @@ public: FUNC2(mesh_remove_surface,RID,int); FUNC1RC(int,mesh_get_surface_count,RID); + FUNC1(mesh_clear,RID); FUNC2(mesh_set_custom_aabb,RID,const AABB&); diff --git a/servers/visual_server.h b/servers/visual_server.h index dd71650801..ece61ec701 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -353,6 +353,8 @@ public: virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb)=0; virtual AABB mesh_get_custom_aabb(RID p_mesh) const=0; + virtual void mesh_clear(RID p_mesh)=0; + /* MULTIMESH API */ virtual RID multimesh_create()=0; |