Page flipping effect

Hi everyone

I’m working on an openframeworks application on ubuntu.
I have a set of images that will be shown to the user and they can change to the next/previous image by pressing a key.

What I want to do is to have a page flipping effect, like when the pages of a real physical book are changed when you browse to a new page.

What I had in mind was to have a mesh, cut the image in half into 2 rectangles, have the 2 most left points move to the center (to give it a folding effect) and when they reach there, have both the rectangles move to the left together.

I’m not sure what I’m doing wrong but it doesn’t look the way it should. Here’s a clip of what it looks like right now when the user changes the page :

Link to youtube clip

and here’s my code :

//--------------------------------------------------------------
void ofApp::setup()
{
    image.loadImage("image1.jpg");
    image.resize(600,700);

    image2.loadImage("image2.jpg");
    image2.resize(600,700);

    resetImage();
}

//--------------------------------------------------------------
void ofApp::update()
{

}

//--------------------------------------------------------------
void ofApp::draw()
{
    //DRAW THE UNDERLYING IMAGE
    ofSetColor(255,255,255,255);
    image2.draw(100,20);

    //DRAW THE TOP IMAGE
    drawImage();
}

//--------------------------------------------------------------
void ofApp::drawImage()
{
    ofPoint imageLocation(100,20);
    ofPath path;
    path.setFilled(true);
    //MAKE 2 RECTANGELS SO THE RIGHT ONE FOLDS ON THE LEFT ONE AND THEN THEY BOTH FOLD TOGETHER
    path.rectangle(100,20,meshWidth/2,700);
    path.rectangle(100+meshWidth/2,20,meshWidth/2,700);
    path.close();

    ofMesh mesh;
    mesh=path.getTessellation();

    for (int i=0; i<mesh.getNumVertices(); i++)
    {
        ofPoint vertPos = mesh.getVertex(i);
        ofPoint uvPos;
        uvPos = vertPos-imageLocation;
        if (imageChanging==true)
        {
            if (meshx1>100)
            {
                //THE RIGHT RECTANGLE IS FOLDED, NOW MOVE BOTH OF THEM TOGETHER
                if (i==0 || i==3)
                {
                    
                    meshx2*=1.2;
                    //meshx1/=1.5;
                    uvPos.x+=meshx2*10;
                    uvPos.y+=meshx2*10;
                }
                else if (i==1 || i==2)
                {
                
                    meshx2*=1.2;
                    uvPos.x+=meshx2*10+meshx1*10;
                    uvPos.y+=meshx2*10+meshx1*10;
                }
            }
            else if (i==1 || i==2)
            {
                //THE RIGHT MOST POINTS OF THE RIGHT RECTANGLE
                //THIS CODE RUNS FIRST AND WHEN MESHX >100 ALL THE FOUR POINTS MOVE TOGETHER
                meshx1*=1.2;
                uvPos.x+=meshx1*10;
                uvPos.y+=meshx1*10;
            }
            meshWidth-=5;

        }
        mesh.addTexCoord(uvPos);
    }
    imageColor.set(255,255,255,alpha);
    ofSetColor(imageColor);
    image.bind();
        mesh.draw();
    image.unbind();
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key)
{
    if (key==114)
    {
        imageChanging=true;
        ofSetFrameRate(2);
    }
    if (key==115)
    {
        resetImage();
    }
}

//--------------------------------------------------------------
void ofApp::resetImage()
{
    imageChanging=false;
    ofSetFrameRate(60);
    meshx1=1;
    meshx2=1;
    meshWidth=600;
    alpha=255;
    ofColor tmp(255,255,255);
    imageColor=tmp;
}

I first thought of breaking the mesh into vertical rectangles and moving them one by one from the right but that seems more complicated.

Could someone guide me on how to do this the right way?
Thanks in advance

Hi again !

I tried a different approach after seeing this clip https://www.youtube.com/watch?v=ixiekkOD_es.

My current result is this :

https://www.youtube.com/watch?v=GdwkwfLKo0Q

It still doesn’t have that impression of flipping the page! Basically what I do is draw a white rectangle and move it along with resizing my mesh
.
This is my updated code :

//--------------------------------------------------------------
void ofApp::draw()
{
    ofSetColor(255,255,255,255);
    //DRAW THE BOTTOM IMAGE
    image2.draw(100,20);

    //DRAW THE TOP IMAGE THAT IS TO BE FLIPPED
    drawImage();

    if (imageChanging==true)
    {
        fadeImage();
    }
}

//--------------------------------------------------------------
void ofApp::drawImage()
{
    ofPoint imageLocation(100,20);
    ofPath path;
    path.setFilled(true);
    path.rectangle(100+rectIndex,20,meshWidth-rectIndex,700);
    //path.rectangle(100,20,600,700);
    path.close();
    ofMesh mesh;

    mesh=path.getTessellation();

    for (int i=0; i<mesh.getNumVertices(); i++)
    {
        ofPoint vertPos = mesh.getVertex(i);
        ofPoint uvPos;
        uvPos = vertPos-imageLocation;
        mesh.addTexCoord(uvPos);
    }
    imageColor.set(255,255,255,alpha);
    ofSetColor(imageColor);
    image.bind();
        mesh.draw();
    image.unbind();
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key)
{
    if (key==114)
    {
        imageChanging=true;
    }
    if (key==115)
    {
        resetImage();
    }
}
//--------------------------------------------------------------
void ofApp::fadeImage()
{
    float x,y,width,height;
    x=100;
    y=20;
    width=meshWidth;
    height=700;
    ofSetColor(240);
    ofRect(x+rectIndex,y,rectWidth,height);
    if (rectIndex+rectWidth+4<meshWidth)
        rectWidth+=4;
    else
        rectWidth=meshWidth-rectIndex;
    rectIndex+=4;

    if (rectIndex==meshWidth)
    {
        imageChanging=false;
    }
    if (alpha<0)
    {
        alpha=0;
        ofSetFrameRate(60);
        imageChanging=false;
    }
}

Can any give me any suggestion on how to make this right ?

Thanks in advance

I think the way apple does it is in 3d. It is based upon this paper