OpenSceneGraph实现的NeHe OpenGL教程 - 第三十课

  • 简介

这节课NeHe课程实现了在场景中进行碰撞检测以及简单的物理作用(碰撞之后的反弹),碰撞检测三维图形学中一个比较高级的主题,本课只涉及了简单的规则几何体之间的碰撞检测,更复杂的实例需要读者去更深入的学习。

  • 实现

本课中碰撞检测的算法包括线与平面的求交检测、线与圆柱体的求交、以及球体之间的碰撞检测,这些碰撞检测的原理可以参考NeHe中的介绍。

具体实现在如下几个函数中:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. ///线面相交  
  2. //  
  3. int TestIntersionPlane(const Plane& plane,const TVector& position,const TVector& direction, double& lamda, TVector& pNormal)  
  4. /线与圆柱体相交///  
  5. //  
  6. int TestIntersionCylinder(const Cylinder& cylinder,const TVector& position,const TVector& direction, double& lamda, TVector& pNormal,TVector& newposition)  
  7. //球体相交/  
  8. //  
  9. int FindBallCol(TVector& point, double& TimePoint, double Time2, int& BallNr1, int& BallNr2)  
之后再每帧中计算了各球体与不同几何体之间的碰撞,具体代码在idle函数中

接下来创建本课中的几何体(包括墙面、地面、圆柱体等)

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Geode* createWalls()  
  2. osg::Geode* createFloor()  
  3. osg::Geode* createCylinder()  
  4. osg::Geode* createCylinder2()  
  5. osg::Geode* createBalls(int i)  
