diff options
Diffstat (limited to 'source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp')
-rw-r--r-- | source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp | 691 |
1 files changed, 691 insertions, 0 deletions
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp b/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp new file mode 100644 index 00000000000..1c03621f530 --- /dev/null +++ b/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp @@ -0,0 +1,691 @@ +//#define FAKE_IT +#define USE_COMPLEX +#define QUADS + +#include <algorithm> +#include <new> +#include <GL/glut.h> + +#include "MT_MinMax.h" +#include "MT_Point3.h" +#include "MT_Vector3.h" +#include "MT_Quaternion.h" +#include "MT_Matrix3x3.h" +#include "MT_Transform.h" + +#include "SM_Object.h" +#include "SM_Scene.h" + +#include "solid.h" + +const MT_Scalar bowl_curv = 0.10; +const MT_Scalar timeStep = 0.04; +const MT_Scalar ground_margin = 0.0; +const MT_Scalar sphere_radius = 0.5; + +const MT_Vector3 gravity(0, -9.8, 0); + +static MT_Scalar DISTANCE = 5; + +static MT_Scalar ele = 0, azi = 0; +static MT_Point3 eye(0, 0, DISTANCE); +static MT_Point3 center(0, 0, 0); + +inline double irnd() { return 2 * MT_random() - 1; } + +static const double SCALE_BOTTOM = 0.5; +static const double SCALE_FACTOR = 2.0; + +SM_ShapeProps g_shapeProps = { + 1.0, // mass + 1.0, // inertia + 0.9, // linear drag + 0.9 // angular drag +}; + +SM_MaterialProps g_materialProps = { + 0.7, // restitution + 0.0, // friction + 0.0, // spring constant + 0.0 // damping +}; + + +void toggleIdle(); + + +void newRandom(); + +void coordSystem() { + glDisable(GL_LIGHTING); + glBegin(GL_LINES); + glColor3f(1, 0, 0); + glVertex3d(0, 0, 0); + glVertex3d(10, 0, 0); + glColor3f(0, 1, 0); + glVertex3d(0, 0, 0); + glVertex3d(0, 10, 0); + glColor3f(0, 0, 1); + glVertex3d(0, 0, 0); + glVertex3d(0, 0, 10); + glEnd(); + glEnable(GL_LIGHTING); +} + + +void display_bbox(const MT_Point3& min, const MT_Point3& max) { + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glColor3f(0, 1, 1); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glBegin(GL_QUAD_STRIP); + glVertex3d(min[0], min[1], min[2]); + glVertex3d(min[0], min[1], max[2]); + glVertex3d(max[0], min[1], min[2]); + glVertex3d(max[0], min[1], max[2]); + glVertex3d(max[0], max[1], min[2]); + glVertex3d(max[0], max[1], max[2]); + glVertex3d(min[0], max[1], min[2]); + glVertex3d(min[0], max[1], max[2]); + glVertex3d(min[0], min[1], min[2]); + glVertex3d(min[0], min[1], max[2]); + glEnd(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); +} + + + + +class GLShape { +public: + virtual void paint(GLdouble *m) const = 0; +}; + + +class GLSphere : public GLShape { + MT_Scalar radius; +public: + GLSphere(MT_Scalar r) : radius(r) {} + + void paint(GLdouble *m) const { + glPushMatrix(); + glLoadMatrixd(m); + coordSystem(); + glutSolidSphere(radius, 20, 20); + glPopMatrix(); + } +}; + + +class GLBox : public GLShape { + MT_Vector3 extent; +public: + GLBox(MT_Scalar x, MT_Scalar y, MT_Scalar z) : + extent(x, y, z) {} + + void paint(GLdouble *m) const { + glPushMatrix(); + glLoadMatrixd(m); + coordSystem(); + glPushMatrix(); + glScaled(extent[0], extent[1], extent[2]); + glutSolidCube(1.0); + glPopMatrix(); + glPopMatrix(); + } +}; + + +class GLCone : public GLShape { + MT_Scalar bottomRadius; + MT_Scalar height; + mutable GLuint displayList; + +public: + GLCone(MT_Scalar r, MT_Scalar h) : + bottomRadius(r), + height(h), + displayList(0) {} + + void paint(GLdouble *m) const { + glPushMatrix(); + glLoadMatrixd(m); + coordSystem(); + if (displayList) glCallList(displayList); + else { + GLUquadricObj *quadObj = gluNewQuadric(); + displayList = glGenLists(1); + glNewList(displayList, GL_COMPILE_AND_EXECUTE); + glPushMatrix(); + glRotatef(-90.0, 1.0, 0.0, 0.0); + glTranslatef(0.0, 0.0, -1.0); + gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL); + gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH); + gluCylinder(quadObj, bottomRadius, 0, height, 15, 10); + glPopMatrix(); + glEndList(); + } + glPopMatrix(); + } +}; + +class GLCylinder : public GLShape { + MT_Scalar radius; + MT_Scalar height; + mutable GLuint displayList; + +public: + GLCylinder(MT_Scalar r, MT_Scalar h) : + radius(r), + height(h), + displayList(0) {} + + void paint(GLdouble *m) const { + glPushMatrix(); + glLoadMatrixd(m); + coordSystem(); + if (displayList) glCallList(displayList); + else { + GLUquadricObj *quadObj = gluNewQuadric(); + displayList = glGenLists(1); + glNewList(displayList, GL_COMPILE_AND_EXECUTE); + glPushMatrix(); + glRotatef(-90.0, 1.0, 0.0, 0.0); + glTranslatef(0.0, 0.0, -1.0); + gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL); + gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH); + gluCylinder(quadObj, radius, radius, height, 15, 10); + glPopMatrix (); + glEndList(); + } + glPopMatrix(); + } +}; + +class Object; + +class Callback : public SM_Callback { +public: + Callback(Object& object) : m_object(object) {} + + virtual void do_me(); + +private: + Object& m_object; +}; + + +class Object { +public: + Object(GLShape *gl_shape, SM_Object& object) : + m_gl_shape(gl_shape), + m_object(object), + m_callback(*this) + { + m_object.registerCallback(m_callback); + } + + ~Object() {} + + void paint() { + m_gl_shape->paint(m); + // display_bbox(m_bbox.lower(), m_bbox.upper()); + } + + MT_Vector3 getAhead() { + return MT_Vector3(-m[8], -m[9], -m[10]); + } + + void clearMomentum() { + m_object.clearMomentum(); + } + + void setMargin(MT_Scalar margin) { + m_object.setMargin(margin); + } + + void setScaling(const MT_Vector3& scaling) { + m_object.setScaling(scaling); + } + + void setPosition(const MT_Point3& pos) { + m_object.setPosition(pos); + } + + void setOrientation(const MT_Quaternion& orn) { + m_object.setOrientation(orn); + } + + void applyCenterForce(const MT_Vector3& force) { + m_object.applyCenterForce(force); + } + + void applyTorque(const MT_Vector3& torque) { + m_object.applyTorque(torque); + } + + MT_Point3 getWorldCoord(const MT_Point3& local) const { + return m_object.getWorldCoord(local); + } + + MT_Vector3 getLinearVelocity() const { + return m_object.getLinearVelocity(); + } + + void setMatrix() { + m_object.getMatrix(m); + } + +private: + GLShape *m_gl_shape; + SM_Object& m_object; + DT_Scalar m[16]; + Callback m_callback; +}; + + +void Callback::do_me() +{ + m_object.setMatrix(); +} + + +const MT_Scalar SPACE_SIZE = 2; + +static GLSphere gl_sphere(sphere_radius); +static GLBox gl_ground(50.0, 0.0, 50.0); + + + +#ifdef USE_COMPLEX + +const int GRID_SCALE = 10; +const MT_Scalar GRID_UNIT = 25.0 / GRID_SCALE; + +DT_ShapeHandle createComplex() { + DT_ShapeHandle shape = DT_NewComplexShape(); + for (int i0 = -GRID_SCALE; i0 != GRID_SCALE; ++i0) { + for (int j0 = -GRID_SCALE; j0 != GRID_SCALE; ++j0) { + int i1 = i0 + 1; + int j1 = j0 + 1; +#ifdef QUADS + DT_Begin(); + DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j0); + DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j1); + DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j1); + DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j0); + DT_End(); +#else + DT_Begin(); + DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j0); + DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1); + DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1); + DT_End(); + + DT_Begin(); + DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1); + DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1); + DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j0); + DT_End(); +#endif + + } + } + DT_EndComplexShape(); + return shape; +} + + +static DT_ShapeHandle ground_shape = createComplex(); + +#else + +static DT_ShapeHandle ground_shape = DT_Box(50, 0, 50); + +#endif + +static SM_Object sm_ground(ground_shape, &g_materialProps, 0, 0); +static Object ground(&gl_ground, sm_ground); + +static SM_Object sm_sphere(DT_Sphere(0.0), &g_materialProps, &g_shapeProps, 0); +static Object object(&gl_sphere, sm_sphere); + + +static SM_Object sm_ray(DT_Ray(0.0, -1.0, 0.0), 0, 0, 0); + +static SM_Scene g_scene; + + +void myinit(void) { + + GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; + GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; + + /* light_position is NOT default value */ + GLfloat light_position0[] = { 1.0, 1.0, 1.0, 0.0 }; + GLfloat light_position1[] = { -1.0, -1.0, -1.0, 0.0 }; + + glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); + glLightfv(GL_LIGHT0, GL_POSITION, light_position0); + + glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); + glLightfv(GL_LIGHT1, GL_POSITION, light_position1); + + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + + // glEnable(GL_CULL_FACE); + // glCullFace(GL_BACK); + + g_scene.setForceField(gravity); + g_scene.add(sm_ground); + sm_ground.setMargin(ground_margin); + + new(&object) Object(&gl_sphere, sm_sphere); + + + object.setMargin(sphere_radius); + + g_scene.add(sm_sphere); + + ground.setPosition(MT_Point3(0, -10, 0)); + ground.setOrientation(MT_Quaternion(0, 0, 0, 1)); + ground.setMatrix(); + center.setValue(0.0, 0.0, 0.0); + + newRandom(); +} + + +//MT_Point3 cp1, cp2; +//bool intersection; + +bool g_hit = false; +MT_Point3 g_spot; +MT_Vector3 g_normal; + + +void display(void) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + ground.paint(); + object.paint(); + + if (g_hit) { + glPointSize(5); + glBegin(GL_POINTS); + glVertex3d(g_spot[0], g_spot[1], g_spot[2]); + glEnd(); + glPointSize(1); + } + + + +#ifdef COLLISION + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glColor3f(1, 1, 0); + if (intersection) { + glPointSize(5); + glBegin(GL_POINTS); + glVertex3d(cp1[0], cp1[1], cp1[2]); + glEnd(); + glPointSize(1); + } + else { + glBegin(GL_LINES); + glVertex3d(cp1[0], cp1[1], cp1[2]); + glVertex3d(cp2[0], cp2[1], cp2[2]); + glEnd(); + } + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); +#endif + + glFlush(); + glutSwapBuffers(); +} + + + + + +void newRandom() { + object.setPosition(MT_Point3(0, 0, 0)); + object.clearMomentum(); + object.setMatrix(); + + display(); +} + +void moveAndDisplay() { + g_scene.proceed(timeStep, 0.01); + + MT_Vector3 normal(0, 1, 0); + + MT_Point3 from = object.getWorldCoord(MT_Point3(0, 0, 0)); + MT_Point3 to = from - normal * 10.0; + + g_hit = DT_ObjectRayTest(sm_ground.getObjectHandle(), + from.getValue(), + to.getValue(), g_spot.getValue(), + g_normal.getValue()); + + // Scrap +#define DO_FH +#ifdef DO_FH + MT_Scalar dist = MT_distance(from, g_spot); + if (dist < 5.0) { + MT_Vector3 lin_vel = object.getLinearVelocity(); + MT_Scalar lin_vel_normal = lin_vel.dot(normal); + + MT_Scalar spring_extent = dist + lin_vel_normal * (timeStep * 0.5); + + MT_Scalar f_spring = (5.0 - spring_extent) * 3.0; + object.applyCenterForce(normal * f_spring); + object.applyCenterForce(-lin_vel_normal * normal); + } + +#endif + + + display(); +} + + +void turn_left() { + object.applyTorque(MT_Vector3(0.0, 10.0, 0.0)); +} + +void turn_right() { + object.applyTorque(MT_Vector3(0.0, -10.0, 0.0)); +} + +void forward() { + object.applyCenterForce(20.0 * object.getAhead()); +} + +void backward() { + object.applyCenterForce(-20.0 * object.getAhead()); +} + +void jump() { + object.applyCenterForce(MT_Vector3(0.0, 200.0, 0.0)); +} + + +void toggleIdle() { + static bool idle = true; + if (idle) { + glutIdleFunc(moveAndDisplay); + idle = false; + } + else { + glutIdleFunc(NULL); + idle = true; + } +} + + +void setCamera() { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 200.0); + MT_Scalar rele = MT_radians(ele); + MT_Scalar razi = MT_radians(azi); + eye.setValue(DISTANCE * sin(razi) * cos(rele), + DISTANCE * sin(rele), + DISTANCE * cos(razi) * cos(rele)); + gluLookAt(eye[0], eye[1], eye[2], + center[0], center[1], center[2], + 0, 1, 0); + glMatrixMode(GL_MODELVIEW); + display(); +} + +const MT_Scalar STEPSIZE = 5; + +void stepLeft() { azi -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); } +void stepRight() { azi += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); } +void stepFront() { ele += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); } +void stepBack() { ele -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); } +void zoomIn() { DISTANCE -= 1; setCamera(); } +void zoomOut() { DISTANCE += 1; setCamera(); } + + +void myReshape(int w, int h) { + glViewport(0, 0, w, h); + setCamera(); +} + +void myKeyboard(unsigned char key, int x, int y) +{ + switch (key) + { + case 'w': forward(); break; + case 's': backward(); break; + case 'a': turn_left(); break; + case 'd': turn_right(); break; + case 'e': jump(); break; + case 'l' : stepLeft(); break; + case 'r' : stepRight(); break; + case 'f' : stepFront(); break; + case 'b' : stepBack(); break; + case 'z' : zoomIn(); break; + case 'x' : zoomOut(); break; + case 'i' : toggleIdle(); break; + case ' ' : newRandom(); break; + default: +// std::cout << "unused key : " << key << std::endl; + break; + } +} + +void mySpecial(int key, int x, int y) +{ + switch (key) + { + case GLUT_KEY_LEFT : stepLeft(); break; + case GLUT_KEY_RIGHT : stepRight(); break; + case GLUT_KEY_UP : stepFront(); break; + case GLUT_KEY_DOWN : stepBack(); break; + case GLUT_KEY_PAGE_UP : zoomIn(); break; + case GLUT_KEY_PAGE_DOWN : zoomOut(); break; + case GLUT_KEY_HOME : toggleIdle(); break; + default: +// std::cout << "unused (special) key : " << key << std::endl; + break; + } +} + +void goodbye( void) +{ + g_scene.remove(sm_ground); + g_scene.remove(sm_sphere); + + std::cout << "goodbye ..." << std::endl; + exit(0); +} + +void menu(int choice) +{ + + static int fullScreen = 0; + static int px, py, sx, sy; + + switch(choice) { + case 1: + if (fullScreen == 1) { + glutPositionWindow(px,py); + glutReshapeWindow(sx,sy); + glutChangeToMenuEntry(1,"Full Screen",1); + fullScreen = 0; + } else { + px=glutGet((GLenum)GLUT_WINDOW_X); + py=glutGet((GLenum)GLUT_WINDOW_Y); + sx=glutGet((GLenum)GLUT_WINDOW_WIDTH); + sy=glutGet((GLenum)GLUT_WINDOW_HEIGHT); + glutFullScreen(); + glutChangeToMenuEntry(1,"Close Full Screen",1); + fullScreen = 1; + } + break; + case 2: + toggleIdle(); + break; + case 3: + goodbye(); + break; + default: + break; + } +} + +void createMenu() +{ + glutCreateMenu(menu); + glutAddMenuEntry("Full Screen", 1); + glutAddMenuEntry("Toggle Idle (Start/Stop)", 2); + glutAddMenuEntry("Quit", 3); + glutAttachMenu(GLUT_RIGHT_BUTTON); +} + +int main(int argc, char **argv) { + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowPosition(0, 0); + glutInitWindowSize(500, 500); + glutCreateWindow("Physics demo"); + + myinit(); + glutKeyboardFunc(myKeyboard); + glutSpecialFunc(mySpecial); + glutReshapeFunc(myReshape); + createMenu(); + glutIdleFunc(NULL); + + glutDisplayFunc(display); + glutMainLoop(); + return 0; +} + + + + + + + |