Go to the documentation of this file.00001 #ifndef OPENTISSUE_KINEMATICS_SKINNING_SBS_SKINNING_SBS_GPU_H
00002 #define OPENTISSUE_KINEMATICS_SKINNING_SBS_SKINNING_SBS_GPU_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/containers/mesh/trimesh/trimesh.h>
00013 #include <OpenTissue/core/containers/mesh/trimesh/util/trimesh_util.h>
00014
00015 #include <OpenTissue/kinematics/skinning/sbs/skinning_center_of_rotation.h>
00016 #include <OpenTissue/kinematics/skinning/skinning_traits.h>
00017
00018 #include <cassert>
00019 #include <vector>
00020
00021
00022 #include <OpenTissue/gpu/cg/cg_program.h>
00023
00024 namespace OpenTissue
00025 {
00026 namespace skinning
00027 {
00028
00029 template<typename types>
00030 class SBSGPU
00031 : public trimesh::TriMesh<types,SkinVertexTraits<types> ,SkinFaceTraits<types>, trimesh::TriMeshArrayKernel >
00032 {
00033 public:
00034
00035
00036 typedef int gpu_support;
00037
00038 typedef typename types::matrix3x3_type matrix3x3_type;
00039 typedef typename types::quaternion_type quaternion_type;
00040 typedef typename types::vector3_type vector3_type;
00041 typedef typename types::real_type real_type;
00042
00043
00044 typedef trimesh::TriMesh<types, SkinVertexTraits<types>, SkinFaceTraits<types>, OpenTissue::trimesh::TriMeshArrayKernel > base_mesh;
00045
00046
00047 typedef OpenTissue::cg::Program Program;
00048
00049 public:
00050
00051 int m_material_idx;
00052
00053 public:
00054
00055 SBSGPU()
00056 : m_material_idx(-1)
00057 {}
00058
00059 public:
00060
00061 bool empty() const
00062 {
00063 return (!(base_mesh::size_faces()>0));
00064 }
00065
00066 template<typename skin_container_type>
00067 static void init_skin_render( skin_container_type & scont )
00068 {
00069 gl::gl_check_errors( "init_rendering: called" );
00070
00071
00072 OpenTissue::cg::startup();
00073
00074
00075 std::string filename =
00076 opentissue_path +
00077 "/OpenTissue/kinematics/skinning/SBS/sbs_skin_shader.cg";
00078 scont.m_vp.load_from_file( cg::Program::vertex_program, filename );
00079 gl::gl_check_errors( "init_fragment_program: program loaded" );
00080 }
00081
00082 template<typename skin_container_type>
00083 static void cleanup_skin_render( skin_container_type & scont )
00084 {
00085 gl::gl_check_errors("cleanup_rendering: called");
00086 OpenTissue::cg::shutdown();
00087 }
00088
00089
00090 template<typename skin_container_type>
00091 static void pre_render( skin_container_type & scont )
00092 {
00093 scont.m_vp.set_modelview_projection_matrix();
00094 scont.m_vp.set_modelview_inverse_transpose();
00095
00096 scont.m_vp.enable();
00097
00098 scont.m_uploadBones = true;
00099 scont.m_uploadRc = true;
00100
00101
00102 scont.m_rc_cached.clear();
00103 scont.m_rc_lut.clear();
00104 }
00105
00106 template<typename skin_container_type>
00107 static void post_render( skin_container_type & scont )
00108 {
00109 scont.m_vp.disable();
00110 }
00111
00121
00122 template<typename skeleton_type, typename skin_container_type>
00123 void update( skeleton_type & skeleton, skin_container_type & scont )
00124 {
00125 typedef typename skeleton_type::bone_traits bone_traits;
00126 typedef typename types::coordsys_type coordsys_type;
00127
00128
00129 if(this->empty())
00130 return;
00131
00132 typedef typename skin_container_type::lut_type lut_type;
00133 typedef typename skeleton_type::bone_type bone_type;
00134 typedef std::vector<bone_type const *> bone_container_type;
00135
00136 if( scont.m_uploadBones )
00137 {
00138
00139 float *allBones = new float[9*skeleton.size()];
00140 unsigned int k=0;
00141
00142
00143 typename skeleton_type::bone_iterator abone = skeleton.begin();
00144 typename skeleton_type::bone_iterator boneEnd = skeleton.end();
00145
00146 for( ; abone!=boneEnd; ++abone )
00147 {
00148 coordsys_type bone_space_transform = bone_traits::convert( abone->bone_space_transform() );
00149
00150 quaternion_type qt = bone_space_transform.Q();
00151 vector3_type trans = bone_space_transform.T();
00152
00153
00154 allBones[0+k*9] = qt.v()(0);
00155 allBones[1+k*9] = qt.v()(1);
00156 allBones[2+k*9] = qt.v()(2);
00157 allBones[3+k*9] = qt.s();
00158 allBones[4+k*9] = 0;
00159 allBones[5+k*9] = 0;
00160 allBones[6+k*9] = trans( 0 );
00161 allBones[7+k*9] = trans( 1 );
00162 allBones[8+k*9] = trans( 2 );
00163
00164
00165 ++k;
00166 }
00167
00168
00169 scont.m_vp.set_floatNxN_array_param( "bones", (int)skeleton.size(), allBones );
00170
00171
00172 delete[] allBones;
00173
00174 scont.m_uploadBones = false;
00175 }
00176
00177 if( scont.m_uploadRc )
00178 {
00179 typename base_mesh::vertex_iterator vertex = base_mesh::vertex_begin();
00180 typename base_mesh::vertex_iterator end = base_mesh::vertex_end();
00181 bone_container_type affecting_bones;
00182
00183 for(;vertex!=end;++vertex)
00184 {
00185 if( vertex->m_influences > 1 )
00186 {
00187
00188 affecting_bones.clear();
00189
00190 vector3_type r_c( 0, 0, 0 );
00191
00192 for(int i=0; i < vertex->m_influences; ++i)
00193 {
00194 bone_type const * bone = skeleton.get_bone( vertex->m_bone[i] );
00195 affecting_bones.push_back( bone );
00196 }
00197
00198
00199 typename lut_type::iterator lut_it = scont.m_rc_lut.find( vertex->m_key );
00200 if( lut_it != scont.m_rc_lut.end() )
00201 r_c = scont.m_rc_cached[lut_it->second];
00202 else
00203 {
00204
00205 r_c = center_of_rotation( skeleton, affecting_bones );
00206
00207
00208 scont.m_rc_cached.push_back( r_c );
00209 scont.m_rc_lut[vertex->m_key] = scont.m_rc_cached.size()-1;
00210 }
00211
00212 }
00213 }
00214
00215
00216 if( scont.m_rc_lut.size() == scont.m_num_keys )
00217 {
00218
00219 float *allRc = new float[3*scont.m_rc_lut.size()];
00220
00221 typename lut_type::iterator lut_it = scont.m_rc_lut.begin();
00222 for( ; lut_it != scont.m_rc_lut.end(); ++lut_it )
00223 {
00224 size_t idx = lut_it->second;
00225 vector3_type r_c = scont.m_rc_cached[idx];
00226
00227 allRc[3*idx] = r_c(0);
00228 allRc[3*idx+1] = r_c(1);
00229 allRc[3*idx+2] = r_c(2);
00230
00231 }
00232
00233
00234 scont.m_vp.set_float3_array_param( "r_c", (int)scont.m_rc_lut.size(), allRc );
00235
00236 delete[] allRc;
00237
00238 scont.m_uploadRc = false;
00239 }
00240 }
00241
00242 }
00243 };
00244
00245 }
00246 }
00247
00248
00249 #endif