예제 #1
0
triangle_index mesh_basic::connectivity(int const index) const
{
    ASSERT_CPE(index>=0,"Index ("+std::to_string(index)+") must be positive");
    ASSERT_CPE(index<size_connectivity(),"Index ("+std::to_string(index)+") must be less than the current size of the connectivity ("+std::to_string(size_connectivity())+")");

    return connectivity_data[index];
}
예제 #2
0
vec3& mesh_basic::vertex(int const index)
{
    ASSERT_CPE(index>=0,"Index ("+std::to_string(index)+") must be positive");
    ASSERT_CPE(index<size_vertex(),"Index ("+std::to_string(index)+") must be less than the current size of the vertices ("+std::to_string(size_vertex())+")");

    return vertex_data[index];
}
예제 #3
0
vec3& mesh_basic::color(int const index)
{
    ASSERT_CPE(index>=0,"Index ("+std::to_string(index)+") must be positive");
    ASSERT_CPE(index<size_color(),"Index ("+std::to_string(index)+") must be less than the current size of the colors ("+std::to_string(size_color())+")");

    return color_data[index];
}
예제 #4
0
vec2& mesh_basic::texture_coord(int const index)
{
    ASSERT_CPE(index>=0,"Index ("+std::to_string(index)+") must be positive");
    ASSERT_CPE(index<size_texture_coord(),"Index ("+std::to_string(index)+") must be less than the current size of the texture coordinates ("+std::to_string(size_texture_coord())+")");

    return texture_coord_data[index];
}
skinning_weight& vertex_weight_parameter::operator[](int const index)
{
    ASSERT_CPE(index>=0,"Index ("+std::to_string(index)+") must be positive");
    ASSERT_CPE(index<size(),"Index ("+std::to_string(index)+") must be less than the number of weight per vertex ("+std::to_string(size())+")");

    return weight_data[index];
}
예제 #6
0
vec3 mesh_basic::normal(int const index) const
{
    ASSERT_CPE(index>=0,"Index ("+std::to_string(index)+") must be positive");
    ASSERT_CPE(index<size_normal(),"Index ("+std::to_string(index)+") must be less than the current size of the normals ("+std::to_string(size_normal())+")");

    return normal_data[index];
}
예제 #7
0
vec3 mesh_parametric::normal(int const ku,int const kv) const
{
    ASSERT_CPE(ku >= 0 , "Value ku ("+std::to_string(ku)+") should be >=0 ");
    ASSERT_CPE(ku < size_u() , "Value ku ("+std::to_string(ku)+") should be < size_u ("+std::to_string(size_u())+")");
    ASSERT_CPE(ku >= 0 , "Value kv ("+std::to_string(kv)+") should be >=0 ");
    ASSERT_CPE(ku < size_v() , "Value kv ("+std::to_string(kv)+") should be < size_v ("+std::to_string(size_v())+")");

    int const offset = ku+size_u_data*kv;
    return mesh_basic::normal(offset);
}
예제 #8
0
void mesh_parametric_cloth::integration_step(float const dt)
{
    ASSERT_CPE(speed_data.size() == force_data.size(),"Incorrect size");
    ASSERT_CPE(static_cast<int>(speed_data.size()) == size_vertex(),"Incorrect size");


    int const Nu = size_u();//nombre de ressort
    int const Nv = size_v();//nombre de ressort
    //*************************************************************//
    // TO DO: Calculer l'integration numerique des positions au cours de l'intervalle de temps dt.
    //*************************************************************//

    //security check (throw exception if divergence is detected)
    static float const LIMIT=30.0f;
 for(int ku=0 ; ku<Nu; ++ku)
    {
        for(int kv=0; kv<Nv; ++kv)
        {
            vec3 & p = vertex(ku,kv);
            speed(ku,kv)=(1-mu*dt)*speed(ku,kv)+ dt*force(ku,kv);//gg c'est beau
            p = p + dt*speed(ku,kv);

            // collision avec le sol
            if (p.z() < -1.101f)// hauteur du sol
            {
                p.z()= -1.100f;
                force(ku,kv).z() = 0.0f;
                speed(ku,kv).z() = 0.0f;
            }
            // collision avec la sphere
            vec3 centre_sphere = {0.5f,0.05f,-1.1f};
            vec3 normale= p-centre_sphere;
            float rayon =0.4f;
            if (norm(normale)<rayon) {

                p= centre_sphere + normale/norm(normale) * rayon;
                //on annule la composante normale de la force  et de la vitesse

                speed(ku,kv) -= dot (speed(ku,kv),normale/norm(normale)) * normale;
                force(ku,kv) -= dot (force(ku,kv),normale/norm(normale)) * normale;




                //on annule la composante normale de la force  et de la vitesse

            }

        }
    }

}
예제 #9
0
vec3& mesh_parametric_cloth::force(int const ku,int const kv)
{
    ASSERT_CPE(ku >= 0 , "Value ku ("+std::to_string(ku)+") should be >=0 ");
    ASSERT_CPE(ku < size_u() , "Value ku ("+std::to_string(ku)+") should be < size_u ("+std::to_string(size_u())+")");
    ASSERT_CPE(kv >= 0 , "Value kv ("+std::to_string(kv)+") should be >=0 ");
    ASSERT_CPE(kv < size_v() , "Value kv ("+std::to_string(kv)+") should be < size_v ("+std::to_string(size_v())+")");

    int const offset = ku + size_u()*kv;

    ASSERT_CPE(offset < static_cast<int>(force_data.size()),"Internal error");

    return force_data[offset];
}
예제 #10
0
void line_opengl::init()
{

    shader_id_data = read_shader("shaders/shader_line.vert","shaders/shader_line.frag");

    vec3 line[]={ {0.0f,0.0f,0.0f} , {1.0f,0.0f,0.0f} };
    glGenBuffers(1,&vbo_data);                                             PRINT_OPENGL_ERROR();

    ASSERT_CPE(vbo_data!=0,"Problem creating VBO");

    glBindBuffer(GL_ARRAY_BUFFER,vbo_data);                                PRINT_OPENGL_ERROR();
    glBufferData(GL_ARRAY_BUFFER,6*sizeof(float),&line[0],GL_DYNAMIC_DRAW); PRINT_OPENGL_ERROR();

    ASSERT_CPE(glIsBuffer(vbo_data),"Problem creating VBO");
}
예제 #11
0
void mesh_opengl::update_vbo_texture(mesh_basic const& m)
{
    //VBO vertex
    glBindBuffer(GL_ARRAY_BUFFER,vbo_texture); PRINT_OPENGL_ERROR();
    ASSERT_CPE(glIsBuffer(vbo_texture),"vbo_buffer incorrect");

    glBufferSubData(GL_ARRAY_BUFFER,0,3*sizeof(float)*m.size_texture_coord(),m.pointer_texture_coord()); PRINT_OPENGL_ERROR();
}
예제 #12
0
void mesh_basic::fill_empty_field_by_default()
{
    int const N_vertex=size_vertex();

    if(size_normal()!=N_vertex)
        fill_normal();
    ASSERT_CPE(size_normal()==N_vertex,"Invalid normal computation");

    if(size_color()!=N_vertex)
        fill_color({0.8f,0.8f,0.8f});
    ASSERT_CPE(size_color()==N_vertex,"Invalid color set up");

    if(size_texture_coord()!=N_vertex)
    {
        texture_coord_data.clear();
        for(int k=0;k<N_vertex;++k)
            add_texture_coord({0.0f,0.0f});
    }

}
예제 #13
0
void mesh_basic::fill_normal()
{
    int const N_vertex=size_vertex();
    if(size_normal()!=N_vertex)
        normal_data.resize(N_vertex);

    //init normal data to 0
    for(auto& n : normal_data)
        n=vec3();

    //walk through all the triangles and add each triangle normal to the vertices
    int const N_triangle=size_connectivity();
    for(int k_triangle=0;k_triangle<N_triangle;++k_triangle)
    {
        //get current triangle index
        triangle_index const& tri=connectivity(k_triangle);

        //check that the index given have correct values
        ASSERT_CPE(tri.u0()>=0 && tri.u0()<N_vertex,"Incorrect triangle index");
        ASSERT_CPE(tri.u1()>=0 && tri.u1()<N_vertex,"Incorrect triangle index");
        ASSERT_CPE(tri.u2()>=0 && tri.u2()<N_vertex,"Incorrect triangle index");

        //compute current normal
        vec3 const& p0=vertex(tri.u0());
        vec3 const& p1=vertex(tri.u1());
        vec3 const& p2=vertex(tri.u2());

        vec3 const u1=normalized(p1-p0);
        vec3 const u2=normalized(p2-p0);
        vec3 const n=normalized(cross(u1,u2));

        //add the computed normal to the normal_data
        for(int kv=0;kv<3;++kv)
            normal_data[tri[kv]] += n;
    }

    //normalize all normal value
    for(auto& n : normal_data)
        n=normalized(n);

}
예제 #14
0
void line_opengl::draw(vec3 const& p0,vec3 const& p1)
{

    glBindBuffer(GL_ARRAY_BUFFER,vbo_data);
    ASSERT_CPE(glIsBuffer(vbo_data),"vbo incorrect");

    vec3 line[]={p0,p1};

    glBufferData(GL_ARRAY_BUFFER,6*sizeof(float),&line[0],GL_DYNAMIC_DRAW); PRINT_OPENGL_ERROR();
    glVertexPointer(3, GL_FLOAT, 0, 0); PRINT_OPENGL_ERROR();
    glDrawArrays(GL_LINES,0,2);
}
예제 #15
0
void mesh_parametric::set_plane_xy_unit(int const size_u_param,int const size_v_param)
{
    ASSERT_CPE(size_u_param>0 && size_v_param>0 , "Problem of mesh size");
    size_u_data = size_u_param;
    size_v_data = size_v_param;

    //set data
    for(int kv=0 ; kv<size_v_param ; ++kv)
    {
        float const v = static_cast<float>(kv)/(size_v_param-1);
        for(int ku=0 ; ku<size_u_param ; ++ku)
        {
            float const u = static_cast<float>(ku)/(size_u_param-1);

            add_vertex( {u,v,0.0f} );
            add_texture_coord( {u,v} );
            add_normal( {0.0f,0.0f,1.0f} );
        }
    }

    //set connectivity
    for(int kv=0 ; kv<size_v_param-1 ; ++kv)
    {
        for(int ku=0 ; ku<size_u_param-1 ; ++ku)
        {
            int const offset = ku+size_u_param*kv;
            triangle_index tri0 = {offset,offset+1,offset+size_u_param+1};
            triangle_index tri1 = {offset,offset+size_u_param+1,offset+size_u_param};

            add_triangle_index(tri0);
            add_triangle_index(tri1);
        }
    }

    fill_empty_field_by_default();

    ASSERT_CPE(valid_mesh(),"Mesh is not valid");
}
ivec2::ivec2(std::initializer_list<int> const& arg)
    :x_data(0),y_data(0)
{
    ASSERT_CPE(arg.size()>=2,"initializer list should have at least 2 arguments");

    int counter=0;
    for(int v : arg)
    {
        if(counter==0)
            x_data=v;
        else if(counter==1)
            y_data=v;
        counter++;
    }
}
예제 #17
0
void mesh_parametric_cloth::update_force()
{

    int const Nu = size_u();
    int const Nv = size_v();
    int const N_total = Nu*Nv;
    ASSERT_CPE(static_cast<int>(force_data.size()) == Nu*Nv , "Error of size");
    //wind direction
    vec3 uw=vec3( x_wind,y_wind,z_wind);
    uw= normalized(uw);

    //Gravity and wind
    static vec3 const g (0.0f,0.0f,-9.81f);
    vec3 const g_normalized = g/N_total;
    for(int ku=0 ; ku<Nu ; ++ku)
    {
        for(int kv=0 ; kv<Nv ; ++kv)
        {

            force(ku,kv) = g_normalized;


            vec3 n=this->normal(ku,kv);
            force(ku,kv) += Kw*dot(n,uw)*n;
        }
    }

    //*************************************************************//
    // TO DO, Calculer les forces s'appliquant sur chaque sommet
    //*************************************************************//
    //*************************************************************//
    float L01= 1.0f/(Nu-1);
    float L02= sqrt(2)/(Nu-1);
    float L03= 2.0f/(Nu-1);

    for(int ku=0 ; ku<Nu; ++ku)
    {
        for(int kv=0 ; kv<Nv; ++kv)
        {

            vec3 const& p = vertex(ku,kv);
            std::vector<vec3> pvd;
            std::vector<vec3> pvdiag;
            std::vector<vec3> pvb;

            /** cas general **/
            //voisin directs
            if( kv < Nv-1) {
                pvd.push_back(vertex(ku,kv+1));
            }
            if( kv > 0) {
                pvd.push_back(vertex(ku,kv-1));
            }
            if( ku < Nu-1) {
                pvd.push_back(vertex(ku+1,kv));
            }
            if( ku > 0) {
                pvd.push_back(vertex(ku-1,kv));
            }
            //voisin diagonale
            if( ku< Nu -1 && kv < Nv-1 ) {
                pvdiag.push_back(vertex(ku+1,kv+1));
            }
            if( ku < Nu-1 && kv >0 ) {
                pvdiag.push_back(vertex(ku+1,kv-1));
            }
            if( ku > 0 && kv > 0 ) {
                pvdiag.push_back(vertex(ku-1,kv-1));
            }
            if( ku>0 && kv< Nu -1) {
                pvdiag.push_back(vertex(ku-1,kv+1));
            }

            //voisin bend
            if( ku < Nu -2) {
                pvb.push_back(vertex(ku+2,kv));
            }
            if( ku >1 ) {
                pvb.push_back(vertex(ku-2,kv));

            }
            if( kv < Nv -2) {
                pvb.push_back(vertex(ku,kv+2));
            }
            if( kv >1 ) {
                pvb.push_back(vertex(ku,kv-2));
            }



            for (int i=0; i<int(pvd.size());i++) {
                vec3 u=p-pvd[i];
                force(ku,kv)  += (Kdirect *(L01 - norm(u)) *u) /norm(u);
            }
            for (int i=0; i<int (pvdiag.size());i++) {
                vec3 u=p-pvdiag[i];
                force(ku,kv)  +=( Kdiag *(L02 - norm(u))*u) /norm(u);
            }
            for (int i=0; i<int (pvb.size());i++) {
                vec3 u=p-pvb[i];
                force(ku,kv)  +=( Kdouble *(L03 - norm(u))*u) /norm(u);
            }


            // on bloque les angles
           if ((ku == 0 && kv == 0 ) || (ku == 0 && kv == Nv -1)) {
            //if ((ku == Nu-1 && kv == Nv-1 )||(ku == Nu-1 && kv == 0 )||(ku == 0 && kv == 0 ) || (ku == 0 && kv == Nv -1)) {

                force(ku,kv) = vec3(0.0f,0.0f, 0.0f);
            }
        }
    }

}
예제 #18
0
float const* mesh_basic::pointer_texture_coord() const
{
    ASSERT_CPE(size_texture_coord()>0,"No texture coord");
    return texture_coord_data[0].pointer();
}
예제 #19
0
void mesh_opengl::fill_vbo(mesh_basic const& m)
{
    if(m.valid_mesh()!=true)
        throw cpe::exception_cpe("Mesh is considered as invalid, cannot fill vbo",EXCEPTION_PARAMETERS_CPE);

    number_of_triangles=m.size_connectivity();
    if(number_of_triangles<=0)
        throw cpe::exception_cpe("incorrect number of triangles",MACRO_EXCEPTION_PARAMETER);

    //create the new vbo
    if(vbo_vertex==0)
    {glGenBuffers(1,&vbo_vertex);PRINT_OPENGL_ERROR();}
    ASSERT_CPE(vbo_vertex!=0,"Problem creation of VBO");

    if(vbo_normal==0)
    {glGenBuffers(1,&vbo_normal);PRINT_OPENGL_ERROR();}
    ASSERT_CPE(vbo_normal!=0,"Problem creation of VBO");

    if(vbo_color==0)
    {glGenBuffers(1,&vbo_color);PRINT_OPENGL_ERROR();}
    ASSERT_CPE(vbo_color!=0,"Problem creation of VBO");

    if(vbo_texture==0)
    {glGenBuffers(1,&vbo_texture);PRINT_OPENGL_ERROR();}
    ASSERT_CPE(vbo_texture!=0,"Problem creation of VBO");

    if(vbo_index==0)
    {glGenBuffers(1,&vbo_index);PRINT_OPENGL_ERROR();}
    ASSERT_CPE(vbo_index!=0,"Problem creation of VBO");



    //VBO vertex
    glBindBuffer(GL_ARRAY_BUFFER,vbo_vertex); PRINT_OPENGL_ERROR();
    if(!glIsBuffer(vbo_vertex))
        throw cpe::exception_cpe("vbo_buffer incorrect",EXCEPTION_PARAMETERS_CPE);
    glBufferData(GL_ARRAY_BUFFER,3*sizeof(float)*m.size_vertex(),m.pointer_vertex(),GL_DYNAMIC_DRAW); PRINT_OPENGL_ERROR();

    //VBO normal
    glBindBuffer(GL_ARRAY_BUFFER,vbo_normal); PRINT_OPENGL_ERROR();
    if(!glIsBuffer(vbo_normal))
        throw cpe::exception_cpe("vbo_normal incorrect",EXCEPTION_PARAMETERS_CPE);
    glBufferData(GL_ARRAY_BUFFER,3*sizeof(float)*m.size_normal(),m.pointer_normal(),GL_DYNAMIC_DRAW); PRINT_OPENGL_ERROR();

    //VBO color
    glBindBuffer(GL_ARRAY_BUFFER,vbo_color); PRINT_OPENGL_ERROR();
    if(!glIsBuffer(vbo_color))
        throw cpe::exception_cpe("vbo_color incorrect",EXCEPTION_PARAMETERS_CPE);
    glBufferData(GL_ARRAY_BUFFER,3*sizeof(float)*m.size_color(),m.pointer_color(),GL_DYNAMIC_DRAW); PRINT_OPENGL_ERROR();

    //VBO texture
    glBindBuffer(GL_ARRAY_BUFFER,vbo_texture); PRINT_OPENGL_ERROR();
    if(!glIsBuffer(vbo_texture))
        throw cpe::exception_cpe("vbo_texture incorrect",EXCEPTION_PARAMETERS_CPE);
    glBufferData(GL_ARRAY_BUFFER,2*sizeof(float)*m.size_texture_coord(),m.pointer_texture_coord(),GL_DYNAMIC_DRAW); PRINT_OPENGL_ERROR();

    //VBO index
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vbo_index); PRINT_OPENGL_ERROR();
    if(!glIsBuffer(vbo_index))
        throw cpe::exception_cpe("vbo_index incorrect",EXCEPTION_PARAMETERS_CPE);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,3*sizeof(int)*m.size_connectivity(),m.pointer_triangle_index(),GL_DYNAMIC_DRAW); PRINT_OPENGL_ERROR();

}
예제 #20
0
float const* mesh_basic::pointer_vertex() const
{
    ASSERT_CPE(size_vertex()>0,"No vertex");
    return vertex_data[0].pointer();
}
예제 #21
0
float const* mesh_basic::pointer_normal() const
{
    ASSERT_CPE(size_normal()>0,"No normal");
    return normal_data[0].pointer();
}
예제 #22
0
float const* mesh_basic::pointer_color() const
{
    ASSERT_CPE(size_color()>0,"No color");
    return color_data[0].pointer();
}
예제 #23
0
int const* mesh_basic::pointer_triangle_index() const
{
    ASSERT_CPE(size_connectivity()>0,"No connectivity");
    return connectivity_data[0].pointer();
}