BreakableBody.h
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:18k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /*
  2. * Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty.  In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. * Permission is granted to anyone to use this software for any purpose,
  8. * including commercial applications, and to alter it and redistribute it
  9. * freely, subject to the following restrictions:
  10. * 1. The origin of this software must not be misrepresented; you must not
  11. * claim that you wrote the original software. If you use this software
  12. * in a product, an acknowledgment in the product documentation would be
  13. * appreciated but is not required.
  14. * 2. Altered source versions must be plainly marked as such, and must not be
  15. * misrepresented as being the original software.
  16. * 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. /* Testbed example showing deformable and breakable bodies using the soft
  19.  * b2DistanceJoint and a small,liteweight triangle mesher.
  20.  * 2008-05-09 / nimodo 
  21.  */
  22. #ifndef BREAKABLE_BODY_H
  23. #define BREAKABLE_BODY_H
  24. #include "TriangleMesh.h"
  25. /// utility macro
  26. #define H(x) (x)/2.0f 
  27. #define N_MAXVERTEX 256
  28. class BreakableBody : public Test
  29. {
  30. public:  
  31.    BreakableBody()
  32.    {   
  33.         /// geometries
  34.         float32  gx  = 100.0f, gy =  1.0f, 
  35.                  dx  =  34.0f, br =   0.3f; 
  36.         float32  sx=-dx-H(dx), sy = 30.f;  
  37.         /// break joint, if the reactionforce exceeds: 
  38.         maxAllowableForce = 100.0f;
  39.         m_drawMode = m_staticBodies = false;
  40.         m_drawCount = 0;
  41.         /// ground
  42.         { 
  43.          b2PolygonDef sd;
  44.          b2BodyDef    bd;
  45.          b2Body*      ground;       
  46.  bd.position.Set(0.0f, 0.0f);
  47.          ground = m_world->CreateBody(&bd);
  48.          /// bottom
  49.          sd.SetAsBox( H(gx), H(gy) );
  50.          ground->CreateFixture(&sd);
  51.          sd.SetAsBox( H(dx), H(gy), b2Vec2(-dx,sy-1.0f), 0.0f );
  52.          ground->CreateFixture(&sd);
  53.         }  
  54.         /// dyn bodies 
  55.         { 
  56.          b2PolygonDef       pd;
  57.          b2DistanceJointDef dj;
  58.          
  59.          dj.dampingRatio     = 0.0f;
  60.          dj.collideConnected = true;
  61.          ExampleData('B');
  62.          dj.frequencyHz      = 20.f;
  63.          pd.density          = 1.0f/70.0f;
  64.          pd.friction         = 0.4f;
  65.          pd.restitution      = 0.01f;
  66.          CreateSoftBody( b2Vec2(sx,sy), 0,  0, pd, dj, 
  67.                          nodes,n_nodes,  segments,n_segments,  holes,n_holes) ;
  68.          ExampleData('@');
  69.          dj.frequencyHz      = 20.f;
  70.          pd.density          = 1.0f/36.0f;
  71.          pd.friction         = 0.1f;
  72.          pd.restitution      = 0.5f;
  73.          CreateSoftBody( b2Vec2(sx+6.f,sy), 0, 0, pd, dj, 
  74.                          nodes,n_nodes,  segments,n_segments,  holes,n_holes) ;
  75.          
  76.          ExampleData('x');                        
  77.          dj.frequencyHz      = 20.0f;            
  78.          pd.density          = 1.0f/60.0f;
  79.          pd.friction         = 0.6f;
  80.          pd.restitution      = 0.0f;
  81.          CreateSoftBody( b2Vec2(sx+13.f,sy),  0, 0,   pd, dj, 
  82.                          nodes,n_nodes,  segments,n_segments,  holes,n_holes) ;
  83.          ExampleData('2');
  84.          pd.density          = 0.01f;
  85.          pd.friction         = 0.3f;
  86.          pd.restitution      = 0.3f;
  87.          CreateSoftBody( b2Vec2(sx+20.f,sy),  0, 0,   pd, dj, 
  88.                          nodes,n_nodes,  segments,n_segments,  holes,n_holes) ;
  89.          ExampleData('D');
  90.          CreateSoftBody( b2Vec2(sx+28.f,sy),  0, 0,   pd, dj, 
  91.                          nodes,n_nodes,  segments,n_segments,  holes,n_holes) ;
  92.           
  93.          ExampleData('b');
  94.          dj.frequencyHz      = 10.0f;
  95.          dj.dampingRatio     = 20.0f;
  96.          pd.friction         = 0.9f;
  97.          pd.restitution      = 0.01f;
  98.          pd.density          = 0.01f;
  99.          CreateSoftBody( b2Vec2(-5.f,5.f*gy),  0, 0,   pd, dj, 
  100.                          nodes,n_nodes,  segments,n_segments,  holes,n_holes) ;
  101.          
  102.          b2CircleDef cd;
  103.          b2BodyDef   bd;
  104.          b2Body*     b;
  105.          cd.radius = br;
  106.          cd.density= 0.001f; 
  107.          bd.position.Set(0.0f,10.0f*gy);
  108.          for (int32 i=0; i<60; i++ )
  109.          {
  110.            b = m_world->CreateBody(&bd);
  111.            b->CreateFixture (&cd);
  112.            b->SetMassFromShapes();
  113.          }
  114.          
  115.         }
  116.     }
  117.     /// Create compound (soft) body using a triangle mesh
  118.     /// If meshDensity is 0, a minimal grid is generated.
  119.     /// Actually pd and dj define the behaviour for all triangles
  120.     void CreateSoftBody(b2Vec2 pos, int32 meshDensity,int32 options,
  121.                        b2PolygonDef pd, b2DistanceJointDef dj,
  122.                        tmVertex* nodes,int32 n_nodes,
  123.                        tmSegmentId *segments=NULL, int32 n_segments=0,
  124.                        tmVertex* holes=NULL, int32 n_holes=0)
  125.     {
  126.         int32   i;
  127.         /// TriangleMesh defs
  128.         tmTriangle *triangles;        
  129.         TriangleMesh     md;
  130.         /// box2d defs
  131.         b2BodyDef          bd;
  132.         b2Body             *b; 
  133.         /// in case of meshDensit>3 ...
  134.         md.SetMaxVertexCount(meshDensity); 
  135.         if (options>0) md.SetOptions(options);
  136.         /// triangulator main 
  137.         md.Mesh( nodes, n_nodes,  segments,n_segments,  holes, n_holes );
  138.         md.PrintData();        
  139.         /// bodies (triangles) 
  140.         triangles = md.GetTriangles(); 
  141.         if ( triangles==NULL ) return;
  142.         pd.vertexCount = 3;
  143.         for ( i=0; i<md.GetTriangleCount(); i++ )
  144.         {
  145.           if ( triangles[i].inside ) 
  146.           {
  147.             /// triangle -> b2PolygonDef
  148.             pd.vertices[0].Set(triangles[i].v[0]->x, triangles[i].v[0]->y);
  149.             pd.vertices[1].Set(triangles[i].v[1]->x, triangles[i].v[1]->y);
  150.             pd.vertices[2].Set(triangles[i].v[2]->x, triangles[i].v[2]->y);
  151.             bd.position.Set(pos.x,pos.y);
  152.             b = m_world->CreateBody(&bd);
  153.             b->CreateFixture(&pd);
  154.             b->SetMassFromShapes();
  155.             /// we need the body pointer in the triangles for the joints later
  156.             triangles[i].userData = (void *)b;
  157.           }
  158.         }   
  159.         /// joints
  160.         /// for each triangle-pair in edges, connect with a distance joint
  161.         tmEdge        *edges;
  162.         tmTriangle    *t0,*t1;        
  163.         b2Body        *b1,*b2; 
  164.         edges = md.GetEdges();
  165.         for ( i=0; i<md.GetEdgeCount(); i++ )
  166.         {
  167.            t0 = edges[i].t[0];
  168.            t1 = edges[i].t[1];
  169.            if ( (t0->inside==false) || (t1->inside==false) ) continue;      
  170.            
  171.            /// Get bodies
  172.            b1 = (b2Body*)t0->userData;
  173.            b2 = (b2Body*)t1->userData;
  174.            if ( b1==NULL || b2==NULL ) continue;
  175.            dj.Initialize( b1,b2, b1->GetWorldCenter(), b2->GetWorldCenter());     
  176.            m_world->CreateJoint(&dj);
  177.         }
  178.         /// clean TriangleMesh 
  179.         md.FreeMemory();
  180.     }
  181.   
  182.     /// maybe here to check for maximal reaction forces to break a body
  183.     void Step(Settings* settings)
  184.     {
  185.       b2Joint *jStressed=NULL; 
  186.       float32 F=0.0f, tmp;
  187.       Test::Step(settings);
  188.       for (b2Joint* j = m_world->GetJointList(); j; j = j->GetNext())
  189.     {
  190.           tmp = j->GetReactionForce(settings->hz).Length();
  191.           if ( tmp>F ) 
  192.           {
  193.               F = tmp;
  194.               jStressed = j;
  195.           }
  196.     }       
  197.       if ( jStressed && (F>maxAllowableForce) ) 
  198.       {
  199.           m_world->DestroyJoint(jStressed);
  200.       }
  201.       m_debugDraw.DrawString(1, m_textLine,"max.reactionforce=%.0f allowable=%.0f  change:-+", (float)F,(float)maxAllowableForce);       
  202.       m_textLine += 12;
  203.       m_debugDraw.DrawString(1, m_textLine,"drawmode(%s):d  mesh:m  static(%s):s", (m_drawMode)?"on":"off", (m_staticBodies)?"on":"off");       
  204.       m_textLine += 12;
  205.       for ( int32 i=0; i<m_drawCount-1; i++ )
  206.       {
  207.           b2Vec2 p1,p2;
  208.           p1.Set(m_drawVertices[i].x,m_drawVertices[i].y);
  209.           p2.Set(m_drawVertices[i+1].x,m_drawVertices[i+1].y);
  210.           m_debugDraw.DrawSegment(p1,p2,b2Color(0.6f,0.2f,0.2f));
  211.       }
  212.     }
  213.     /// default constructor for TestEntries.cpp
  214.     static Test* Create()
  215.     {
  216.       return new BreakableBody;
  217.     }
  218.     void Keyboard(unsigned char key)
  219.     {
  220.       switch (key)
  221.       {
  222.        case '-':
  223.            maxAllowableForce -= 5.0f;
  224.          break;
  225.        case '+':
  226.            maxAllowableForce += 5.0f;
  227.          break;
  228.        case 'd':
  229.            m_drawMode = !m_drawMode; 
  230.          break;
  231.        case 's':
  232.            m_staticBodies = !m_staticBodies; 
  233.          break;
  234.        case 'm':
  235.            if ( m_drawCount>0 )
  236.            {              
  237.              b2PolygonDef       pd;
  238.              b2DistanceJointDef dj;
  239.              dj.collideConnected = true;
  240.              dj.frequencyHz      = 20.f;
  241.              dj.dampingRatio     = 10.0f;
  242.              pd.density          = (m_staticBodies) ? 0.0f : 1.0f/32.0f;
  243.              pd.friction         = 0.99f;
  244.              pd.restitution      = 0.01f;
  245.              CreateSoftBody( b2Vec2(0.0f,0.0f),  0, tmO_SEGMENTBOUNDARY|tmO_GRADING,   
  246.                              pd, dj, m_drawVertices, m_drawCount) ;
  247.              
  248.              m_drawCount = 0;
  249.              m_drawMode = false; 
  250.            }
  251.          break;
  252.       }
  253.     }
  254.     void MouseDown(const b2Vec2& p)
  255.     {   
  256.         if ( m_drawMode && (m_drawCount<N_MAXVERTEX) )
  257.         {
  258.             m_drawVertices[m_drawCount].x = p.x; 
  259.             m_drawVertices[m_drawCount].y = p.y;
  260.             m_drawCount++;
  261.         }
  262.         else Test::MouseDown(p);
  263.     }
  264. /*
  265.     void MouseMove(const b2Vec2& p)
  266.     {
  267.     m_lastPoint = p;
  268. if (m_drawMode)
  269.         {          
  270.         }
  271.     }
  272. */
  273.     void MouseUp(const b2Vec2& p)
  274.     {
  275.         Test::MouseUp(p);
  276.     }
  277.     /// examples
  278.     void ExampleData(char which)
  279.     {
  280.      /// @ - ring
  281.      static tmVertex ring_nodes[] = {
  282.        { 6.00f, 3.00f},
  283.        { 5.12f, 5.12f},
  284.        { 3.00f, 6.00f},
  285.        { 0.88f, 5.12f},
  286.        { 0.00f, 3.00f},
  287.        { 0.88f, 0.88f},
  288.        { 3.00f, 0.00f},
  289.        { 5.12f, 0.88f},
  290.        { 4.50f, 3.00f},
  291.        { 4.06f, 4.06f},
  292.        { 3.00f, 4.50f},
  293.        { 1.94f, 4.06f},
  294.        { 1.50f, 3.00f},
  295.        { 1.94f, 1.94f},
  296.        { 3.00f, 1.50f},
  297.        { 4.06f, 1.94f}
  298.      };
  299.      static tmSegmentId ring_segments[] = {
  300.        { 9, 10 },
  301.        { 10, 11 },
  302.        { 11, 12 },
  303.        { 12, 13 },
  304.        { 13, 14 },
  305.        { 14, 15 },
  306.        { 15, 16 },
  307.        { 16, 9 }
  308.      };
  309.      static tmVertex ring_holes[] = {
  310.        { 3.00f, 3.00f}
  311.      };    
  312.  /// 'B'
  313.      static tmVertex B_nodes[] = {
  314.        { 0.00f, 0.00f},
  315.        { 4.00f, 0.00f},
  316.        { 5.00f, 2.00f},
  317.        { 5.00f, 4.00f},
  318.        { 4.00f, 5.00f},
  319.        { 5.00f, 6.00f},
  320.        { 5.00f, 8.00f},
  321.        { 4.00f, 9.00f},
  322.        { 0.00f, 9.00f},
  323.        { 0.00f, 5.00f},
  324.        { 1.50f, 1.50f},
  325.        { 3.50f, 1.50f},
  326.        { 3.50f, 4.00f},
  327.        { 1.50f, 4.00f},
  328.        { 1.50f, 6.00f},
  329.        { 3.50f, 6.00f},
  330.        { 3.50f, 8.50f},
  331.        { 1.50f, 8.50f}
  332.      };
  333.      static tmSegmentId B_segments[] = {
  334.        { 1, 2 },
  335.        { 2, 3 },
  336.        { 3, 4 },
  337.        { 4, 5 },
  338.        { 5, 6 },
  339.        { 6, 7 },
  340.        { 7, 8 },
  341.        { 8, 9 },
  342.        { 9, 10 },
  343.        { 10, 1 },
  344.        { 11, 12 },
  345.        { 12, 13 },
  346.        { 13, 14 },
  347.        { 14, 11 },
  348.        { 15, 16 },
  349.        { 16, 17 },
  350.        { 17, 18 },
  351.        { 18, 15 }
  352.      };
  353.      static tmVertex B_holes[] = {
  354.        { 5.00f, 5.00f},
  355.        { 2.50f, 2.50f},
  356.        { 2.50f, 7.00f}
  357.      };    
  358.  /// 'D'
  359.      static tmVertex D_nodes[] = {
  360.        { 0.00f, 0.00f},
  361.        { 4.00f, 0.00f},
  362.        { 5.00f, 2.50f},
  363.        { 5.00f, 7.00f},
  364.        { 4.00f, 9.00f},
  365.        { 0.00f, 9.00f},
  366.        { 0.00f, 5.00f},
  367.        { 1.50f, 2.50f},
  368.        { 3.50f, 2.50f},
  369.        { 3.50f, 7.00f},
  370.        { 1.50f, 7.00f},
  371.      };
  372.      static tmSegmentId D_segments[] = {
  373.        { 1, 2 },
  374.        { 2, 3 },
  375.        { 3, 4 },
  376.        { 4, 5 },
  377.        { 5, 6 },
  378.        { 6, 7 },
  379.        { 7, 1 },
  380.        { 8, 9 },
  381.        { 9, 10 },
  382.        { 10, 11 },
  383.        { 11, 8 },
  384.      };
  385.      static tmVertex D_holes[] = {
  386.       { 2.50f, 5.00f},
  387.      };
  388.      /// 'x' 
  389.      static tmVertex x_nodes[] = {
  390.       { 0.00f, 0.00f},
  391.        { 1.00f, 0.00f},
  392.        { 5.00f, 0.00f},
  393.        { 6.00f, 0.00f},
  394.        { 6.00f, 1.00f},
  395.        { 6.00f, 5.00f},
  396.        { 6.00f, 6.00f},
  397.        { 1.00f, 6.00f},
  398.        { 5.00f, 6.00f},
  399.        { 0.00f, 6.00f},
  400.        { 0.00f, 5.00f},
  401.        { 0.00f, 1.00f},
  402.        { 3.00f, 2.00f},
  403.        { 4.00f, 3.00f},
  404.        { 3.00f, 4.00f},
  405.        { 2.00f, 3.00f}
  406.      };
  407.      static tmSegmentId x_segments[] = {
  408.       { 2, 13 },
  409.        { 3, 13 },
  410.        { 5, 14 },
  411.        { 6, 14 },
  412.        { 8, 15 },
  413.        { 9, 15 },
  414.        { 11, 16 },
  415.        { 12, 16 }
  416.      };
  417.      static tmVertex x_holes[] = {
  418.        { 3.00f, 1.00f},
  419.        { 5.00f, 3.00f},
  420.        { 3.00f, 5.00f},
  421.        { 1.00f, 3.00f},
  422.      };
  423.  /// '2'
  424.      static tmVertex two_nodes[] = {
  425.        { 0.00f, 0.00f},
  426.        { 6.00f, 0.00f},
  427.        { 6.00f, 1.00f},
  428.        { 2.00f, 1.00f},
  429.        { 2.00f, 2.00f},
  430.        { 6.00f, 6.00f},
  431.        { 6.00f, 8.00f},
  432.        { 5.00f, 9.00f},
  433.        { 2.00f, 9.00f},
  434.        { 1.00f, 7.50f},
  435.        { 0.00f, 2.50f},
  436.        { 5.00f, 6.50f},
  437.        { 5.00f, 8.00f},
  438.        { 2.50f, 8.00f},
  439.        { 2.00f, 7.50f},
  440.      };
  441.      static tmSegmentId two_segments[] = {
  442.        { 1, 2 },
  443.        { 2, 3 },
  444.        { 3, 4 },
  445.        { 4, 5 },
  446.        { 5, 6 },
  447.        { 6, 7 },
  448.        { 7, 8 },
  449.        { 8, 9 },
  450.        { 9, 10 },
  451.        { 10, 15 },
  452.        { 11, 12 },
  453.        { 12, 13 },
  454.        { 13, 14 },
  455.        { 14, 15 },
  456.      };
  457.      static tmVertex two_holes[] = {
  458.        { 3.00f, 5.00f},
  459.        { 4.00f, 3.00f},
  460.      };
  461.      /// '-' beam
  462.      static tmVertex beam_nodes[] = {
  463.        { 0.00f, 0.00f},
  464.        { 32.00f, 0.00f},
  465.        { 32.00f, 3.00f},
  466.        { 0.00f, 3.00f},
  467.      }; 
  468.      static tmSegmentId *beam_segments  = NULL;
  469.      static tmVertex    *beam_holes  = NULL;
  470.      /// 'b' a box
  471.      static tmVertex b_nodes[] = {
  472.        { 0.00f, 0.00f},
  473.        { 10.00f, 0.00f},
  474.        { 10.00f, 10.00f},
  475.        { 0.00f, 10.00f},
  476.        { 2.00f, 2.00f},
  477.        { 8.00f, 2.00f},
  478.        { 8.00f, 8.00f},
  479.        { 2.00f, 8.00f},
  480.      };
  481.      static tmSegmentId b_segments[] = {
  482.        { 5, 6 },
  483.        { 6, 7 },
  484.        { 7, 8 },
  485.        { 8, 5 },
  486.      };
  487.      static tmVertex b_holes[] = {
  488.        { 5.0f, 5.0f},
  489.      };     
  490.      /// choose...
  491.      switch( which )
  492.      {      
  493.             case 'B':
  494.                 nodes      = B_nodes;
  495.                 segments   = B_segments;
  496.                 holes      = B_holes;
  497.                 
  498.                 n_nodes    = sizeof(B_nodes)/sizeof(tmVertex);
  499.                 n_segments = (segments) ? sizeof(B_segments)/sizeof(tmSegmentId) : 0;
  500.                 n_holes    = (holes) ? sizeof(B_holes)/sizeof(tmVertex) : 0;            
  501.             break;
  502.             case 'D':
  503.                 nodes      = D_nodes;
  504.                 segments   = D_segments;
  505.                 holes      = D_holes;
  506.                 
  507.                 n_nodes    = sizeof(D_nodes)/sizeof(tmVertex);
  508.                 n_segments = (segments) ? sizeof(D_segments)/sizeof(tmSegmentId) : 0;
  509.                 n_holes    = (holes) ? sizeof(D_holes)/sizeof(tmVertex) : 0;            
  510.             break;
  511.             case 'x':
  512.                 nodes      = x_nodes;
  513.                 segments   = x_segments;
  514.                 holes      = x_holes;
  515.                 
  516.                 n_nodes    = sizeof(x_nodes)/sizeof(tmVertex);
  517.                 n_segments = (segments) ? sizeof(x_segments)/sizeof(tmSegmentId) : 0;
  518.                 n_holes    = (holes) ? sizeof(x_holes)/sizeof(tmVertex) : 0;            
  519.             break;
  520.             case '@':
  521.                 nodes      = ring_nodes;
  522.                 segments   = ring_segments;
  523.                 holes      = ring_holes ;
  524.                 
  525.                 n_nodes    = sizeof(ring_nodes)/sizeof(tmVertex);
  526.                 n_segments = (segments) ? sizeof(ring_segments)/sizeof(tmSegmentId) : 0;
  527.                 n_holes    = (holes) ? sizeof(ring_holes)/sizeof(tmVertex) : 0;
  528.             break;              
  529.             case '2':
  530.                 nodes      = two_nodes;
  531.                 segments   = two_segments;
  532.                 holes      = two_holes ;
  533.                 
  534.                 n_nodes    = sizeof(two_nodes)/sizeof(tmVertex);
  535.                 n_segments = (segments) ? sizeof(two_segments)/sizeof(tmSegmentId) : 0;
  536.                 n_holes    = (holes) ? sizeof(two_holes)/sizeof(tmVertex) : 0;
  537.             break;                  
  538.             case '-':
  539.                 nodes      = beam_nodes;
  540.                 segments   = beam_segments;
  541.                 holes      = beam_holes ;
  542.                 
  543.                 n_nodes    = sizeof(beam_nodes)/sizeof(tmVertex);
  544.                 n_segments = (segments) ? sizeof(beam_segments)/sizeof(tmSegmentId) : 0;
  545.                 n_holes    = (holes) ? sizeof(beam_holes)/sizeof(tmVertex) : 0;
  546.             break;                  
  547.             case 'b':
  548.                 nodes      = b_nodes;
  549.                 segments   = b_segments;
  550.                 holes      = b_holes;
  551.                 
  552.                 n_nodes    = sizeof(b_nodes)/sizeof(tmVertex);
  553.                 n_segments = (segments) ? sizeof(b_segments)/sizeof(tmSegmentId) : 0;
  554.                 n_holes    = (holes) ? sizeof(b_holes)/sizeof(tmVertex) : 0;            
  555.             break;
  556.      }
  557.     }
  558.     ///
  559.     bool        m_drawMode, m_staticBodies;
  560.     tmVertex    m_drawVertices[N_MAXVERTEX];
  561.     int32       m_drawCount;
  562.     /// 
  563.     float32     maxAllowableForce;
  564.     /// temporary vars to hold the examples
  565.     tmVertex    *nodes;
  566.     int32        n_nodes;
  567.     tmVertex    *holes;
  568.     int32        n_holes;
  569.     tmSegmentId *segments;
  570.     int32        n_segments;
  571. };
  572. #undef H
  573. #endif