1 year ago

#367855

test-img

Arthur Sally

how do i interpolate keyframes into vectors with structs in Rust?

I started studying Rust and the "Glium" crate to use OpenGL, in the process I was trying to do something I had done before in Python when I needed to animate an asset.

In Python to animate an asset I loaded two frames of the same model in two different variables, then I did the keyframe interpolation like this:

frame1 = [0,0,..0,0,0] # The asset weighs around 50,000 points
frame2 = [1,2,..49997,49998,49999]
frame1 = np.array(frame1,np.float32)
frame2 = np.array(frame2,np.float32)
# interpolation
tframe = frame1*(1-time/ANIMATION_DURATION)+frame2*(time/ANIMATION_DURATION)
# And the OpenGL
glBufferSubData(GL_ARRAY_BUFFER, 0, len(tframe)*4, tframe)
# And Draw:
glDrawArrays(GL_TRIANGLES, 0, NUMBER_OF_POINTS)

Using this principle, I was able to get 3D models inside Python and OpenGL to be animated.

But recently I was trying to learn Rust and in the process I ended up discovering the Glium crate, which also uses OpenGL and I started testing things on it and most things worked very well. Until I try to do the interpolation there that I did in Python. To draw in Rust:

#[device(Copy,Clone)]
struct Vertex { position: [f32;3], texcoord:[f32;2] }
implement_vertex!(Vertex,position,texcoord);

And then we create a vector with the struct:

let v1 = Vertex{position:[-0.5,-0.5,0.0],texcoord:[0.0,0.0]};
let v2 = Vertex{position:[0.0,0.5,0.0],texcoord:[0.5,1.0]};
let v3 = Vertex{position:[0.5,-0.5,0.0],texcoord:[1.0,0.0]};
let shape = vec![v1,v2,v3];
let model = glium::VertexBuffer::new(&display, &shape).unwrap();

So we can draw it with the command:

target.draw(&model, &indices, &program, &u, &params).unwrap();

I already managed to make him draw, I already put texture, perspective, my doubt is not that. But how do I interpolate KeyFrames in Rust?

I tried doing it using a for loop, but it wasn't as fast as Python:

let mut vf = Vec::new();
for x in 0..50000{
    vf.push(Vertex{
        position:[
            v1[x].position[0]*(1 - time/DURATION)-v2[x].position[0]*(time/DURATION),
            v1[x].position[1]*(1 - time/DURATION)-v2[x].position[1]*(time/DURATION),
            v1[x].position[2]*(1 - time/DURATION)-v2[x].position[2]*(time/DURATION),
        ],
        texcoord:[
            v1[x].texcoord[0],
            v1[x].texcoord[1],
        ]
    });
}

I googled and even found a crate called interpolation that supposedly talks about this, but it doesn't accept vectors of structs.

I'm still new to Rust and I don't understand much of the language, but can someone tell me how I can get the interpolation thing to work? I'm talking about loading two pieces of information from the same model in different positions and then calculating the linear interpolation between them with a time variable. I just want to know how to make this work in Rust?

python

rust

linear-interpolation

glium

0 Answers

Your Answer

Accepted video resources