Customise Consent Preferences

We use cookies to help you navigate efficiently and perform certain functions. You will find detailed information about all cookies under each consent category below.

The cookies that are categorised as "Necessary" are stored on your browser as they are essential for enabling the basic functionalities of the site. ... 

Always Active

Necessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data.

No cookies to display.

Functional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features.

No cookies to display.

Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc.

No cookies to display.

Performance cookies are used to understand and analyse the key performance indexes of the website which helps in delivering a better user experience for the visitors.

No cookies to display.

Advertisement cookies are used to provide visitors with customised advertisements based on the pages you visited previously and to analyse the effectiveness of the ad campaigns.

No cookies to display.

[ad_1]

I am making an attempt to do Skeleton Animation utilizing OpenGL and Rust, loading from a gltf file. And issues aren’t understanding very effectively. I do not know if the issue is within the file I am utilizing, if it is within the code or if it is in the way in which I load the knowledge.

That is the gltf file I am utilizing, it has a male basemesh mannequin with a “strolling” animation that I loaded from Mixamo:
ANDAR.gltf

I used the gl library in rust to program.

To load the knowledge into the VBO, I used the next perform:

fn CarregarGltf(tudo : &mut Vec<f32>, modelo : &str){
    let local_exe = std::env::current_dir().unwrap();
    let native = local_exe.show();
    let original_tamanho = tudo.len()/19;
    let (gltf, buffers, _) = gltf::import(format!("extras/{}.gltf",modelo)).unwrap();
    for m in gltf.meshes(){
        for p in m.primitives(){
            let r = p.reader(|buffer| Some(&buffers[buffer.index()]));
            let mut indices = Vec::new();
            if let Some(gltf::mesh::util::ReadIndices::U16(gltf::accessor::Iter::Customary(iter))) = r.read_indices(){
                for v in iter{
                    indices.push(v);
                }
            }
            let mut posicao = Vec::new();
            if let Some(iter) = r.read_positions(){
                for v in iter{
                    posicao.push(v);
                }
            }
            let mut textura = Vec::new();
            if let Some(gltf::mesh::util::ReadTexCoords::F32(gltf::accessor::Iter::Customary(iter))) = r.read_tex_coords(0){
                for v in iter{
                    textura.push(v);
                }
            }
            let mut normais = Vec::new();
            if let Some(iter) = r.read_normals(){
                for v in iter{
                    normais.push(v);
                }
            }
            let mut ossosid = Vec::new();
            if let Some(gltf::mesh::util::ReadJoints::U8(gltf::accessor::Iter::Customary(iter))) = r.read_joints(0){
                for v in iter{
                    ossosid.push(v);
                }
            }
            let mut pesos = Vec::new();
            if let Some(gltf::mesh::util::ReadWeights::F32(gltf::accessor::Iter::Customary(iter))) = r.read_weights(0){
                for v in iter{
                    pesos.push(v);
                }
            }
            for q in indices{
                // posição
                tudo.push(posicao[q as usize][0] as f32);
                tudo.push(posicao[q as usize][1] as f32);
                tudo.push(posicao[q as usize][2] as f32);
                // textura
                tudo.push(textura[q as usize][0] as f32);
                tudo.push(textura[q as usize][1] as f32);
                // normais
                tudo.push(normais[q as usize][0] as f32);
                tudo.push(normais[q as usize][1] as f32);
                tudo.push(normais[q as usize][2] as f32);
                // ossosid
                tudo.push(ossosid[q as usize][0] as f32);
                tudo.push(ossosid[q as usize][1] as f32);
                tudo.push(ossosid[q as usize][2] as f32);
                tudo.push(ossosid[q as usize][3] as f32);
                // pesos
                tudo.push(pesos[q as usize][0]);
                tudo.push(pesos[q as usize][1]);
                tudo.push(pesos[q as usize][2]);
                tudo.push(pesos[q as usize][3]);
                // aoffset
                tudo.push(0.0);
                tudo.push(0.0);
                tudo.push(0.0);
            }
        }
    }
    println!("VBO do "{}" : {}, {}", modelo, original_tamanho, tudo.len()/19-original_tamanho);
}

