PDA

View Full Version : move an object in 3D, fall, and bounce



Cypray
04-26-2004, 03:39 AM
I want to make a sphere roll to the edge of a table and then fall off and bounce on when it hits the floor. I have got the sphere positioned on top of the table. Please can any one give me the codes to make it move and then fall and bounce?
Your help will be highly appereciated.

mikeman
04-26-2004, 04:01 AM
The subject is not so simple,and there is certainly a lot of ways of doing this.I assume your needs are not limited to the situation you described,so you have to develop some kind of physics engine,even a primitive one at first.I can give you some pointers,base on my experience:
The ball is an object.Create a class,structure,whatever that represents it and can hold its position and velocity.Then write a function RunPhysics() or something like that that moves the ball according to physical laws.You have to take into account gravity,collision detection,etc.This is as simple as it gets,the sky is the limit.Anyway,I hope a little pseudo-code sample will give you an idea(vector operations are simplified,you actually have to write code for them):

struct Object3D
{TVector position;
TVector velocity;
}

void RunPhysics(float dt)
{
velocity.y=velocity.y-gravity*dt;
position=position+velocity*dt;

if VerticalCollisionHappened()
{
velocity.y=-velocity.y;
}

}

void MainLoop()
{

while NotQuit()
{
RunPhysics(0.01);//Arbitary value,use a timer for that

DrawScene();
SwapBuffers();
}

}

Cypray
04-26-2004, 04:23 AM
Thanks a lot. I could see that I don't have enough physics and opengl knowledge to do this.
Here is the code I put together to display the sphere. How do I make this work with your inputs?

#include <windows.h>
#include <gl/Gl.h>
#include <gl/Glu.h>
#include <gl/glut.h>
#include <math.h>
#include <iostream.h>
#include <fstream.h>

void myInit()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 64/48.0, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0, 5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

glColor3d(0,0,0);
}

void myDisplay(void)
{

glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINE_LOOP); // Draw Platform
glVertex3d(0.8,-0.9,0.5);
glVertex3d(0.8,0.9,0.5);
glVertex3d(-1.8,0.9,0.9);
glVertex3d(-1.8,-0.9,0.9);
glEnd();



glBegin(GL_LINE_LOOP);
glVertex3d(-2.0, 0.1, 0.5); // Draw little Bar
glVertex3d(-2.0, 0.3,0.5);
glVertex3d(-1.2, 0.3,0.5);
glVertex3d(-1.2, 0.1,0.5);

glEnd();

glPushMatrix(); // draw and place Sphere
glTranslated(-1.7, 0.5, 0.5);

glutSolidSphere(0.2, 15, 15);
glPopMatrix();


glutSwapBuffers();
}

void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB );
glutInitWindowSize(640,480);
glutInitWindowPosition(50, 50);
glutCreateWindow("Rolling");
glutDisplayFunc(myDisplay);
glClearColor(1.0f, 1.0f, 1.0f,0.0f);
glViewport(0, 0, 640, 480);
//glutKeyboardFunc(myKeyboard);
myInit();
glutMainLoop();
}

mikeman
04-26-2004, 05:05 AM
This code demonstrates the roll&bounce thing,but you must further develop it to do something really functional.Read articles on the web(my favourite is www.gamedev.net (http://www.gamedev.net) ,has a lot of stuff) or books about physics,collision detection,etc.

#include <windows.h>
#include <gl/Gl.h>
#include <gl/Glu.h>
#include <gl/glut.h>
#include <math.h>
#include <iostream.h>
#include <fstream.h>

void myIdle();
void myDisplay();

struct TVector
{
float x,y,z;
};

struct TObject3D
{
TVector position;
TVector velocity;
};

TObject3D sphere;

#define GRAVITY 4.0

void RunPhysics(float dt)
{
sphere.velocity.y=sphere.velocity.y-GRAVITY*dt;

sphere.position.x=sphere.position.x+sphere.velocit y.x*dt;
sphere.position.y=sphere.position.y+sphere.velocit y.y*dt;
sphere.position.z=sphere.position.z+sphere.velocit y.z*dt;


if (sphere.velocity.y<0)
{

if (sphere.position.y<0.5)
{

if ((sphere.position.x>-2)&amp;&amp;(sphere.position.x<-1.2)) sphere.velocity.y=-sphere.velocity.y;
}

if (sphere.position.y<-0.9) sphere.velocity.y=-sphere.velocity.y;

}

}

void myInit()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 64/48.0, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0, 5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

glColor3d(0,0,0);
}

void myIdle()
{
RunPhysics(0.01);
myDisplay();

}

void myDisplay(void)
{

glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINE_LOOP); // Draw Platform
glVertex3d(0.8,-0.9,0.5);
glVertex3d(0.8,0.9,0.5);
glVertex3d(-1.8,0.9,0.9);
glVertex3d(-1.8,-0.9,0.9);
glEnd();



glBegin(GL_LINE_LOOP);
glVertex3d(-2.0, 0.1, 0.5); // Draw little Bar
glVertex3d(-2.0, 0.3,0.5);
glVertex3d(-1.2, 0.3,0.5);
glVertex3d(-1.2, 0.1,0.5);

glEnd();

glPushMatrix(); // draw and place Sphere
glTranslated(sphere.position.x,sphere.position.y,s phere.position.z);

glutSolidSphere(0.2, 15, 15);
glPopMatrix();


glutSwapBuffers();
}

void main(int argc, char **argv)
{
sphere.position.x=-1.7;
sphere.position.y=0.5;
sphere.position.z=0.5;

sphere.velocity.x=1;
sphere.velocity.y=0;
sphere.velocity.z=0;


glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB );
glutInitWindowSize(640,480);
glutInitWindowPosition(50, 50);
glutCreateWindow("Rolling");
glutDisplayFunc(myDisplay);
glutIdleFunc(myIdle);
glClearColor(1.0f, 1.0f, 1.0f,0.0f);
glViewport(0, 0, 640, 480);
//glutKeyboardFunc(myKeyboard);
myInit();
glutMainLoop();
}

Cypray
04-26-2004, 05:29 AM
Thanks a lot for your help. I will keep working on this. You have got me to a good point.

Cypray
04-26-2004, 04:33 PM
Please how do I make changes to the above code so that the sphere will start rolling only when then right mouse button is clicked on it. I tried to call myIdle() from inside myMouse function, but it does not work.

nexusone
04-26-2004, 04:46 PM
// Add to mouse routine
if (Right_mouse_click ) Start_physics = 0.01;

void myIdle()
{
RunPhysics( Start_physics ); // Ball roll will not start until variable Start_physics is non-zero
myDisplay();
}


Originally posted by Cypray:
Please how do I make changes to the above code so that the sphere will start rolling only when then right mouse button is clicked on it. I tried to call myIdle() from inside myMouse function, but it does not work.

Cypray
04-26-2004, 05:22 PM
Thank you very much. That works great. I really appreciate your help.

04-27-2004, 11:39 PM
That suggestion works in that particular case,but it is like the whole world is "frosen" and then "unfrosen" with a right click.This can be useful,if you want to pause your application,for example,but i don't recommend it for controlling the movement of objects in general.
If RunPhysics() handles the movement of many objects,and not just the sphere,it would be better to set the sphere velocity to any desirable value once you click the mouse.You can have RunPhysics(0.01) as always,but you initialize ball velocity to 0,so the ball stands still.When the right button is clicked,you set "ball.velocity.x=1" and the ball starts to move to the right.
In general,use the controls to change the velocity of your objects,while the physics run all the time.That way you can control the movement of any object of the world,indepedently from other objects.