PDA

View Full Version : Rolling and pitching Marble

Ikhan
11-26-2011, 07:05 AM
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 radius=0.2; // Sphere radius
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)
glutWireSphere(radius,size<3?3:size,size<3?3:size);
else
glutSolidSphere(radius,size<3?3:size,size<3?3:size);
glPopMatrix();
glPopAttrib();
}

// Renders the map
void renderBase(){
glColor3f(0.0,0.0,1.0);
glBegin(GL_QUADS);
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);
glLoadIdentity();
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);
glLoadIdentity();
gluPerspective(45.0f,(w*1.0)/(h>0?h:1.0),0.1,100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

// 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(&amp;argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUB LE);
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 !!
Sphere is not placed on the base properly !!
Movement & pitch is not clean, its not wrt base !!

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 ??

Ikhan
11-26-2011, 07:38 AM
// 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 !!