So as, it carries place, texture, regular, bones, affect weights and one final piece of data that’s not related in the mean time. The target was for the mannequin to be prepared in order that I may then apply the strolling animation transformations to it.

To load the animation, I used a separate perform that might hold the animation code separate within the code, right here is the perform:

fn CarregarAnimacao(modelo : &str) -> (Vec<Vec<f32>>,Vec<Vec<f32>>,Vec<Vec<f32>>){
    let (knowledge, buffers, _) = gltf::import(format!("extras/{}.gltf",modelo)).unwrap();
    let mut translate : Vec<Vec<f32>> = Vec::new();
    let mut rotations : Vec<Vec<f32>> = Vec::new();
    let mut scales : Vec<Vec<f32>> = Vec::new();
    for a in knowledge.animations(){
        for c in a.channels(){
            let r = c.reader(|buffer| Some(&buffers[buffer.index()]));
            let kt = if let Some(inputs) = r.read_inputs(){
                match inputs{
                    gltf::accessor::Iter::Customary(occasions) =>{
                        let occasions : Vec<f32> = occasions.acquire();
                    },
                    gltf::accessor::Iter::Customary(_) => todo!(),
                    gltf::accessor::Iter::Sparse(_) => todo!()
                }
            };
            let okay = if let Some(outputs) = r.read_outputs(){
                match outputs{
                    gltf::animation::util::ReadOutputs::Translations(translation) => {
                        translation.for_each(|tr|{
                            let v : Vec<f32> = tr.into();
                            translate.push(v);
                        });
                    },
                    gltf::animation::util::ReadOutputs::Rotations(rotation) => {
                        for r in rotation.into_f32(){
                            rotations.push(r.into());
                        }
                    },
                    gltf::animation::util::ReadOutputs::Scales(scale) => {
                        scale.for_each(|tr|{
                            let v : Vec<f32> = tr.into();
                            scales.push(v);
                        });
                    },
                    different => ()
                }
            };
        }
    }
    (rotations,translate,scales)
}

In flip, it masses the Rotation and Translation data from the identical file “ANDAR.gltf” and retains it in a variable within the code. Then I cross them to the code utilizing the next code snippet:

let andar = CarregarAnimacao("ANDAR"); // Rotação, Translate, Escala
unsafe{
    for i in 0..65{
        gl::Uniform3f(gl::GetUniformLocation(shader,std::ffi::CString::new(format!("ANIMACAO1[{}]",i)).unwrap().as_ptr()), andar.1[i*26+10][0], andar.1[i*26+10][1], andar.1[i*26+10][2]);
        gl::Uniform3f(gl::GetUniformLocation(shader,std::ffi::CString::new(format!("ANIMACAO2[{}]",i)).unwrap().as_ptr()), andar.0[i*26+10][0], andar.0[i*26+10][1], andar.0[i*26+10][2]);
    }
}

I am not very used to utilizing 4×4 matrices when programming vertex_shader, I attempted to create my model of the code from https://learnopengl.com/Visitor-Articles/2020/Skeletal-Animation when within the shader I used the next logic:

for(int i = 0; i < 4; i++){
    if(ossosid[i] == -1){
        proceed;
    }
    if(ossosid[i] >= 65){
        break;
    }
    pos = pos+ANIMACAO1[int(ossosid[i])]*pesos[i];
    // Rotate on the x axis
    pos = vec3(pos.x,pos.y*cos(ANIMACAO2[int(ossosid[i])][0]*pi/180)-pos.z*sin(ANIMACAO2[int(ossosid[i])][0]*pi/180),pos.z*cos(ANIMACAO2[int(ossosid[i])][0]*pi/180)+pos.y*sin(ANIMACAO2[int(ossosid[i])][0]*pi/180));
    // Different features to rotate the place.
    // ...
}

Anyway, on this context, the outcome that got here out ultimately was a physique that, earlier than making use of the animation transformations, appeared intact and regular… However then it was so distorted that it was troublesome to interpret.

From then on, I attempted a collection of different variations within the code utilizing different websites as a base resembling https://lisyarus.github.io/weblog/graphics/2023/07/03/gltf-animation.html however I nonetheless could not obtain a constant outcome.

My query is… How do I make the animation work?

[ad_2]

Leave a Reply

Your email address will not be published. Required fields are marked *