blender/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp
Kent Mein 209a2ede2c Last of the config.h mods...
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

added to these files.

Kent
--
mein@cs.umn.edu
2002-11-25 15:29:57 +00:00

696 lines
16 KiB
C++

//#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"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
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;
}