diff options
author | Juan Linietsky <reduzio@gmail.com> | 2014-09-17 20:03:10 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2014-09-17 20:03:10 -0300 |
commit | 990f6cf50e96213a4b1a2961e61a9b922cd75d71 (patch) | |
tree | 600fb659508e8745d7656416b24f89b2157a2630 | |
parent | 76aaa96d0e114d5293efed2fd0378ea390076b7e (diff) |
More Bug Fixes
-=-=-=-=-=-=-
-Fixed a few bugs in Mixer, now playback of chiptunes works great :)
-Changed how visibility AABB generation from skeletons work, it's fully automatic and real-time now, generated from current skeleton pose for the frame.
-Fixed camera in 3D kinematic character demo.
-rw-r--r-- | demos/3d/kinematic_char/follow_camera.gd | 6 | ||||
-rw-r--r-- | drivers/chibi/cp_player_data.cpp | 2 | ||||
-rw-r--r-- | drivers/chibi/cp_player_data_events.cpp | 16 | ||||
-rw-r--r-- | drivers/chibi/event_stream_chibi.cpp | 20 | ||||
-rw-r--r-- | drivers/gles1/rasterizer_gles1.cpp | 2 | ||||
-rw-r--r-- | drivers/gles1/rasterizer_gles1.h | 2 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 127 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.h | 40 | ||||
-rw-r--r-- | scene/audio/event_player.cpp | 3 | ||||
-rw-r--r-- | scene/resources/event_stream.cpp | 2 | ||||
-rw-r--r-- | servers/audio/audio_mixer_sw.cpp | 16 | ||||
-rw-r--r-- | servers/audio/audio_server_sw.cpp | 1 | ||||
-rw-r--r-- | servers/audio/sample_manager_sw.cpp | 32 | ||||
-rw-r--r-- | servers/visual/rasterizer.h | 2 | ||||
-rw-r--r-- | servers/visual/rasterizer_dummy.cpp | 2 | ||||
-rw-r--r-- | servers/visual/rasterizer_dummy.h | 2 | ||||
-rw-r--r-- | servers/visual/visual_server_raster.cpp | 41 | ||||
-rw-r--r-- | servers/visual/visual_server_raster.h | 5 |
18 files changed, 288 insertions, 33 deletions
diff --git a/demos/3d/kinematic_char/follow_camera.gd b/demos/3d/kinematic_char/follow_camera.gd index 0b9ff9bbb2..60eef5787a 100644 --- a/demos/3d/kinematic_char/follow_camera.gd +++ b/demos/3d/kinematic_char/follow_camera.gd @@ -45,13 +45,13 @@ func _fixed_process(dt): var col = ds.intersect_ray(target,target,collision_exception) var col_right = ds.intersect_ray(target,target+Matrix3(up,deg2rad(-autoturn_ray_aperture)).xform(delta),collision_exception) - if (col!=null): + if (!col.empty()): #if main ray was occluded, get camera closer, this is the worst case scenario delta = col.position - target - elif (col_left!=null and col_right==null): + elif (!col_left.empty() and col_right.empty()): #if only left ray is occluded, turn the camera around to the right delta = Matrix3(up,deg2rad(-dt*autoturn_speed)).xform(delta) - elif (col_left==null and col_right!=null): + elif (col_left.empty() and !col_right.empty()): #if only right ray is occluded, turn the camera around to the left delta = Matrix3(up,deg2rad(dt*autoturn_speed)).xform(delta) else: diff --git a/drivers/chibi/cp_player_data.cpp b/drivers/chibi/cp_player_data.cpp index 324c3f7c36..99bc4fddd2 100644 --- a/drivers/chibi/cp_player_data.cpp +++ b/drivers/chibi/cp_player_data.cpp @@ -125,7 +125,7 @@ int64_t CPPlayer::get_channel_last_note_time_usec(int p_channel) const { void CPPlayer::set_channel_global_volume(int p_channel,int p_volume) { CP_FAIL_INDEX(p_channel,64); - control.channel[p_channel].channel_global_volume=p_volume; + control.channel[p_channel].channel_global_volume=CLAMP(p_volume,0,255); } diff --git a/drivers/chibi/cp_player_data_events.cpp b/drivers/chibi/cp_player_data_events.cpp index 6f2815211c..32335040bc 100644 --- a/drivers/chibi/cp_player_data_events.cpp +++ b/drivers/chibi/cp_player_data_events.cpp @@ -146,6 +146,7 @@ void CPPlayer::Voice_Control::reset() { void CPPlayer::Channel_Control::reset() { + int prev_gv =channel_global_volume; cp_memzero(this,sizeof(*this)); slave_voice=NULL; @@ -162,6 +163,7 @@ void CPPlayer::Channel_Control::reset() { reserved=false; carry.maybe=false; last_event_usecs=-1; + channel_global_volume=prev_gv; } void CPPlayer::Voice_Control::update_info_from_master_channel() { @@ -316,6 +318,15 @@ void CPPlayer::update_mixer() { } + /*printf("fadeout %i\n",(int)v.fadeout_volume); + printf("channel %i\n",(int)v.channel_volume); + printf("output %i\n",(int)v.output_volume); + printf("env %i\n",(int)tmp_volenv_value); + printf("cgb %i\n",(int)v.master_channel->channel_global_volume); +*/ + + + int cv=v.master_channel->channel_global_volume; tmpvol=(uint64_t)v.fadeout_volume; /* max 1024 - 10 bits */ tmpvol*=(uint64_t)v.channel_volume; /* * max 64 - 6 bits */ @@ -341,6 +352,7 @@ void CPPlayer::update_mixer() { v.total_volume=tmpvol; + if ((v.master_channel!=NULL) && song->is_channel_mute( v.master_channel_index ) && !v.master_channel->reserved) { mixer->set_voice_volume(i,0); @@ -518,7 +530,7 @@ void CPPlayer::update_mixer() { } } - + switch(song->get_reverb_mode()) { case CPSong::REVERB_MODE_ROOM: { @@ -569,6 +581,8 @@ void CPPlayer::update_mixer() { } mixer->set_chorus_params(song->get_chorus_delay_ms(),song->get_chorus_separation_ms(),song->get_chorus_depth_ms10(),song->get_chorus_speed_hz10() ); + + } diff --git a/drivers/chibi/event_stream_chibi.cpp b/drivers/chibi/event_stream_chibi.cpp index a9106d6d78..2deb83e2bc 100644 --- a/drivers/chibi/event_stream_chibi.cpp +++ b/drivers/chibi/event_stream_chibi.cpp @@ -372,6 +372,7 @@ void CPMixerImpl::set_voice_panning(int p_voice_index,int p_pan) { void CPMixerImpl::set_voice_volume(int p_voice_index,int p_vol) { + Voice &v=voices[p_voice_index]; ERR_FAIL_COND(v.channel==AudioMixer::INVALID_CHANNEL); float vol = p_vol/512.0; @@ -488,8 +489,9 @@ void CPMixerImpl::process_usecs(int p_usec,float p_volume,float p_pitch_scale,fl p_usec-=callback_timeout; callback_timeout=0; - if (callback) + if (callback) { callback(userdata); + } callback_timeout=callback_interval*(1.0/p_tempo_scale); } else { @@ -704,6 +706,9 @@ float EventStreamPlaybackChibi::get_tempo_scale() const{ void EventStreamPlaybackChibi::set_channel_volume(int p_channel,float p_volume) { + + if (p_channel>=64) + return; player->set_channel_global_volume(p_channel,p_volume*256); } @@ -784,28 +789,33 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina Ref<EventStreamChibi> esc( memnew( EventStreamChibi ) ); CPLoader_IT loader(&f); - loader.load_song(p_path.utf8().get_data(),&esc->song,false); + CPLoader::Error err = loader.load_song(p_path.utf8().get_data(),&esc->song,false); + ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES()); + return esc; } else if (el=="xm") { Ref<EventStreamChibi> esc( memnew( EventStreamChibi ) ); CPLoader_XM loader(&f); - loader.load_song(p_path.utf8().get_data(),&esc->song,false); + CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false); + ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES()); return esc; } else if (el=="s3m") { Ref<EventStreamChibi> esc( memnew( EventStreamChibi ) ); CPLoader_S3M loader(&f); - loader.load_song(p_path.utf8().get_data(),&esc->song,false); + CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false); + ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES()); return esc; } else if (el=="mod") { Ref<EventStreamChibi> esc( memnew( EventStreamChibi ) ); CPLoader_MOD loader(&f); - loader.load_song(p_path.utf8().get_data(),&esc->song,false); + CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false); + ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES()); return esc; } diff --git a/drivers/gles1/rasterizer_gles1.cpp b/drivers/gles1/rasterizer_gles1.cpp index ad0c8e3c7f..02de063bda 100644 --- a/drivers/gles1/rasterizer_gles1.cpp +++ b/drivers/gles1/rasterizer_gles1.cpp @@ -1956,7 +1956,7 @@ int RasterizerGLES1::mesh_get_surface_count(RID p_mesh) const { return mesh->surfaces.size(); } -AABB RasterizerGLES1::mesh_get_aabb(RID p_mesh) const { +AABB RasterizerGLES1::mesh_get_aabb(RID p_mesh,RID p_skeleton) const { Mesh *mesh = mesh_owner.get( p_mesh ); ERR_FAIL_COND_V(!mesh,AABB()); diff --git a/drivers/gles1/rasterizer_gles1.h b/drivers/gles1/rasterizer_gles1.h index e7937f43c3..cca953eed0 100644 --- a/drivers/gles1/rasterizer_gles1.h +++ b/drivers/gles1/rasterizer_gles1.h @@ -939,7 +939,7 @@ public: virtual void mesh_remove_surface(RID p_mesh,int p_index); virtual int mesh_get_surface_count(RID p_mesh) const; - virtual AABB mesh_get_aabb(RID p_mesh) const; + virtual AABB mesh_get_aabb(RID p_mesh,RID p_skeleton=RID()) const; virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb); virtual AABB mesh_get_custom_aabb(RID p_mesh) const; diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 4a1362f9f8..6ea696e153 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -1746,6 +1746,9 @@ void RasterizerGLES2::mesh_add_surface(RID p_mesh,VS::PrimitiveType p_primitive, iaw = index_array_pre_vbo.write(); index_array_ptr=iaw.ptr(); } + + _surface_set_arrays(surface,array_ptr,index_array_ptr,p_arrays,true); + } else { surface->array_local = (uint8_t*)memalloc(surface->array_len*surface->stride); @@ -1755,6 +1758,8 @@ void RasterizerGLES2::mesh_add_surface(RID p_mesh,VS::PrimitiveType p_primitive, index_array_ptr=(uint8_t*)surface->index_array_local; } + _surface_set_arrays(surface,array_ptr,index_array_ptr,p_arrays,true); + if (mesh->morph_target_count) { surface->morph_targets_local = memnew_arr(Surface::MorphTarget,mesh->morph_target_count); @@ -1769,7 +1774,6 @@ void RasterizerGLES2::mesh_add_surface(RID p_mesh,VS::PrimitiveType p_primitive, - _surface_set_arrays(surface,array_ptr,index_array_ptr,p_arrays,true); /* create buffers!! */ @@ -2167,6 +2171,67 @@ Error RasterizerGLES2::_surface_set_arrays(Surface *p_surface, uint8_t *p_mem,ui p_surface->configured_format|=(1<<ai); } + if (p_surface->format&VS::ARRAY_FORMAT_BONES) { + //create AABBs for each detected bone + int total_bones = p_surface->max_bone+1; + if (p_main) { + p_surface->skeleton_bone_aabb.resize(total_bones); + p_surface->skeleton_bone_used.resize(total_bones); + for(int i=0;i<total_bones;i++) + p_surface->skeleton_bone_used[i]=false; + } + DVector<Vector3> vertices = p_arrays[VS::ARRAY_VERTEX]; + DVector<int> bones = p_arrays[VS::ARRAY_BONES]; + DVector<float> weights = p_arrays[VS::ARRAY_WEIGHTS]; + + bool any_valid=false; + + if (vertices.size() && bones.size()==vertices.size()*4 && weights.size()==bones.size()) { + //print_line("MAKING SKELETHONG"); + int vs = vertices.size(); + DVector<Vector3>::Read rv =vertices.read(); + DVector<int>::Read rb=bones.read(); + DVector<float>::Read rw=weights.read(); + + Vector<bool> first; + first.resize(total_bones); + for(int i=0;i<total_bones;i++) { + first[i]=p_main; + } + AABB *bptr = p_surface->skeleton_bone_aabb.ptr(); + bool *fptr=first.ptr(); + bool *usedptr=p_surface->skeleton_bone_used.ptr(); + + for(int i=0;i<vs;i++) { + + Vector3 v = rv[i]; + for(int j=0;j<4;j++) { + + int idx = rb[i*4+j]; + float w = rw[i*4+j]; + if (w==0) + continue;//break; + ERR_FAIL_INDEX_V(idx,total_bones,ERR_INVALID_DATA); + + if (fptr[idx]) { + bptr[idx].pos=v; + fptr[idx]=false; + any_valid=true; + } else { + bptr[idx].expand_to(v); + } + usedptr[idx]=true; + } + } + } + + if (p_main && !any_valid) { + + p_surface->skeleton_bone_aabb.clear(); + p_surface->skeleton_bone_used.clear(); + } + } + return OK; } @@ -2343,7 +2408,7 @@ int RasterizerGLES2::mesh_get_surface_count(RID p_mesh) const { return mesh->surfaces.size(); } -AABB RasterizerGLES2::mesh_get_aabb(RID p_mesh) const { +AABB RasterizerGLES2::mesh_get_aabb(RID p_mesh, RID p_skeleton) const { Mesh *mesh = mesh_owner.get( p_mesh ); ERR_FAIL_COND_V(!mesh,AABB()); @@ -2351,14 +2416,62 @@ AABB RasterizerGLES2::mesh_get_aabb(RID p_mesh) const { if (mesh->custom_aabb!=AABB()) return mesh->custom_aabb; + Skeleton *sk=NULL; + if (p_skeleton.is_valid()) + sk=skeleton_owner.get(p_skeleton); + AABB aabb; + if (sk) { - for (int i=0;i<mesh->surfaces.size();i++) { - if (i==0) - aabb=mesh->surfaces[i]->aabb; - else - aabb.merge_with(mesh->surfaces[i]->aabb); + for (int i=0;i<mesh->surfaces.size();i++) { + + AABB laabb; + if (mesh->surfaces[i]->format&VS::ARRAY_FORMAT_BONES && mesh->surfaces[i]->skeleton_bone_aabb.size()) { + + + int bs = mesh->surfaces[i]->skeleton_bone_aabb.size(); + const AABB *skbones = mesh->surfaces[i]->skeleton_bone_aabb.ptr(); + const bool *skused = mesh->surfaces[i]->skeleton_bone_used.ptr(); + + int sbs = sk->bones.size(); + ERR_CONTINUE(bs>sbs); + Skeleton::Bone *skb = sk->bones.ptr(); + + bool first=true; + for(int j=0;j<bs;j++) { + + if (!skused[j]) + continue; + AABB baabb = skb[ j ].transform_aabb ( skbones[j] ); + if (first) { + laabb=baabb; + first=false; + } else { + laabb.merge_with(baabb); + } + } + + } else { + + laabb=mesh->surfaces[i]->aabb; + } + + if (i==0) + aabb=laabb; + else + aabb.merge_with(laabb); + } + } else { + + for (int i=0;i<mesh->surfaces.size();i++) { + + if (i==0) + aabb=mesh->surfaces[i]->aabb; + else + aabb.merge_with(mesh->surfaces[i]->aabb); + } + } return aabb; diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index d905d817c9..a9fa7994e5 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -312,6 +312,8 @@ class RasterizerGLES2 : public Rasterizer { // no support for the above, array in localmem. uint8_t *array_local; uint8_t *index_array_local; + Vector<AABB> skeleton_bone_aabb; + Vector<bool> skeleton_bone_used; //bool packed; @@ -547,6 +549,42 @@ class RasterizerGLES2 : public Rasterizer { r_dst[1]+=((mtx[0][1]*p_src[0] ) + ( mtx[1][1]*p_src[1] ) + ( mtx[2][1]*p_src[2] ) )*p_weight; r_dst[2]+=((mtx[0][2]*p_src[0] ) + ( mtx[1][2]*p_src[1] ) + ( mtx[2][2]*p_src[2] ) )*p_weight; } + + _ALWAYS_INLINE_ AABB transform_aabb(const AABB& p_aabb) const { + + float vertices[8][3]={ + {p_aabb.pos.x+p_aabb.size.x, p_aabb.pos.y+p_aabb.size.y, p_aabb.pos.z+p_aabb.size.z}, + {p_aabb.pos.x+p_aabb.size.x, p_aabb.pos.y+p_aabb.size.y, p_aabb.pos.z}, + {p_aabb.pos.x+p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z}, + {p_aabb.pos.x+p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z}, + {p_aabb.pos.x, p_aabb.pos.y+p_aabb.size.y, p_aabb.pos.z+p_aabb.size.z}, + {p_aabb.pos.x, p_aabb.pos.y+p_aabb.size.y, p_aabb.pos.z}, + {p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z}, + {p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z} + }; + + + AABB ret; + + + + for (int i=0;i<8;i++) { + + Vector3 xv( + + ((mtx[0][0]*vertices[i][0] ) + ( mtx[1][0]*vertices[i][1] ) + ( mtx[2][0]*vertices[i][2] ) + mtx[3][0] ), + ((mtx[0][1]*vertices[i][0] ) + ( mtx[1][1]*vertices[i][1] ) + ( mtx[2][1]*vertices[i][2] ) + mtx[3][1] ), + ((mtx[0][2]*vertices[i][0] ) + ( mtx[1][2]*vertices[i][1] ) + ( mtx[2][2]*vertices[i][2] ) + mtx[3][2] ) + ); + + if (i==0) + ret.pos=xv; + else + ret.expand_to(xv); + } + + return ret; + } }; GLuint tex_id; @@ -1242,7 +1280,7 @@ public: virtual void mesh_remove_surface(RID p_mesh,int p_index); virtual int mesh_get_surface_count(RID p_mesh) const; - virtual AABB mesh_get_aabb(RID p_mesh) const; + virtual AABB mesh_get_aabb(RID p_mesh,RID p_skeleton=RID()) const; virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb); virtual AABB mesh_get_custom_aabb(RID p_mesh) const; diff --git a/scene/audio/event_player.cpp b/scene/audio/event_player.cpp index 07162e42fd..6bad94bf0e 100644 --- a/scene/audio/event_player.cpp +++ b/scene/audio/event_player.cpp @@ -76,8 +76,9 @@ Ref<EventStream> EventPlayer::get_stream() const { void EventPlayer::play() { ERR_FAIL_COND(!is_inside_scene()); - if (playback.is_null()) + if (playback.is_null()) { return; + } if (playback->is_playing()) { AudioServer::get_singleton()->lock(); stop(); diff --git a/scene/resources/event_stream.cpp b/scene/resources/event_stream.cpp index d7ecfe1aba..de3c6a7a64 100644 --- a/scene/resources/event_stream.cpp +++ b/scene/resources/event_stream.cpp @@ -32,10 +32,12 @@ Error EventStreamPlayback::play() { if (stream.is_valid()) stop(); + Error err = _play(); if (err) return err; + playing=true; AudioServer::get_singleton()->stream_set_active(stream,true); diff --git a/servers/audio/audio_mixer_sw.cpp b/servers/audio/audio_mixer_sw.cpp index 873e19823a..3af18cf3ae 100644 --- a/servers/audio/audio_mixer_sw.cpp +++ b/servers/audio/audio_mixer_sw.cpp @@ -369,7 +369,17 @@ void AudioMixerSW::mix_channel(Channel& c) { AS::SampleLoopFormat loop_format=sample_manager->sample_get_loop_format(c.sample); AS::SampleFormat format=sample_manager->sample_get_format(c.sample); - bool use_fx=fx_enabled && (c.mix.old_reverb_vol || c.mix.reverb_vol || c.mix.old_chorus_vol || c.mix.chorus_vol ); + bool use_fx=false; + + if (fx_enabled) { + + for(int i=0;i<mix_channels;i++) { + if (c.mix.old_reverb_vol[i] || c.mix.reverb_vol[i] || c.mix.old_chorus_vol[i] || c.mix.chorus_vol[i] ) { + use_fx=true; + break; + } + } + } /* audio data */ @@ -547,8 +557,8 @@ void AudioMixerSW::mix_channel(Channel& c) { } c.mix.offset+=rstate.pos; - dst_buff+=target*2; - + dst_buff+=target*mix_channels; + rstate.reverb_buffer+=target*mix_channels; } c.filter.old_coefs=c.filter.coefs; diff --git a/servers/audio/audio_server_sw.cpp b/servers/audio/audio_server_sw.cpp index cb08024851..f50813731e 100644 --- a/servers/audio/audio_server_sw.cpp +++ b/servers/audio/audio_server_sw.cpp @@ -502,6 +502,7 @@ void AudioServerSW::voice_set_reverb(RID p_voice, ReverbRoomType p_room_type, fl cmd.voice=p_voice; cmd.reverb.room=p_room_type; cmd.reverb.send=p_reverb; + voice_rb.push_command(cmd); } diff --git a/servers/audio/sample_manager_sw.cpp b/servers/audio/sample_manager_sw.cpp index 29564fe018..a74c4372ca 100644 --- a/servers/audio/sample_manager_sw.cpp +++ b/servers/audio/sample_manager_sw.cpp @@ -146,6 +146,38 @@ void SampleManagerMallocSW::sample_set_data(RID p_sample, const DVector<uint8_t> dst[i]=src[i]; } + switch(s->format) { + + case AS::SAMPLE_FORMAT_PCM8: { + + if (s->stereo) { + dst[s->length]=dst[s->length-2]; + dst[s->length+1]=dst[s->length-1]; + } else { + + dst[s->length]=dst[s->length-1]; + } + + } break; + case AS::SAMPLE_FORMAT_PCM16: { + + if (s->stereo) { + dst[s->length]=dst[s->length-4]; + dst[s->length+1]=dst[s->length-3]; + dst[s->length+2]=dst[s->length-2]; + dst[s->length+3]=dst[s->length-1]; + } else { + + dst[s->length]=dst[s->length-2]; + dst[s->length+1]=dst[s->length-1]; + } + + } break; + + } + + + } const DVector<uint8_t> SampleManagerMallocSW::sample_get_data(RID p_sample) const { diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 77d4da81d9..5b07c633c3 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -275,7 +275,7 @@ public: virtual void mesh_remove_surface(RID p_mesh,int p_index)=0; virtual int mesh_get_surface_count(RID p_mesh) const=0; - virtual AABB mesh_get_aabb(RID p_mesh) const=0; + virtual AABB mesh_get_aabb(RID p_mesh,RID p_skeleton=RID()) const=0; 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; diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp index e0c1932589..637c251cf1 100644 --- a/servers/visual/rasterizer_dummy.cpp +++ b/servers/visual/rasterizer_dummy.cpp @@ -561,7 +561,7 @@ int RasterizerDummy::mesh_get_surface_count(RID p_mesh) const { return mesh->surfaces.size(); } -AABB RasterizerDummy::mesh_get_aabb(RID p_mesh) const { +AABB RasterizerDummy::mesh_get_aabb(RID p_mesh,RID p_skeleton) const { Mesh *mesh = mesh_owner.get( p_mesh ); ERR_FAIL_COND_V(!mesh,AABB()); diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h index 01ae6c7644..373564249e 100644 --- a/servers/visual/rasterizer_dummy.h +++ b/servers/visual/rasterizer_dummy.h @@ -471,7 +471,7 @@ public: virtual void mesh_remove_surface(RID p_mesh,int p_index); virtual int mesh_get_surface_count(RID p_mesh) const; - virtual AABB mesh_get_aabb(RID p_mesh) const; + virtual AABB mesh_get_aabb(RID p_mesh,RID p_skeleton=RID()) const; virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb); virtual AABB mesh_get_custom_aabb(RID p_mesh) const; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 66862ece65..21ecd4030d 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -888,8 +888,17 @@ int VisualServerRaster::skeleton_get_bone_count(RID p_skeleton) const { void VisualServerRaster::skeleton_bone_set_transform(RID p_skeleton,int p_bone, const Transform& p_transform) { VS_CHANGED; - return rasterizer->skeleton_bone_set_transform(p_skeleton,p_bone,p_transform); + rasterizer->skeleton_bone_set_transform(p_skeleton,p_bone,p_transform); + Map< RID, Set<Instance*> >::Element *E=skeleton_dependency_map.find(p_skeleton); + + if (E) { + //detach skeletons + for (Set<Instance*>::Element *F=E->get().front();F;F=F->next()) { + + _instance_queue_update( F->get() , true); + } + } } Transform VisualServerRaster::skeleton_bone_get_transform(RID p_skeleton,int p_bone) { @@ -2113,8 +2122,17 @@ void VisualServerRaster::instance_attach_skeleton(RID p_instance,RID p_skeleton) VS_CHANGED; Instance *instance = instance_owner.get( p_instance ); ERR_FAIL_COND( !instance ); + + if (instance->data.skeleton.is_valid()) { + skeleton_dependency_map[instance->data.skeleton].erase(instance); + } + instance->data.skeleton=p_skeleton; + if (instance->data.skeleton.is_valid()) { + skeleton_dependency_map[instance->data.skeleton].insert(instance); + } + } RID VisualServerRaster::instance_get_skeleton(RID p_instance) const { @@ -2773,7 +2791,7 @@ void VisualServerRaster::_update_instance_aabb(Instance *p_instance) { } break; case VisualServer::INSTANCE_MESH: { - new_aabb = rasterizer->mesh_get_aabb(p_instance->base_rid); + new_aabb = rasterizer->mesh_get_aabb(p_instance->base_rid,p_instance->data.skeleton); } break; case VisualServer::INSTANCE_MULTIMESH: { @@ -3673,10 +3691,23 @@ void VisualServerRaster::free( RID p_rid ) { VS_CHANGED; - if (rasterizer->is_texture(p_rid) || rasterizer->is_material(p_rid) || rasterizer->is_skeleton(p_rid) || rasterizer->is_shader(p_rid)) { + if (rasterizer->is_texture(p_rid) || rasterizer->is_material(p_rid) || rasterizer->is_shader(p_rid)) { rasterizer->free(p_rid); - + } else if (rasterizer->is_skeleton(p_rid)) { + + Map< RID, Set<Instance*> >::Element *E=skeleton_dependency_map.find(p_rid); + + if (E) { + //detach skeletons + for (Set<Instance*>::Element *F=E->get().front();F;F=F->next()) { + + F->get()->data.skeleton=RID(); + } + skeleton_dependency_map.erase(E); + } + + rasterizer->free(p_rid); } else if (rasterizer->is_mesh(p_rid) || rasterizer->is_multimesh(p_rid) || rasterizer->is_light(p_rid) || rasterizer->is_particles(p_rid) ) { //delete the resource @@ -3763,6 +3794,8 @@ void VisualServerRaster::free( RID p_rid ) { instance_set_scenario(p_rid,RID()); instance_geometry_set_baked_light(p_rid,RID()); instance_set_base(p_rid,RID()); + if (instance->data.skeleton.is_valid()) + instance_attach_skeleton(p_rid,RID()); instance_owner.free(p_rid); memdelete(instance); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 2620225cc2..49e7996c59 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -610,7 +610,7 @@ class VisualServerRaster : public VisualServer { void _portal_disconnect(Instance *p_portal,bool p_cleanup=false); void _portal_attempt_connect(Instance *p_portal); void _dependency_queue_update(RID p_rid,bool p_update_aabb=false); - void _instance_queue_update(Instance *p_instance,bool p_update_aabb=false); + _FORCE_INLINE_ void _instance_queue_update(Instance *p_instance,bool p_update_aabb=false); void _update_instances(); void _update_instance_aabb(Instance *p_instance); void _update_instance(Instance *p_instance); @@ -640,7 +640,8 @@ class VisualServerRaster : public VisualServer { mutable RID_Owner<CanvasItem> canvas_item_owner; Map< RID, Set<RID> > instance_dependency_map; - + Map< RID, Set<Instance*> > skeleton_dependency_map; + ViewportRect viewport_rect; _FORCE_INLINE_ void _instance_draw(Instance *p_instance); |