summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2014-09-17 20:03:10 -0300
committerJuan Linietsky <reduzio@gmail.com>2014-09-17 20:03:10 -0300
commit990f6cf50e96213a4b1a2961e61a9b922cd75d71 (patch)
tree600fb659508e8745d7656416b24f89b2157a2630 /drivers
parent76aaa96d0e114d5293efed2fd0378ea390076b7e (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.cpp2
-rw-r--r--drivers/chibi/cp_player_data_events.cpp16
-rw-r--r--drivers/chibi/event_stream_chibi.cpp20
-rw-r--r--drivers/gles1/rasterizer_gles1.cpp2
-rw-r--r--drivers/gles1/rasterizer_gles1.h2
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp127
-rw-r--r--drivers/gles2/rasterizer_gles2.h40
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;