Reverted incorrect merge (missing files)
[blender.git] / source / gameengine / Physics / Sumo / Fuzzics / sample / particle0.cpp
1 //#define FAKE_IT
2 #define USE_COMPLEX
3 #define QUADS
4
5 #include <algorithm>
6 #include <new>
7 #include <GL/glut.h>
8
9 #include "MT_MinMax.h"
10 #include "MT_Point3.h"
11 #include "MT_Vector3.h"
12 #include "MT_Quaternion.h"
13 #include "MT_Matrix3x3.h"
14 #include "MT_Transform.h"
15
16 #include "SM_Object.h"
17 #include "SM_Scene.h"
18
19 #include "solid.h"
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 const MT_Scalar bowl_curv = 0.10;
26 const MT_Scalar timeStep = 0.04;
27 const MT_Scalar ground_margin = 0.0;
28 const MT_Scalar sphere_radius = 0.5;
29
30 const MT_Vector3 gravity(0, -9.8, 0);
31
32 static MT_Scalar DISTANCE = 5; 
33
34 static MT_Scalar ele = 0, azi = 0;
35 static MT_Point3 eye(0, 0, DISTANCE);
36 static MT_Point3 center(0, 0, 0);
37
38 inline double irnd() { return 2 * MT_random() - 1; }  
39
40 static const double SCALE_BOTTOM = 0.5;
41 static const double SCALE_FACTOR = 2.0;
42
43 SM_ShapeProps g_shapeProps = {
44         1.0,    // mass
45         1.0,    // inertia 
46         0.9,    // linear drag
47         0.9     // angular drag
48 };
49
50 SM_MaterialProps g_materialProps = {
51         0.7,    // restitution
52         0.0,    // friction 
53         0.0,    // spring constant
54         0.0     // damping
55 };
56  
57
58 void toggleIdle();
59
60
61 void newRandom();
62
63 void coordSystem() {
64     glDisable(GL_LIGHTING);
65     glBegin(GL_LINES);
66     glColor3f(1, 0, 0);
67     glVertex3d(0, 0, 0);
68     glVertex3d(10, 0, 0);
69     glColor3f(0, 1, 0);
70     glVertex3d(0, 0, 0);
71     glVertex3d(0, 10, 0);
72     glColor3f(0, 0, 1);
73     glVertex3d(0, 0, 0);
74     glVertex3d(0, 0, 10);
75     glEnd();
76     glEnable(GL_LIGHTING);
77 }
78
79
80 void display_bbox(const MT_Point3& min, const MT_Point3& max) {
81     glDisable(GL_DEPTH_TEST);
82     glDisable(GL_LIGHTING);
83     glColor3f(0, 1, 1);
84     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
85     glBegin(GL_QUAD_STRIP);
86     glVertex3d(min[0], min[1], min[2]);
87     glVertex3d(min[0], min[1], max[2]);
88     glVertex3d(max[0], min[1], min[2]);
89     glVertex3d(max[0], min[1], max[2]);
90     glVertex3d(max[0], max[1], min[2]);
91     glVertex3d(max[0], max[1], max[2]);
92     glVertex3d(min[0], max[1], min[2]);
93     glVertex3d(min[0], max[1], max[2]);
94     glVertex3d(min[0], min[1], min[2]);
95     glVertex3d(min[0], min[1], max[2]);
96     glEnd();  
97     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
98     glEnable(GL_LIGHTING);
99     glEnable(GL_DEPTH_TEST);
100 }
101
102
103
104
105 class GLShape {
106 public:
107     virtual void paint(GLdouble *m) const = 0;
108 };
109
110
111 class GLSphere : public GLShape {
112     MT_Scalar radius;
113 public:
114     GLSphere(MT_Scalar r) : radius(r) {}
115
116     void paint(GLdouble *m) const {
117         glPushMatrix(); 
118         glLoadMatrixd(m);
119         coordSystem();
120         glutSolidSphere(radius, 20, 20);
121         glPopMatrix();
122     }
123 };
124
125
126 class GLBox : public GLShape {
127     MT_Vector3 extent;
128 public:
129     GLBox(MT_Scalar x, MT_Scalar y, MT_Scalar z) : 
130         extent(x, y, z) {}
131
132     void paint(GLdouble *m) const {
133         glPushMatrix(); 
134         glLoadMatrixd(m);
135         coordSystem();
136         glPushMatrix();
137         glScaled(extent[0], extent[1], extent[2]);
138         glutSolidCube(1.0);
139         glPopMatrix();
140         glPopMatrix();
141     }
142 };
143
144
145 class GLCone : public GLShape {
146     MT_Scalar bottomRadius;
147     MT_Scalar height;
148     mutable GLuint displayList;
149
150 public:
151     GLCone(MT_Scalar r, MT_Scalar h) :  
152         bottomRadius(r), 
153         height(h), 
154         displayList(0) {}
155   
156     void paint(GLdouble *m) const { 
157         glPushMatrix(); 
158         glLoadMatrixd(m);
159         coordSystem();
160         if (displayList) glCallList(displayList); 
161         else {
162             GLUquadricObj *quadObj = gluNewQuadric();
163             displayList = glGenLists(1);
164             glNewList(displayList, GL_COMPILE_AND_EXECUTE);
165             glPushMatrix();
166             glRotatef(-90.0, 1.0, 0.0, 0.0);
167             glTranslatef(0.0, 0.0, -1.0);
168             gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL);
169             gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH);
170             gluCylinder(quadObj, bottomRadius, 0, height, 15, 10);
171             glPopMatrix();
172             glEndList();
173         }
174         glPopMatrix();
175     }
176 };
177
178 class GLCylinder : public GLShape {
179     MT_Scalar radius;
180     MT_Scalar height;
181     mutable GLuint displayList;
182
183 public:
184     GLCylinder(MT_Scalar r, MT_Scalar h) : 
185         radius(r), 
186         height(h), 
187         displayList(0) {}
188
189     void paint(GLdouble *m) const { 
190         glPushMatrix(); 
191         glLoadMatrixd(m);
192         coordSystem();
193         if (displayList) glCallList(displayList); 
194         else {
195             GLUquadricObj *quadObj = gluNewQuadric();
196             displayList = glGenLists(1);
197             glNewList(displayList, GL_COMPILE_AND_EXECUTE);
198             glPushMatrix();
199             glRotatef(-90.0, 1.0, 0.0, 0.0);
200             glTranslatef(0.0, 0.0, -1.0);
201             gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL);
202             gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH);
203             gluCylinder(quadObj, radius, radius, height, 15, 10);
204             glPopMatrix ();
205             glEndList();
206         }
207         glPopMatrix();
208     }
209 };
210
211 class Object;
212
213 class Callback : public SM_Callback {
214 public:
215         Callback(Object& object) : m_object(object) {}
216
217         virtual void do_me();
218
219 private:
220         Object& m_object;
221 };
222
223
224 class Object {
225 public:
226     Object(GLShape *gl_shape, SM_Object& object) :
227         m_gl_shape(gl_shape),
228         m_object(object),
229                 m_callback(*this)
230         {
231                         m_object.registerCallback(m_callback);
232                 }
233         
234     ~Object() {}
235
236     void paint() {
237         m_gl_shape->paint(m);
238         //      display_bbox(m_bbox.lower(), m_bbox.upper());
239     }
240         
241         MT_Vector3 getAhead() {
242                 return MT_Vector3(-m[8], -m[9], -m[10]);
243         }
244
245     void clearMomentum() {
246                 m_object.clearMomentum();
247     }
248         
249     void setMargin(MT_Scalar margin) {
250         m_object.setMargin(margin);
251     }
252         
253     void setScaling(const MT_Vector3& scaling) {
254         m_object.setScaling(scaling); 
255     }
256
257     void setPosition(const MT_Point3& pos) {
258                 m_object.setPosition(pos);
259     }
260
261     void setOrientation(const MT_Quaternion& orn) {
262         m_object.setOrientation(orn);
263     }
264
265     void applyCenterForce(const MT_Vector3& force) {
266                 m_object.applyCenterForce(force);
267     }
268
269     void applyTorque(const MT_Vector3& torque) {
270                 m_object.applyTorque(torque);
271     }
272
273     MT_Point3 getWorldCoord(const MT_Point3& local) const {
274         return m_object.getWorldCoord(local);
275     }
276
277     MT_Vector3 getLinearVelocity() const {
278         return m_object.getLinearVelocity();
279     }
280
281     void setMatrix() {
282                 m_object.getMatrix(m);
283     }
284
285 private:
286     GLShape        *m_gl_shape;
287     SM_Object&      m_object;
288         DT_Scalar       m[16];
289         Callback        m_callback;
290 };
291
292
293 void Callback::do_me()
294 {
295         m_object.setMatrix();
296 }
297
298
299 const MT_Scalar SPACE_SIZE = 2;
300
301 static GLSphere gl_sphere(sphere_radius);
302 static GLBox gl_ground(50.0, 0.0, 50.0);
303
304
305
306 #ifdef USE_COMPLEX
307
308 const int GRID_SCALE = 10;
309 const MT_Scalar GRID_UNIT  = 25.0 / GRID_SCALE;
310
311 DT_ShapeHandle createComplex() {
312     DT_ShapeHandle shape = DT_NewComplexShape();
313     for (int i0 = -GRID_SCALE; i0 != GRID_SCALE; ++i0) {
314         for (int j0 = -GRID_SCALE; j0 != GRID_SCALE; ++j0) {
315             int i1 = i0 + 1;
316             int j1 = j0 + 1;
317 #ifdef QUADS
318             DT_Begin();
319             DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j0);
320             DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j1);
321             DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j1);
322             DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j0);
323             DT_End();
324 #else
325             DT_Begin();
326             DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j0);
327             DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1);
328             DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1);
329             DT_End();
330
331             DT_Begin();
332             DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1);
333             DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1);
334             DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j0);
335             DT_End();
336 #endif
337
338         }
339     }
340     DT_EndComplexShape();
341     return shape;
342 }
343
344
345 static DT_ShapeHandle ground_shape = createComplex();
346
347 #else 
348
349 static DT_ShapeHandle ground_shape = DT_Box(50, 0, 50);
350
351 #endif
352
353 static SM_Object sm_ground(ground_shape, &g_materialProps, 0, 0);
354 static Object    ground(&gl_ground, sm_ground);
355
356 static SM_Object sm_sphere(DT_Sphere(0.0), &g_materialProps, &g_shapeProps, 0);
357 static Object    object(&gl_sphere, sm_sphere);
358
359
360 static SM_Object sm_ray(DT_Ray(0.0, -1.0, 0.0), 0, 0, 0);
361
362 static SM_Scene   g_scene;
363
364
365 void myinit(void) {
366
367     GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
368     GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
369     GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
370
371     /*  light_position is NOT default value     */
372     GLfloat light_position0[] = { 1.0, 1.0, 1.0, 0.0 };
373     GLfloat light_position1[] = { -1.0, -1.0, -1.0, 0.0 };
374   
375     glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
376     glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
377     glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
378     glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
379   
380     glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
381     glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
382     glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
383     glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
384   
385
386     glEnable(GL_LIGHTING);
387     glEnable(GL_LIGHT0);
388     glEnable(GL_LIGHT1);
389   
390     glShadeModel(GL_SMOOTH);
391   
392     glEnable(GL_DEPTH_TEST);
393     glDepthFunc(GL_LESS);
394   
395     //  glEnable(GL_CULL_FACE);
396     //  glCullFace(GL_BACK);
397
398         g_scene.setForceField(gravity);
399     g_scene.add(sm_ground);
400         sm_ground.setMargin(ground_margin);
401
402     new(&object) Object(&gl_sphere, sm_sphere);
403
404
405         object.setMargin(sphere_radius);
406         
407     g_scene.add(sm_sphere);
408     
409     ground.setPosition(MT_Point3(0, -10, 0));
410     ground.setOrientation(MT_Quaternion(0, 0, 0, 1));
411     ground.setMatrix();
412     center.setValue(0.0, 0.0, 0.0);
413
414     newRandom();
415 }
416
417
418 //MT_Point3 cp1, cp2;
419 //bool intersection;
420
421 bool g_hit = false;
422 MT_Point3 g_spot;
423 MT_Vector3 g_normal;
424
425
426 void display(void) {
427     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
428
429     ground.paint();
430         object.paint();
431         
432         if (g_hit) {
433                 glPointSize(5);
434                 glBegin(GL_POINTS);
435                 glVertex3d(g_spot[0], g_spot[1], g_spot[2]);
436                 glEnd();
437                 glPointSize(1);
438         }
439
440         
441
442 #ifdef COLLISION
443     glDisable(GL_DEPTH_TEST);
444     glDisable(GL_LIGHTING);
445     glColor3f(1, 1, 0);
446     if (intersection) {
447         glPointSize(5);
448         glBegin(GL_POINTS);
449         glVertex3d(cp1[0], cp1[1], cp1[2]);
450         glEnd();
451         glPointSize(1);
452     }
453     else {
454         glBegin(GL_LINES); 
455         glVertex3d(cp1[0], cp1[1], cp1[2]);
456         glVertex3d(cp2[0], cp2[1], cp2[2]);
457         glEnd();
458     }
459     glEnable(GL_LIGHTING);
460     glEnable(GL_DEPTH_TEST);
461 #endif
462
463     glFlush();
464     glutSwapBuffers();
465 }
466
467
468
469
470
471 void newRandom() {
472         object.setPosition(MT_Point3(0, 0, 0));
473         object.clearMomentum();
474         object.setMatrix();
475         
476     display();
477 }
478
479 void moveAndDisplay() {
480         g_scene.proceed(timeStep, 0.01);
481
482         MT_Vector3 normal(0, 1, 0);
483
484         MT_Point3 from = object.getWorldCoord(MT_Point3(0, 0, 0));
485         MT_Point3 to   = from - normal * 10.0;
486
487         g_hit = DT_ObjectRayTest(sm_ground.getObjectHandle(), 
488                                                          from.getValue(),
489                                                          to.getValue(), g_spot.getValue(), 
490                                                          g_normal.getValue());
491
492         // Scrap
493 #define DO_FH
494 #ifdef DO_FH
495         MT_Scalar dist = MT_distance(from, g_spot);
496         if (dist < 5.0) {
497                 MT_Vector3 lin_vel = object.getLinearVelocity();
498                 MT_Scalar lin_vel_normal = lin_vel.dot(normal);
499
500                 MT_Scalar spring_extent = dist + lin_vel_normal * (timeStep * 0.5);
501                 
502                 MT_Scalar f_spring = (5.0 - spring_extent) * 3.0;
503                 object.applyCenterForce(normal * f_spring);
504                 object.applyCenterForce(-lin_vel_normal * normal);
505         }
506         
507 #endif
508
509
510     display();
511 }
512
513
514 void turn_left() {
515         object.applyTorque(MT_Vector3(0.0, 10.0, 0.0));
516 }
517
518 void turn_right() {
519         object.applyTorque(MT_Vector3(0.0, -10.0, 0.0));
520 }
521
522 void forward() {
523         object.applyCenterForce(20.0 * object.getAhead());
524 }
525
526 void backward() {
527         object.applyCenterForce(-20.0 * object.getAhead());
528 }
529
530 void jump() {
531         object.applyCenterForce(MT_Vector3(0.0, 200.0, 0.0));
532 }
533
534
535 void toggleIdle() {
536     static bool idle = true;
537     if (idle) {
538         glutIdleFunc(moveAndDisplay);
539         idle = false;
540     }
541     else {
542         glutIdleFunc(NULL);
543         idle = true;
544     }
545 }
546
547
548 void setCamera() {
549     glMatrixMode(GL_PROJECTION);
550     glLoadIdentity();
551     glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 200.0);
552     MT_Scalar rele = MT_radians(ele);
553     MT_Scalar razi = MT_radians(azi);
554     eye.setValue(DISTANCE * sin(razi) * cos(rele), 
555                  DISTANCE * sin(rele),
556                  DISTANCE * cos(razi) * cos(rele));
557     gluLookAt(eye[0], eye[1], eye[2], 
558               center[0], center[1], center[2], 
559               0, 1, 0);
560     glMatrixMode(GL_MODELVIEW);
561     display();
562 }
563
564 const MT_Scalar STEPSIZE = 5;
565
566 void stepLeft() { azi -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); }
567 void stepRight() { azi += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); }
568 void stepFront() { ele += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); }
569 void stepBack() { ele -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); }
570 void zoomIn() { DISTANCE -= 1; setCamera(); }
571 void zoomOut() { DISTANCE += 1; setCamera(); }
572
573
574 void myReshape(int w, int h) {
575     glViewport(0, 0, w, h);
576     setCamera();
577 }
578
579 void myKeyboard(unsigned char key, int x, int y)
580 {
581     switch (key) 
582     {
583         case 'w': forward();    break;
584         case 's': backward();   break;
585         case 'a': turn_left();  break;
586         case 'd': turn_right(); break;
587         case 'e': jump(); break;        
588     case 'l' : stepLeft(); break;
589     case 'r' : stepRight(); break;
590     case 'f' : stepFront(); break;
591     case 'b' : stepBack(); break;
592     case 'z' : zoomIn(); break;
593     case 'x' : zoomOut(); break;
594     case 'i' : toggleIdle(); break;
595     case ' ' : newRandom(); break;
596     default:
597 //        std::cout << "unused key : " << key << std::endl;
598         break;
599     }
600 }
601
602 void mySpecial(int key, int x, int y)
603 {
604     switch (key) 
605     {
606     case GLUT_KEY_LEFT : stepLeft(); break;
607     case GLUT_KEY_RIGHT : stepRight(); break;
608     case GLUT_KEY_UP : stepFront(); break;
609     case GLUT_KEY_DOWN : stepBack(); break;
610     case GLUT_KEY_PAGE_UP : zoomIn(); break;
611     case GLUT_KEY_PAGE_DOWN : zoomOut(); break;
612     case GLUT_KEY_HOME : toggleIdle(); break;
613     default:
614 //        std::cout << "unused (special) key : " << key << std::endl;
615         break;
616     }
617 }
618
619 void goodbye( void)
620 {
621         g_scene.remove(sm_ground);
622         g_scene.remove(sm_sphere);
623
624     std::cout << "goodbye ..." << std::endl;
625     exit(0);
626 }
627
628 void menu(int choice)
629 {
630
631     static int fullScreen = 0;
632     static int px, py, sx, sy;
633  
634     switch(choice) {
635     case 1:
636         if (fullScreen == 1) {
637             glutPositionWindow(px,py);
638             glutReshapeWindow(sx,sy);
639             glutChangeToMenuEntry(1,"Full Screen",1);
640             fullScreen = 0;
641         } else {
642             px=glutGet((GLenum)GLUT_WINDOW_X);
643             py=glutGet((GLenum)GLUT_WINDOW_Y);
644             sx=glutGet((GLenum)GLUT_WINDOW_WIDTH);
645             sy=glutGet((GLenum)GLUT_WINDOW_HEIGHT);
646             glutFullScreen();
647             glutChangeToMenuEntry(1,"Close Full Screen",1);
648             fullScreen = 1;
649         }
650         break;
651     case 2:
652         toggleIdle();
653         break;
654     case 3:
655         goodbye();
656         break;
657     default:
658         break;
659     }
660 }
661
662 void createMenu()
663 {
664     glutCreateMenu(menu);
665     glutAddMenuEntry("Full Screen", 1);
666     glutAddMenuEntry("Toggle Idle (Start/Stop)", 2);
667     glutAddMenuEntry("Quit", 3);
668     glutAttachMenu(GLUT_RIGHT_BUTTON);
669 }
670
671 int main(int argc, char **argv) {
672     glutInit(&argc, argv);
673     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
674     glutInitWindowPosition(0, 0);
675     glutInitWindowSize(500, 500);
676     glutCreateWindow("Physics demo");
677
678     myinit();
679     glutKeyboardFunc(myKeyboard);
680     glutSpecialFunc(mySpecial);
681     glutReshapeFunc(myReshape);
682     createMenu();
683     glutIdleFunc(NULL);
684
685     glutDisplayFunc(display);
686     glutMainLoop();
687     return 0;
688 }
689
690
691
692
693
694
695