# Rolling and pitching Marble

I have created a sphere, which rolls and pitches as user wish !! Need quick help !!

Here is the code :

``````
#include"windows.h"
#include"GL/glut.h"
#include"math.h"

bool* keyBuffer = new bool[256],wired=false,isJumping=false;        // Key buffer to process arrow keys
float theta[]={0.0,0.0,0.0};                        // Rotating sphere
float size=20.0;                                    // Sphere longitude and latitude size
float eyeX=0.0,eyeY=0.5,eyeZ=4.0;                   // Camera eye
float atX=0.0,atY=0.5,atZ=0.0;                      // Center of projection : Look at

void causeDelay(){
for(int i=0;i<4000;i++)
for(int j=0;j<4500;j++);
}

// Spins marble around based on axis and amount of fraction
void spin(int axis,float fraction){
theta[axis]=fmod((theta[axis]+fraction),360.0);
}

// Moves marble forward and backward based on fraction param
void moveSphere(float fraction){
float dirX,dirZ;
dirX=atX-eyeX;
dirZ=atZ-eyeZ;
eyeX += dirX * fraction;
eyeZ += dirZ * fraction;
atX += dirX * fraction;
atZ += dirZ * fraction;
}

// Strafes marble left and right based on fraction param
void strafeSphere(float fraction){
float orthoX,orthoZ;
orthoX = -(atZ-eyeZ);
orthoZ = atX-eyeX;
eyeX += orthoX * fraction;
eyeZ += orthoZ * fraction;
atX += orthoX * fraction;
atZ += orthoZ * fraction;
}

// Rotate the camera
void rotateView(float fraction){
float dirX,dirZ;
dirX = atX - eyeX;
dirZ = atZ - eyeZ;
atZ = eyeZ + sin(fraction) * dirX + cos(fraction) * dirZ;
atX = eyeX + cos(fraction) * dirX - sin(fraction) * dirZ;
dirX = eyeX - atX;
dirZ = eyeZ - atZ;
eyeZ = atZ + sin(fraction) * dirX + cos(fraction) * dirZ;
eyeX = atX + cos(fraction) * dirX - sin(fraction) * dirZ;
}

// Procesess the active arrow keys
void processKeys(){
if(keyBuffer[GLUT_KEY_UP]){
spin(0,1.0);
moveSphere(0.01);
}
if(keyBuffer[GLUT_KEY_DOWN]){
spin(0,-1.0);
moveSphere(-0.01);
}
if(keyBuffer[GLUT_KEY_LEFT]){
spin(2,0.5);
strafeSphere(-0.01);
}
if(keyBuffer[GLUT_KEY_RIGHT]){
spin(2,-0.5);
strafeSphere(0.01);
}
}

// Renders the marble
void renderSphere(){
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushMatrix();
glColor3f(1.0,1.0,1.0);
if(wired)
else
glPopMatrix();
glPopAttrib();
}

// Renders the map
void renderBase(){
glColor3f(0.0,0.0,1.0);
glVertex3f(-3.0f, -1.0f, -50.0f);
glVertex3f(-3.0f, -1.0f, -1.0f);
glVertex3f( 3.0f, -1.0f, -1.0f);
glVertex3f( 3.0f, -1.0f, -50.0f);
glEnd();
}

// Main display function
void renderScene(){
processKeys();
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
gluLookAt(  eyeX,eyeY,eyeZ,
atX,atY,atZ,
0.0,1.0,0.0);
renderBase();
glTranslatef(atX,atY-1.0,atZ-2.0);
glRotatef(theta[0],1.0,0.0,0.0);
glRotatef(theta[1],0.0,1.0,0.0);
glRotatef(theta[2],0.0,0.0,1.0);
renderSphere();
glFlush();
glutSwapBuffers();
}

// Sphere hops as you wish
void hopSphere(){
int i=0;
while(i<10){
atY+=0.1;
eyeY+=0.1;
i++;
renderScene();
causeDelay();
}
while(i>0){
atY-=0.1;
eyeY-=0.1;
i--;
renderScene();
causeDelay();
}
}

// Reshape function done using perspective
void reshape(int w,int h){
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
gluPerspective(45.0f,(w*1.0)/(h>0?h:1.0),0.1,100.0);
glMatrixMode(GL_MODELVIEW);
}

// Initialization of depth and lighting (TO BE DONE..)
void init(){
glEnable(GL_DEPTH_TEST);
ShowCursor(false);
glutIgnoreKeyRepeat(0);
}

// Call back functions registered with keyboard

void keyDown(int key,int xx,int yy){
keyBuffer[key]=true;
}

void keyUp(int key,int xx,int yy){
keyBuffer[key]=false;
}

void keyPressed(unsigned char key,int xx,int yy){
if(key==27)
exit(0);
if(key==32)
hopSphere();
if(key=='+')
size++;
if(key=='-')
size=(size>3?size-1:3);
if(key=='q'||key=='Q')
rotateView(-0.05);
if(key=='e'||key=='E')
rotateView(0.05);
if(key=='w'||key=='W')
wired=!wired;
}

// Entry for game
int main(int argc,char** argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutGameModeString("1240x780:64@72");
glutEnterGameMode();
init();
glutReshapeFunc(reshape);
glutDisplayFunc(renderScene);
//glutIdleFunc(spin);
glutIdleFunc(renderScene);
glutKeyboardFunc(keyPressed);
glutSpecialFunc(keyDown);
glutSpecialUpFunc(keyUp);
glutMainLoop();
}
``````

But, its not clean !!
[ul][li]Sphere is not placed on the base properly !! [/li] [li]Movement & pitch is not clean, its not wrt base !![/ul][/li]
Can any one guide me how to make it look more realistic ??

And, any idea how to marble fall when its not on the base ??

``````
// Rotate the camera
void rotateView(float fraction){
float dirX,dirZ;
//    dirX = atX - eyeX;
//    dirZ = atZ - eyeZ;
//    atZ = eyeZ + sin(fraction) * dirX + cos(fraction) * dirZ;
//    atX = eyeX + cos(fraction) * dirX - sin(fraction) * dirZ;
dirX = eyeX - atX;
dirZ = eyeZ - atZ;
eyeZ = atZ + sin(fraction) * dirX + cos(fraction) * dirZ;
eyeX = atX + cos(fraction) * dirX - sin(fraction) * dirZ;
}

``````

This fixes rotation !!

and setting translate of sphere to

`````` glTranslatef(atX,atY-1.3,atZ-2.0);
``````

fixes its position !!

But realistic movement & pitching is still an issue !!
And idea for marble falling down too !! Please Reply SOON !!