在ManipulatorSceneHandler中的Frame时间中不断地进行计算和判断每个球体的位置(调用idle)

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. switch(ea.getEventType())  
  2. {  
  3. case (osgGA::GUIEventAdapter::FRAME):  
  4.     {  
  5.         idle();  
  6.         viewer->getCamera()->setViewMatrixAsLookAt(osg::Vec3(Pos.X(),Pos.Y(),Pos.Z()), osg::Vec3(Pos.X()+dir.X(),Pos.Y()+dir.Y(),Pos.Z()+dir.Z()), osg::Y_AXIS);  
  7.     }  
最后把这些部分都添加到场景中:

在BuildScene中查看相应的代码

编译运行程序:


附:本课源码(源码中可能存在错误和不足,仅供参考)[其他头文件可以在NeHe课程中下载]

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include "../osgNeHe.h"  
  2.   
  3. #include <QtCore/QTimer>  
  4. #include <QtGui/QApplication>  
  5. #include <QtGui/QVBoxLayout>  
  6.   
  7. #include <osgViewer/Viewer>  
  8. #include <osgDB/ReadFile>  
  9. #include <osgQt/GraphicsWindowQt>  
  10.   
  11. #include <osg/MatrixTransform>  
  12. #include <osg/Plane>  
  13. #include <osg/Texture2D>  
  14. #include <osg/Geode>  
  15. #include <osg/Geometry>  
  16. #include <osg/CullFace>  
  17.   
  18. #include <osgGA/TrackballManipulator>  
  19. #include <osg/ShapeDrawable>  
  20.   
  21. #include <osgGA/GUIEventHandler>  
  22. #include <osgGA/GUIEventAdapter>  
  23. #include <osg/AnimationPath>  
  24. #include <osg/BlendFunc>  
  25. #include <osg/Switch>  
  26. #include <osg/Material>  
  27.   
  28. #include "Tray.h"  
  29. #include "Tvector.h"  
  30.   
  31. //  
  32. GLfloat spec[]={1.0, 1.0 ,1.0 ,1.0};      //sets specular highlight of balls  
  33. GLfloat posl[]={0,400,0,1};               //position of ligth source  
  34. GLfloat amb[]={0.2f, 0.2f, 0.2f ,1.0f};   //global ambient  
  35. GLfloat amb2[]={0.3f, 0.3f, 0.3f ,1.0f};  //ambient of lightsource  
  36.   
  37. TVector dir(0,0,-10);                     //initial direction of camera  
  38. TVector Pos(0,-50,1000);                  //initial position of camera  
  39. float camera_rotation=0;                  //holds rotation around the Y axis  
  40.   
  41.   
  42. TVector veloc(0.5,-0.1,0.5);              //initial velocity of balls  
  43. TVector accel(0,-0.05,0);                 //acceleration ie. gravity of balls  
  44.   
  45. TVector ArrayVel[10];                     //holds velocity of balls  
  46. TVector ArrayPos[10];                     //position of balls  
  47. TVector OldPos[10];                       //old position of balls  
  48. int NrOfBalls;                            //sets the number of balls  
  49. double Time=0.6;                          //timestep of simulation  
  50. int hook_toball1=0, sounds=1;             //hook camera on ball, and sound on/off  
  51. //Plane structure  
  52. struct Plane{  
  53.     TVector _Position;  
  54.     TVector _Normal;  
  55. };  
  56. //Cylinder structure  
  57. struct Cylinder{                            
  58.     TVector _Position;  
  59.     TVector _Axis;  
  60.     double _Radius;  
  61. };  
  62. //Explosion structure  
  63. struct Explosion{  
  64.     TVector _Position;  
  65.     float   _Alpha;  
  66.     float   _Scale;  
  67. };  
  68.   
  69. Plane pl1,pl2,pl3,pl4,pl5;                //the 5 planes of the room  
  70. Cylinder cyl1,cyl2,cyl3;                  //the 2 cylinders of the room  
  71.   
  72. GLuint texture[4], dlist;                 //stores texture objects and display list  
  73. Explosion ExplosionArray[20];             //holds max 20 explosions at once  
  74. //Perform Intersection tests with primitives  
  75.   
  76. osg::Switch *g_SwitchNode;  
  77. //  
  78. ///线面相交  
  79. //  
  80. int TestIntersionPlane(const Plane& plane,const TVector& position,const TVector& direction, double& lamda, TVector& pNormal)  
  81. {  
  82.     double DotProduct=direction.dot(plane._Normal);  
  83.     double l2;  
  84.   
  85.     //determine if ray paralle to plane  
  86.     if ((DotProduct<ZERO)&&(DotProduct>-ZERO))   
  87.         return 0;  
  88.   
  89.     l2=(plane._Normal.dot(plane._Position-position))/DotProduct;  
  90.   
  91.     if (l2<-ZERO)   
  92.         return 0;  
  93.   
  94.     pNormal=plane._Normal;  
  95.     lamda=l2;  
  96.     return 1;  
  97. }  
  98.   
  99.   
  100. //  
  101. /线与圆柱体相交///  
  102. //  
  103. int TestIntersionCylinder(const Cylinder& cylinder,const TVector& position,const TVector& direction, double& lamda, TVector& pNormal,TVector& newposition)  
  104. {  
  105.     TVector RC;  
  106.     double d;  
  107.     double t,s;  
  108.     TVector n,D,O;  
  109.     double ln;  
  110.     double in,out;  
  111.   
  112.   
  113.     TVector::subtract(position,cylinder._Position,RC);  
  114.     TVector::cross(direction,cylinder._Axis,n);  
  115.   
  116.     ln=n.mag();  
  117.   
  118.     if ( (ln<ZERO)&&(ln>-ZERO) ) return 0;  
  119.   
  120.     n.unit();  
  121.   
  122.     d= fabs( RC.dot(n) );  
  123.   
  124.     if (d<=cylinder._Radius)  
  125.     {  
  126.         TVector::cross(RC,cylinder._Axis,O);  
  127.         t= - O.dot(n)/ln;  
  128.         TVector::cross(n,cylinder._Axis,O);  
  129.         O.unit();  
  130.         s= fabs( sqrt(cylinder._Radius*cylinder._Radius - d*d) / direction.dot(O) );  
  131.   
  132.         in=t-s;  
  133.         out=t+s;  
  134.   
  135.         if (in<-ZERO){  
  136.             if (out<-ZERO) return 0;  
  137.             else lamda=out;  
  138.         }  
  139.         else  
  140.             if (out<-ZERO) {  
  141.                 lamda=in;  
  142.             }  
  143.             else  
  144.                 if (in<out) lamda=in;  
  145.                 else lamda=out;  
  146.   
  147.                 newposition=position+direction*lamda;  
  148.                 TVector HB=newposition-cylinder._Position;  
  149.                 pNormal=HB - cylinder._Axis*(HB.dot(cylinder._Axis));  
  150.                 pNormal.unit();  
  151.   
  152.                 return 1;  
  153.     }  
  154.   
  155.     return 0;  
  156. }  
  157.   
  158. //  
  159. //球体相交/  
  160. //  
  161. int FindBallCol(TVector& point, double& TimePoint, double Time2, int& BallNr1, int& BallNr2)  
  162. {  
  163.     TVector RelativeV;  
  164.     TRay rays;  
  165.     double MyTime=0.0, Add=Time2/150.0, Timedummy=10000, Timedummy2=-1;  
  166.     TVector posi;  
  167.   
  168.     //Test all balls against eachother in 150 small steps  
  169.     for (int i=0;i<NrOfBalls-1;i++)  
  170.     {  
  171.         for (int j=i+1;j<NrOfBalls;j++)  
  172.         {     
  173.             RelativeV=ArrayVel[i]-ArrayVel[j];  
  174.             rays=TRay(OldPos[i],TVector::unit(RelativeV));  
  175.             MyTime=0.0;  
  176.   
  177.             if ( (rays.dist(OldPos[j])) > 40) continue;   
  178.   
  179.             while (MyTime<Time2)  
  180.             {  
  181.                 MyTime+=Add;  
  182.                 posi=OldPos[i]+RelativeV*MyTime;  
  183.                 if (posi.dist(OldPos[j])<=40) {  
  184.                     point=posi;  
  185.                     if (Timedummy>(MyTime-Add))   
  186.                         Timedummy=MyTime-Add;  
  187.                     BallNr1=i;  
  188.                     BallNr2=j;  
  189.                     break;  
  190.                 }  
  191.             }  
  192.         }  
  193.     }  
  194.   
  195.     if (Timedummy!=10000) {   
  196.         TimePoint=Timedummy;  
  197.         return 1;  
  198.     }  
  199.   
  200.     return 0;  
  201. }  
  202.   
  203.   
  204. void initVars()  
  205. {  
  206.     //create palnes  
  207.     pl1._Position=TVector(0,-300,0);  
  208.     pl1._Normal=TVector(0,1,0);  
  209.     pl2._Position=TVector(300,0,0);  
  210.     pl2._Normal=TVector(-1,0,0);  
  211.     pl3._Position=TVector(-300,0,0);  
  212.     pl3._Normal=TVector(1,0,0);  
  213.     pl4._Position=TVector(0,0,300);  
  214.     pl4._Normal=TVector(0,0,-1);  
  215.     pl5._Position=TVector(0,0,-300);  
  216.     pl5._Normal=TVector(0,0,1);  
  217.   
  218.   
  219.     //create cylinders  
  220.     cyl1._Position=TVector(0,0,0);  
  221.     cyl1._Axis=TVector(0,1,0);  
  222.     cyl1._Radius=60+20;  
  223.     cyl2._Position=TVector(200,-300,0);  
  224.     cyl2._Axis=TVector(0,0,1);  
  225.     cyl2._Radius=60+20;  
  226.     cyl3._Position=TVector(-200,0,0);  
  227.     cyl3._Axis=TVector(0,1,1);  
  228.     cyl3._Axis.unit();  
  229.     cyl3._Radius=30+20;  
  230.   
  231.     //Set initial positions and velocities of balls  
  232.     //also initialize array which holds explosions  
  233.     NrOfBalls=10;  
  234.     ArrayVel[0]=veloc;  
  235.     ArrayPos[0]=TVector(199,180,10);  
  236.     ExplosionArray[0]._Alpha=0;  
  237.     ExplosionArray[0]._Scale=1;  
  238.     ArrayVel[1]=veloc;  
  239.     ArrayPos[1]=TVector(0,150,100);  
  240.     ExplosionArray[1]._Alpha=0;  
  241.     ExplosionArray[1]._Scale=1;  
  242.     ArrayVel[2]=veloc;  
  243.     ArrayPos[2]=TVector(-100,180,-100);  
  244.     ExplosionArray[2]._Alpha=0;  
  245.     ExplosionArray[2]._Scale=1;  
  246.     for (int i=3; i<10; i++)  
  247.     {  
  248.         ArrayVel[i]=veloc;  
  249.         ArrayPos[i]=TVector(-500+i*75, 300, -500+i*50);  
  250.         ExplosionArray[i]._Alpha=0;  
  251.         ExplosionArray[i]._Scale=1;  
  252.     }  
  253.     for (int i=10; i<20; i++)  
  254.     {  
  255.         ExplosionArray[i]._Alpha=0;  
  256.         ExplosionArray[i]._Scale=1;  
  257.     }  
  258. }  
  259.   
  260.   
  261. void idle()  
  262. {  
  263.     double rt,rt2,rt4,lamda=10000;  
  264.     TVector norm,uveloc;  
  265.     TVector normal,point,time;  
  266.     double RestTime,BallTime;  
  267.     TVector Pos2;  
  268.     int BallNr=0,dummy=0,BallColNr1,BallColNr2;  
  269.     TVector Nc;  
  270.   
  271.     if (!hook_toball1)  
  272.     {  
  273.         camera_rotation+=0.1f;  
  274.         if (camera_rotation>360)  
  275.             camera_rotation=0;  
  276.     }  
  277.   
  278.     RestTime=Time;  
  279.     lamda=1000;  
  280.   
  281.     //Compute velocity for next timestep using Euler equations  
  282.     for (int j=0;j<NrOfBalls;j++)  
  283.         ArrayVel[j]+=accel*RestTime;  
  284.   
  285.     //While timestep not over  
  286.     while (RestTime>ZERO)  
  287.     {  
  288.         lamda=10000;   //initialize to very large value  
  289.   
  290.         //For all the balls find closest intersection between balls and planes/cylinders  
  291.         for (int i=0;i<NrOfBalls;i++)  
  292.         {  
  293.             //compute new position and distance  
  294.             OldPos[i]=ArrayPos[i];  
  295.             TVector::unit(ArrayVel[i],uveloc);  
  296.             ArrayPos[i]=ArrayPos[i]+ArrayVel[i]*RestTime;  
  297.             rt2=OldPos[i].dist(ArrayPos[i]);  
  298.   
  299.             //Test if collision occured between ball and all 5 planes  
  300.             if (TestIntersionPlane(pl1,OldPos[i],uveloc,rt,norm))  
  301.             {    
  302.                 //Find intersection time  
  303.                 rt4=rt*RestTime/rt2;  
  304.   
  305.                 //if smaller than the one already stored replace and in timestep  
  306.                 if (rt4<=lamda)  
  307.                 {   
  308.                     if (rt4<=RestTime+ZERO)  
  309.                         if (! ((rt<=ZERO)&&(uveloc.dot(norm)>ZERO)) )  
  310.                         {  
  311.                             normal=norm;  
  312.                             point=OldPos[i]+uveloc*rt;  
  313.                             lamda=rt4;  
  314.                             BallNr=i;  
  315.                         }  
  316.                 }  
  317.             }  
  318.   
  319.             if (TestIntersionPlane(pl2,OldPos[i],uveloc,rt,norm))  
  320.             {  
  321.                 rt4=rt*RestTime/rt2;  
  322.   
  323.                 if (rt4<=lamda)  
  324.                 {   
  325.                     if (rt4<=RestTime+ZERO)  
  326.                         if (! ((rt<=ZERO)&&(uveloc.dot(norm)>ZERO)) )  
  327.                         {  
  328.                             normal=norm;  
  329.                             point=OldPos[i]+uveloc*rt;  
  330.                             lamda=rt4;  
  331.                             BallNr=i;  
  332.                             dummy=1;  
  333.                         }  
  334.                 }  
  335.   
  336.             }  
  337.   
  338.             if (TestIntersionPlane(pl3,OldPos[i],uveloc,rt,norm))  
  339.             {  
  340.                 rt4=rt*RestTime/rt2;  
  341.   
  342.                 if (rt4<=lamda)  
  343.                 {   
  344.                     if (rt4<=RestTime+ZERO)  
  345.                         if (! ((rt<=ZERO)&&(uveloc.dot(norm)>ZERO)) )  
  346.                         {  
  347.                             normal=norm;  
  348.                             point=OldPos[i]+uveloc*rt;  
  349.                             lamda=rt4;  
  350.                             BallNr=i;  
  351.                         }  
  352.                 }  
  353.             }  
  354.   
  355.             if (TestIntersionPlane(pl4,OldPos[i],uveloc,rt,norm))  
  356.             {  
  357.                 rt4=rt*RestTime/rt2;  
  358.   
  359.                 if (rt4<=lamda)  
  360.                 {   
  361.                     if (rt4<=RestTime+ZERO)  
  362.                         if (! ((rt<=ZERO)&&(uveloc.dot(norm)>ZERO)) )  
  363.                         {  
  364.                             normal=norm;  
  365.                             point=OldPos[i]+uveloc*rt;  
  366.                             lamda=rt4;  
  367.                             BallNr=i;  
  368.                         }  
  369.                 }  
  370.             }  
  371.   
  372.             if (TestIntersionPlane(pl5,OldPos[i],uveloc,rt,norm))  
  373.             {  
  374.                 rt4=rt*RestTime/rt2;  
  375.   
  376.                 if (rt4<=lamda)  
  377.                 {   
  378.                     if (rt4<=RestTime+ZERO)  
  379.                         if (! ((rt<=ZERO)&&(uveloc.dot(norm)>ZERO)) )  
  380.                         {  
  381.                             normal=norm;  
  382.                             point=OldPos[i]+uveloc*rt;  
  383.                             lamda=rt4;  
  384.                             BallNr=i;  
  385.                         }  
  386.                 }  
  387.             }  
  388.   
  389.             //Now test intersection with the 3 cylinders  
  390.             if (TestIntersionCylinder(cyl1,OldPos[i],uveloc,rt,norm,Nc))  
  391.             {  
  392.                 rt4=rt*RestTime/rt2;  
  393.   
  394.                 if (rt4<=lamda)  
  395.                 {   
  396.                     if (rt4<=RestTime+ZERO)  
  397.                         if (! ((rt<=ZERO)&&(uveloc.dot(norm)>ZERO)) )  
  398.                         {  
  399.                             normal=norm;  
  400.                             point=Nc;  
  401.                             lamda=rt4;  
  402.                             BallNr=i;  
  403.                         }  
  404.                 }  
  405.   
  406.             }  
  407.             if (TestIntersionCylinder(cyl2,OldPos[i],uveloc,rt,norm,Nc))  
  408.             {  
  409.                 rt4=rt*RestTime/rt2;  
  410.   
  411.                 if (rt4<=lamda)  
  412.                 {   
  413.                     if (rt4<=RestTime+ZERO)  
  414.                         if (! ((rt<=ZERO)&&(uveloc.dot(norm)>ZERO)) )  
  415.                         {  
  416.                             normal=norm;  
  417.                             point=Nc;  
  418.                             lamda=rt4;  
  419.                             BallNr=i;  
  420.                         }  
  421.                 }  
  422.   
  423.             }  
  424.             if (TestIntersionCylinder(cyl3,OldPos[i],uveloc,rt,norm,Nc))  
  425.             {  
  426.                 rt4=rt*RestTime/rt2;  
  427.   
  428.                 if (rt4<=lamda)  
  429.                 {   
  430.                     if (rt4<=RestTime+ZERO)  
  431.                         if (! ((rt<=ZERO)&&(uveloc.dot(norm)>ZERO)) )  
  432.                         {  
  433.                             normal=norm;  
  434.                             point=Nc;  
  435.                             lamda=rt4;  
  436.                             BallNr=i;  
  437.                         }  
  438.                 }  
  439.   
  440.             }  
  441.         }  
  442.   
  443.         //After all balls were teste with planes/cylinders test for collision  
  444.         //between them and replace if collision time smaller  
  445.         if (FindBallCol(Pos2,BallTime,RestTime,BallColNr1,BallColNr2))  
  446.         {  
  447.             //if (sounds)  
  448.             //  PlaySound("Data/Explode.wav",NULL,SND_FILENAME|SND_ASYNC);  
  449.   
  450.             if ( (lamda==10000) || (lamda>BallTime) )  
  451.             {  
  452.                 RestTime=RestTime-BallTime;  
  453.   
  454.                 TVector pb1,pb2,xaxis,U1x,U1y,U2x,U2y,V1x,V1y,V2x,V2y;  
  455.                 double a,b;  
  456.   
  457.                 pb1=OldPos[BallColNr1]+ArrayVel[BallColNr1]*BallTime;  
  458.                 pb2=OldPos[BallColNr2]+ArrayVel[BallColNr2]*BallTime;  
  459.                 xaxis=(pb2-pb1).unit();  
  460.   
  461.                 a=xaxis.dot(ArrayVel[BallColNr1]);  
  462.                 U1x=xaxis*a;  
  463.                 U1y=ArrayVel[BallColNr1]-U1x;  
  464.   
  465.                 xaxis=(pb1-pb2).unit();  
  466.                 b=xaxis.dot(ArrayVel[BallColNr2]);  
  467.                 U2x=xaxis*b;  
  468.                 U2y=ArrayVel[BallColNr2]-U2x;  
  469.   
  470.                 V1x=(U1x+U2x-(U1x-U2x))*0.5;  
  471.                 V2x=(U1x+U2x-(U2x-U1x))*0.5;  
  472.                 V1y=U1y;  
  473.                 V2y=U2y;  
  474.   
  475.                 for (int j=0;j<NrOfBalls;j++)  
  476.                     ArrayPos[j]=OldPos[j]+ArrayVel[j]*BallTime;  
  477.   
  478.                 ArrayVel[BallColNr1]=V1x+V1y;  
  479.                 ArrayVel[BallColNr2]=V2x+V2y;  
  480.   
  481.                 //Update explosion array  
  482.                 for(int j=0;j<20;j++)  
  483.                 {  
  484.                     if (ExplosionArray[j]._Alpha<=0)  
  485.                     {  
  486.                         ExplosionArray[j]._Alpha=1;  
  487.                         ExplosionArray[j]._Position=ArrayPos[BallColNr1];  
  488.                         ExplosionArray[j]._Scale=1;  
  489.                         break;  
  490.                     }  
  491.                 }  
  492.   
  493.                 continue;  
  494.             }  
  495.         }  
  496.   
  497.         //End of tests   
  498.         //If test occured move simulation for the correct timestep  
  499.         //and compute response for the colliding ball  
  500.         if (lamda!=10000)  
  501.         {          
  502.             RestTime-=lamda;  
  503.   
  504.             for (int j=0;j<NrOfBalls;j++)  
  505.                 ArrayPos[j]=OldPos[j]+ArrayVel[j]*lamda;  
  506.   
  507.             rt2=ArrayVel[BallNr].mag();  
  508.             ArrayVel[BallNr].unit();  
  509.             ArrayVel[BallNr]=TVector::unit( (normal*(2*normal.dot(-ArrayVel[BallNr]))) + ArrayVel[BallNr] );  
  510.             ArrayVel[BallNr]=ArrayVel[BallNr]*rt2;  
  511.   
  512.             //Update explosion array  
  513.             for(int j=0;j<20;j++)  
  514.             {  
  515.                 if (ExplosionArray[j]._Alpha<=0)  
  516.                 {  
  517.                     ExplosionArray[j]._Alpha=1;  
  518.                     ExplosionArray[j]._Position=point;  
  519.                     ExplosionArray[j]._Scale=1;  
  520.                     break;  
  521.                 }  
  522.             }  
  523.         }  
  524.         else RestTime=0;  
  525.   
  526.     }  
  527.   
  528. }  
  529.   
  530. //  
  531. //  
  532. //  
  533.   
  534.   
  535. osg::Geode* createWalls()  
  536. {  
  537.     osg::Geode *geode = new osg::Geode;  
  538.     osg::Geometry *geometry = new osg::Geometry;  
  539.     osg::Vec3Array *vertexArray = new osg::Vec3Array;  
  540.     osg::Vec2Array *textureArray = new osg::Vec2Array;  
  541.     osg::Vec3Array *colorArray = new osg::Vec3Array;  
  542.   
  543.     colorArray->push_back(osg::Vec3(1,1,1));  
  544.   
  545.     vertexArray->push_back(osg::Vec3(320,320,320));  
  546.     vertexArray->push_back(osg::Vec3(320,-320,320));  
  547.     vertexArray->push_back(osg::Vec3(-320,-320,320));  
  548.     vertexArray->push_back(osg::Vec3(-320,320,320));  
  549.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  550.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  551.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  552.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  553.   
  554.     vertexArray->push_back(osg::Vec3(-320,320,-320));  
  555.     vertexArray->push_back(osg::Vec3(-320,-320,-320));  
  556.     vertexArray->push_back(osg::Vec3(320,-320,-320));  
  557.     vertexArray->push_back(osg::Vec3(320,320,-320));  
  558.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  559.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  560.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  561.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  562.   
  563.     vertexArray->push_back(osg::Vec3(320,320,-320));  
  564.     vertexArray->push_back(osg::Vec3(320,-320,-320));  
  565.     vertexArray->push_back(osg::Vec3(320,-320,320));  
  566.     vertexArray->push_back(osg::Vec3(320,320,320));  
  567.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  568.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  569.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  570.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  571.   
  572.     vertexArray->push_back(osg::Vec3(-320,320,320));  
  573.     vertexArray->push_back(osg::Vec3(-320,-320,320));  
  574.     vertexArray->push_back(osg::Vec3(-320,-320,-320));  
  575.     vertexArray->push_back(osg::Vec3(-320,320,-320));  
  576.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  577.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  578.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  579.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  580.   
  581.     geometry->setVertexArray(vertexArray);  
  582.     geometry->setColorArray(colorArray, osg::Array::BIND_OVERALL);  
  583.     geometry->setTexCoordArray(0, textureArray, osg::Array::BIND_PER_VERTEX);  
  584.   
  585.     osg::Texture2D *texture2D = new osg::Texture2D;  
  586.     texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  587.     texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  588.     texture2D->setImage(osgDB::readImageFile("Data/wand.bmp"));  
  589.     geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture2D);  
  590.     geometry->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace());  
  591.   
  592.     geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertexArray->size()));  
  593.     geode->addDrawable(geometry);  
  594.   
  595.     return geode;  
  596. }  
  597.   
  598.   
  599. osg::Geode* createFloor()  
  600. {  
  601.     osg::Geode *geode = new osg::Geode;  
  602.     osg::Geometry *geometry = new osg::Geometry;  
  603.   
  604.     osg::Vec3Array *vertexArray = new osg::Vec3Array;  
  605.     osg::Vec2Array *textureArray = new osg::Vec2Array;  
  606.     osg::Vec3Array *colorArray = new osg::Vec3Array;  
  607.     colorArray->push_back(osg::Vec3(1,1,1));  
  608.     vertexArray->push_back(osg::Vec3(-320,-320,320));  
  609.     vertexArray->push_back(osg::Vec3(320,-320,320));  
  610.     vertexArray->push_back(osg::Vec3(320,-320,-320));  
  611.     vertexArray->push_back(osg::Vec3(-320,-320,-320));  
  612.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  613.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  614.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  615.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  616.     geometry->setVertexArray(vertexArray);  
  617.     geometry->setColorArray(colorArray, osg::Array::BIND_OVERALL);  
  618.     geometry->setTexCoordArray(0, textureArray, osg::Array::BIND_PER_VERTEX);  
  619.   
  620.     osg::Texture2D *texture2D = new osg::Texture2D;  
  621.     texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  622.     texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  623.     texture2D->setImage(osgDB::readImageFile("Data/boden.bmp"));  
  624.     geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture2D);  
  625.   
  626.     geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertexArray->size()));  
  627.     geode->addDrawable(geometry);  
  628.   
  629.     return geode;  
  630. }  
  631.   
  632.   
  633.   
  634. osg::Geode* createCylinder()  
  635. {  
  636.     osg::Geode *cylinderGeode = new osg::Geode;  
  637.     osg::ShapeDrawable *shapeDrawable = new osg::ShapeDrawable;  
  638.     osg::Texture2D *texture2D = new osg::Texture2D;  
  639.     texture2D->setImage(osgDB::readImageFile("Data/Marble.bmp"));  
  640.     shapeDrawable->getOrCreateStateSet()->setTextureAttributeAndModes(0,texture2D);  
  641.     shapeDrawable->setColor(osg::Vec4(0.5,0.5,0.5, 1.0));  
  642.     shapeDrawable->setShape(new osg::Cylinder(osg::Vec3(), 60, 2000));  
  643.     cylinderGeode->addDrawable(shapeDrawable);  
  644.       
  645.     return cylinderGeode;  
  646. }  
  647.   
  648. osg::Geode* createCylinder2()  
  649. {  
  650.     osg::Geode *cylinderGeode = new osg::Geode;  
  651.     osg::ShapeDrawable *shapeDrawable = new osg::ShapeDrawable;  
  652.   
  653.     osg::Texture2D *texture2D = new osg::Texture2D;  
  654.     texture2D->setImage(osgDB::readImageFile("Data/Marble.bmp"));  
  655.     shapeDrawable->getOrCreateStateSet()->setTextureAttributeAndModes(0,texture2D);  
  656.     shapeDrawable->setColor(osg::Vec4(0.5,0.5,0.5, 1.0));  
  657.     shapeDrawable->setShape(new osg::Cylinder(osg::Vec3(), 30, 2000));  
  658.     cylinderGeode->addDrawable(shapeDrawable);  
  659.   
  660.     return cylinderGeode;  
  661. }  
  662.   
  663. osg::Geode* createBalls(int i)  
  664. {  
  665.     osg::Geode *cylinderSphere = new osg::Geode;  
  666.     osg::ShapeDrawable *shapeDrawable = new osg::ShapeDrawable;  
  667.   
  668.     switch(i){  
  669.         case 1: shapeDrawable->setColor(osg::Vec4(1.0f,1.0f,1.0f, 1.0f));  
  670.             break;  
  671.         case 2: shapeDrawable->setColor(osg::Vec4(1.0f,1.0f,0.0f, 1.0f));  
  672.             break;  
  673.         case 3: shapeDrawable->setColor(osg::Vec4(0.0f,1.0f,1.0f, 1.0f));  
  674.             break;  
  675.         case 4: shapeDrawable->setColor(osg::Vec4(0.0f,1.0f,0.0f, 1.0f));  
  676.             break;  
  677.         case 5: shapeDrawable->setColor(osg::Vec4(0.0f,0.0f,1.0f, 1.0f));  
  678.             break;  
  679.         case 6: shapeDrawable->setColor(osg::Vec4(0.65f,0.2f,0.3f, 1.0f));  
  680.             break;  
  681.         case 7: shapeDrawable->setColor(osg::Vec4(1.0f,0.0f,1.0f, 1.0f));  
  682.             break;  
  683.         case 8: shapeDrawable->setColor(osg::Vec4(0.0f,0.7f,0.4f,1.0f));  
  684.             break;  
  685.         default: shapeDrawable->setColor(osg::Vec4(1.0f, 0.0, 0.0, 1.0));  
  686.     }  
  687.     shapeDrawable->setShape(new osg::Sphere(osg::Vec3(), 20));  
  688.     cylinderSphere->addDrawable(shapeDrawable);  
  689.   
  690.     return cylinderSphere;  
  691. }  
  692.   
  693.   
  694. //  
  695. //  
  696. //  
  697. //  
  698. //  
  699. class ManipulatorSceneHandler : public osgGA::GUIEventHandler  
  700. {  
  701. public:  
  702.     ManipulatorSceneHandler()  
  703.     {  
  704.     }  
  705.   
  706. public:  
  707.     virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)  
  708.     {  
  709.         osgViewer::Viewer *viewer = dynamic_cast<osgViewer::Viewer*>(&aa);  
  710.         if (!viewer)  
  711.             return false;  
  712.         if (!viewer->getSceneData())  
  713.             return false;  
  714.         if (ea.getHandled())   
  715.             return false;  
  716.   
  717.         osg::Group *root = viewer->getSceneData()->asGroup();  
  718.   
  719.         switch(ea.getEventType())  
  720.         {  
  721.         case (osgGA::GUIEventAdapter::FRAME):  
  722.             {  
  723.                 idle();  
  724.                 viewer->getCamera()->setViewMatrixAsLookAt(osg::Vec3(Pos.X(),Pos.Y(),Pos.Z()), osg::Vec3(Pos.X()+dir.X(),Pos.Y()+dir.Y(),Pos.Z()+dir.Z()), osg::Y_AXIS);  
  725.             }  
  726.         case(osgGA::GUIEventAdapter::KEYDOWN):  
  727.             {  
  728.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)  
  729.                 {  
  730.                 }  
  731.   
  732.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)  
  733.                 {  
  734.                 }  
  735.   
  736.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Space)  
  737.                 {  
  738.                 }  
  739.             }  
  740.         defaultbreak;  
  741.         }  
  742.         return false;  
  743.     }  
  744. };  
  745.   
  746. //  
  747.   
  748. class PostionUpdateCallback : public osg::NodeCallback  
  749. {  
  750. public:  
  751.     PostionUpdateCallback(int index) : _index(index){ }  
  752.   
  753.     virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  754.     {  
  755.         osg::MatrixTransform *mt = dynamic_cast<osg::MatrixTransform*>(node);  
  756.         if (!mt)  
  757.             return;  
  758.   
  759.         mt->setMatrix(osg::Matrix::translate(ArrayPos[_index].X(),ArrayPos[_index].Y(),ArrayPos[_index].Z()));  
  760.           
  761.         traverse(node, nv);  
  762.     }  
  763.       
  764.     int _index;  
  765. };  
  766.   
  767.   
  768. class CollisionSwitchUpdateCallback : public osg::NodeCallback  
  769. {  
  770. public:  
  771.     CollisionSwitchUpdateCallback(int index) : _index(index){ }  
  772.   
  773.     virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  774.     {  
  775.         osg::Switch *st = dynamic_cast<osg::Switch*>(node);  
  776.         if (!st)  
  777.             return;  
  778.   
  779.         if (ExplosionArray[_index]._Alpha >= 0)  
  780.         {  
  781.             ExplosionArray[_index]._Alpha-=0.01f;  
  782.             ExplosionArray[_index]._Scale+=0.03f;  
  783.             st->setAllChildrenOn();  
  784.         }  
  785.         else  
  786.         {  
  787.             st->setAllChildrenOff();  
  788.         }  
  789.           
  790.           
  791.   
  792.         traverse(node, nv);  
  793.     }  
  794.   
  795.     int _index;  
  796. };  
  797.   
  798.   
  799.   
  800.   
  801. class CollisionScaleUpdateCallback : public osg::NodeCallback  
  802. {  
  803. public:  
  804.     CollisionScaleUpdateCallback(int index) : _index(index){ }  
  805.   
  806.     virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  807.     {  
  808.         osg::MatrixTransform *mt = dynamic_cast<osg::MatrixTransform*>(node);  
  809.         if (!mt)  
  810.             return;  
  811.           
  812.         if (ExplosionArray[_index]._Alpha >= 0)  
  813.         {  
  814.             mt->setMatrix(osg::Matrix::scale(ExplosionArray[_index]._Scale,ExplosionArray[_index]._Scale,ExplosionArray[_index]._Scale));  
  815.         }  
  816.   
  817.         traverse(node, nv);  
  818.     }  
  819.   
  820.     int _index;  
  821. };  
  822.   
  823.   
  824. class CollisionTransUpdateCallback : public osg::NodeCallback  
  825. {  
  826. public:  
  827.     CollisionTransUpdateCallback(int index) : _index(index){ }  
  828.   
  829.     virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  830.     {  
  831.         osg::MatrixTransform *mt = dynamic_cast<osg::MatrixTransform*>(node);  
  832.         if (!mt)  
  833.             return;  
  834.   
  835.         if (ExplosionArray[_index]._Alpha >= 0)  
  836.         {  
  837.             mt->setMatrix(osg::Matrix::translate(ArrayPos[_index].X(),ArrayPos[_index].Y(),ArrayPos[_index].Z()));  
  838.         }     
  839.   
  840.         traverse(node, nv);  
  841.     }  
  842.   
  843.     int _index;  
  844. };  
  845.   
  846.   
  847. class CollisionGeometryUpdateCallback : public  osg::Drawable::UpdateCallback  
  848. {  
  849. public:  
  850.     CollisionGeometryUpdateCallback(int index) : _index(index){ }  
  851.   
  852.     virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)  
  853.     {  
  854.         osg::Geometry *geo = dynamic_cast<osg::Geometry*>(drawable);  
  855.         if (!geo)  
  856.             return;  
  857.   
  858.         osg::Vec4Array *colorArray = dynamic_cast<osg::Vec4Array*>(geo->getColorArray());  
  859.         if(!colorArray)  
  860.             return;  
  861.           
  862.         colorArray->clear();  
  863.         colorArray->push_back(osg::Vec4(1,1,0,ExplosionArray[_index]._Alpha));  
  864.         geo->setColorArray(colorArray, osg::Array::BIND_OVERALL);  
  865.     }  
  866.   
  867.     int _index;  
  868. };  
  869.   
  870.   
  871.   
  872. //  
  873. osg::Node*  createExplorsionNode(int i)  
  874. {  
  875.     osg::MatrixTransform *rotMT = new osg::MatrixTransform;  
  876.     rotMT->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(-45.0), osg::Y_AXIS));  
  877.   
  878.     osg::Geode *geode = new osg::Geode;  
  879.     osg::Geometry *geometry = new osg::Geometry;  
  880.     geometry->setUpdateCallback(new CollisionGeometryUpdateCallback(i));  
  881.     osg::Vec3Array *vertexArray = new osg::Vec3Array;  
  882.     osg::Vec3Array *normalArray = new osg::Vec3Array;  
  883.     osg::Vec2Array *textureArray = new osg::Vec2Array;  
  884.     osg::Vec4Array *colorArray = new osg::Vec4Array;  
  885.     colorArray->push_back(osg::Vec4(0,0,0,1));  
  886.   
  887.     vertexArray->push_back(osg::Vec3(-50,-40,0));  
  888.     vertexArray->push_back(osg::Vec3(50,-40,0));  
  889.     vertexArray->push_back(osg::Vec3(50,40,0));  
  890.     vertexArray->push_back(osg::Vec3(-50,40,0));  
  891.     for (int j = 0; j < 4; ++j)  
  892.     {  
  893.         normalArray->push_back(osg::Vec3(0,0,1));  
  894.     }  
  895.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  896.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  897.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  898.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  899.   
  900.     vertexArray->push_back(osg::Vec3(-50,40,0));  
  901.     vertexArray->push_back(osg::Vec3(50,40,0));  
  902.     vertexArray->push_back(osg::Vec3(50,-40,0));  
  903.     vertexArray->push_back(osg::Vec3(-50,-40,0));  
  904.     for (int j = 0; j < 4; ++j)  
  905.     {  
  906.         normalArray->push_back(osg::Vec3(0,0,-1));  
  907.     }  
  908.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  909.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  910.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  911.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  912.   
  913.     vertexArray->push_back(osg::Vec3(0,-40,50));  
  914.     vertexArray->push_back(osg::Vec3(0,-40,-50));  
  915.     vertexArray->push_back(osg::Vec3(0,40,-50));  
  916.     vertexArray->push_back(osg::Vec3(0,40,50));  
  917.     for (int j = 0; j < 4; ++j)  
  918.     {  
  919.         normalArray->push_back(osg::Vec3(1,0,0));  
  920.     }  
  921.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  922.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  923.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  924.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  925.   
  926.     vertexArray->push_back(osg::Vec3(0,40,50));  
  927.     vertexArray->push_back(osg::Vec3(0,40,-50));  
  928.     vertexArray->push_back(osg::Vec3(0,-40,-50));  
  929.     vertexArray->push_back(osg::Vec3(0,-40,50));  
  930.     for (int j = 0; j < 4; ++j)  
  931.     {  
  932.         normalArray->push_back(osg::Vec3(-1,0,0));  
  933.     }  
  934.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  935.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  936.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  937.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  938.   
  939.     osg::Texture2D *texture2D = new osg::Texture2D;  
  940.     texture2D->setImage(osgDB::readImageFile("Data/spark.bmp"));  
  941.   
  942.     osg::BlendFunc *blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE);  
  943.   
  944.     osg::Material *material = new osg::Material();  
  945.     material->setShininess(osg::Material::FRONT,100.0);  
  946.     material->setSpecular(osg::Material::FRONT, osg::Vec4(1.0, 1.0 ,1.0 ,1.0));  
  947.     material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);  
  948.   
  949.     geometry->setVertexArray(vertexArray);  
  950.     geometry->setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX);  
  951.     geometry->setTexCoordArray(0, textureArray, osg::Array::BIND_PER_VERTEX);  
  952.     geometry->setColorArray(colorArray, osg::Array::BIND_OVERALL);  
  953.     geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture2D);  
  954.     geometry->getOrCreateStateSet()->setAttributeAndModes(blendFunc);  
  955.     geometry->getOrCreateStateSet()->setAttributeAndModes(material);  
  956.     geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertexArray->size()));  
  957.     geometry->setUseDisplayList(false);  
  958.     geode->addDrawable(geometry);  
  959.     rotMT->addChild(geode);  
  960.   
  961.     return rotMT;  
  962. }  
  963.   
  964. //  
  965. /osgNeHe框架/  
  966. //  
  967.   
  968. class ViewerWidget : public QWidget, public osgViewer::Viewer  
  969. {  
  970. public:  
  971.     ViewerWidget(osg::Node *scene = NULL)  
  972.     {  
  973.         QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,100,100), scene);  
  974.   
  975.         QVBoxLayout* layout = new QVBoxLayout;  
  976.         layout->addWidget(renderWidget);  
  977.         layout->setContentsMargins(0, 0, 0, 1);  
  978.         setLayout( layout );  
  979.   
  980.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  981.         _timer.start( 10 );  
  982.     }  
  983.   
  984.     QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )  
  985.     {  
  986.         osg::Camera* camera = this->getCamera();  
  987.         camera->setGraphicsContext( gw );  
  988.   
  989.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  990.   
  991.         camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 0.0) );  
  992.         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );  
  993.         camera->setProjectionMatrixAsPerspective(50.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 10.0f, 1000.0f);  
  994.         this->setSceneData(scene);  
  995.         addEventHandler(new ManipulatorSceneHandler);  
  996.   
  997.         return gw->getGLWidget();  
  998.     }  
  999.   
  1000.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  1001.     {  
  1002.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  1003.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  1004.         traits->windowName = name;  
  1005.         traits->windowDecoration = windowDecoration;  
  1006.         traits->x = x;  
  1007.         traits->y = y;  
  1008.         traits->width = w;  
  1009.         traits->height = h;  
  1010.         traits->doubleBuffer = true;  
  1011.         traits->alpha = ds->getMinimumNumAlphaBits();  
  1012.         traits->stencil = ds->getMinimumNumStencilBits();  
  1013.         traits->sampleBuffers = ds->getMultiSamples();  
  1014.         traits->samples = ds->getNumMultiSamples();  
  1015.   
  1016.         return new osgQt::GraphicsWindowQt(traits.get());  
  1017.     }  
  1018.   
  1019.     virtual void paintEvent( QPaintEvent* event )  
  1020.     {   
  1021.         frame();   
  1022.     }  
  1023.   
  1024. protected:  
  1025.   
  1026.     QTimer _timer;  
  1027. };  
  1028.   
  1029.   
  1030.   
  1031. osg::Node*  buildScene()  
  1032. {  
  1033.     initVars();  
  1034.     osg::Group *root = new osg::Group;  
  1035.   
  1036.     osg::Light *light = new osg::Light;  
  1037.     light->setAmbient(osg::Vec4(amb2[0], amb2[1],amb2[2], amb2[3]));  
  1038.     light->setLightNum(0);  
  1039.     light->setPosition(osg::Vec4(posl[0],posl[1],posl[2],posl[3]) );  
  1040.     osg::LightSource *lightSource = new osg::LightSource;  
  1041.     lightSource->setLight(light);  
  1042.     root->addChild(lightSource);  
  1043.       
  1044.   
  1045.     osg::MatrixTransform *rotMT = new osg::MatrixTransform;  
  1046.     rotMT->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Y_AXIS, 0.5));  
  1047.     rotMT->addChild(createWalls());  
  1048.     rotMT->addChild(createFloor());  
  1049.   
  1050.     osg::MatrixTransform *cylinderRotMT1 = new osg::MatrixTransform;  
  1051.     osg::MatrixTransform *cylinderTransMT1 = new osg::MatrixTransform;  
  1052.     cylinderRotMT1->setMatrix(osg::Matrix::rotate(osg::PI_2, osg::X_AXIS));  
  1053.     cylinderTransMT1->setMatrix(osg::Matrix::translate(0, 0, -500));  
  1054.     cylinderTransMT1->addChild(createCylinder());  
  1055.     cylinderRotMT1->addChild(cylinderTransMT1);  
  1056.       
  1057.     osg::MatrixTransform *cylinderTransMT2 = new osg::MatrixTransform;  
  1058.     cylinderTransMT2->setMatrix(osg::Matrix::translate(200,-300,-500));  
  1059.     cylinderTransMT2->addChild(createCylinder());  
  1060.   
  1061.     osg::MatrixTransform *cylinderTransMT31 = new osg::MatrixTransform;  
  1062.     osg::MatrixTransform *cylinderRotMT3 = new osg::MatrixTransform;  
  1063.     osg::MatrixTransform *cylinderTransMT32 = new osg::MatrixTransform;  
  1064.     cylinderTransMT31->setMatrix(osg::Matrix::translate(-200, 0, 0));  
  1065.     cylinderRotMT3->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(135.0), osg::X_AXIS));  
  1066.     cylinderTransMT32->setMatrix(osg::Matrix::translate(0, 0, -500));  
  1067.     cylinderTransMT32->addChild(createCylinder2());  
  1068.     cylinderTransMT31->addChild(cylinderRotMT3);  
  1069.     cylinderRotMT3->addChild(cylinderTransMT32);  
  1070.   
  1071.     rotMT->addChild(cylinderRotMT1);  
  1072.     rotMT->addChild(cylinderTransMT2);  
  1073.     rotMT->addChild(cylinderTransMT31);  
  1074.   
  1075.   
  1076.     for (int i = 0; i < NrOfBalls; ++i)  
  1077.     {  
  1078.         osg::MatrixTransform *mt = new osg::MatrixTransform;  
  1079.         mt->addUpdateCallback(new PostionUpdateCallback(i));  
  1080.         mt->addChild(createBalls(i));  
  1081.         rotMT->addChild(mt);  
  1082.     }  
  1083.   
  1084.     //  
  1085.       
  1086.     for (int i = 0; i < 20; ++i)  
  1087.     {  
  1088.         osg::Switch *switchNode = new osg::Switch;  
  1089.         g_SwitchNode = switchNode;  
  1090.         switchNode->addUpdateCallback(new CollisionSwitchUpdateCallback(i));  
  1091.         osg::MatrixTransform *collisionScale = new osg::MatrixTransform;  
  1092.         collisionScale->addUpdateCallback(new CollisionScaleUpdateCallback(i));  
  1093.         osg::MatrixTransform *collisionMT = new osg::MatrixTransform;  
  1094.         collisionMT->addUpdateCallback(new CollisionTransUpdateCallback(i));  
  1095.         osg::Node *collisionNode = createExplorsionNode(i);  
  1096.         collisionScale->addChild(collisionMT);  
  1097.         collisionMT->addChild(collisionNode);  
  1098.         switchNode->addChild(collisionScale);  
  1099.         rotMT->addChild(switchNode);  
  1100.     }  
  1101.       
  1102.     root->addChild(rotMT);  
  1103.   
  1104.     return root;  
  1105. }  
  1106.   
  1107.   
  1108.   
  1109. int main( int argc, char** argv )  
  1110. {  
  1111.     QApplication app(argc, argv);  
  1112.     ViewerWidget* viewWidget = new ViewerWidget(buildScene());  
  1113.     viewWidget->setGeometry( 100, 100, 640, 480 );  
  1114.     viewWidget->show();  
  1115.     return app.exec();  
  1116. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值