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 /drivers | |
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.
Diffstat (limited to 'drivers')
-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 |
7 files changed, 192 insertions, 17 deletions
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; |