void Physics::createSolidWall(b2Vec2 position, float rotation, b2Vec2 size, bool isWorkspace=false) { Body wall; wall.setType(WALL); b2BodyDef wallDef; //static body by default wallDef.position.Set(position.x,position.y); wallDef.angle = rotation; b2Body* wallBody = world->CreateBody(&wallDef); b2PolygonShape wallShape; wallShape.SetAsBox(size.x,size.y); b2FixtureDef wallFixtureDef; wallFixtureDef.shape = &wallShape; wallBody->CreateFixture(&wallFixtureDef); wall.addNode(wallBody); wall.finish(); wall.setName("Wall"); wall.setWallPosition(rotation*180/pi); if(isWorkspace) { workspaceWalls.append(wall); }else { bodyList.append(wall); emit objectListUpdated(bodyList); } }
void Physics::createBall(b2Vec2 position,float radius, float stiffness, float damping, float density, float maxSpacing) { Body ball; ball.setType(BALL); float nodeRadius = maxSpacing*.45; ball.setNodeRadius(nodeRadius); float mass(density*radius*radius); int nodeCount = (2*pi*radius/maxSpacing); //not including center float nodeDensity(mass/(nodeRadius*nodeRadius*(nodeCount+1))); b2BodyDef ballNodeDef; ballNodeDef.linearDamping = 1; ballNodeDef.angularDamping = 1; b2CircleShape ballNodeShape; ballNodeShape.m_radius = nodeRadius; b2FixtureDef ballFixtureDef; ballFixtureDef.shape = &ballNodeShape; ballFixtureDef.density = nodeDensity; ballNodeDef.type = b2_dynamicBody; b2DistanceJointDef nodeLinkDef; b2MotorJointDef nodeLinkMotorDef; // Smaller stiffness in the link from the center to the edge // So that the effector can deform the ball without penetrating it nodeLinkDef.frequencyHz = sqrt((stiffness)*FORCE_FACTOR/mass); nodeLinkDef.dampingRatio = damping; nodeLinkMotorDef.correctionFactor = stiffness; nodeLinkMotorDef.maxForce = stiffness*radius; nodeLinkMotorDef.maxTorque = 0; //center ballNodeDef.position.Set(position.x,position.y); b2Body* ballCenter = world->CreateBody(&ballNodeDef); ballCenter->CreateFixture(&ballFixtureDef); ball.addNode(ballCenter); //circle b2Vec2 nodePosition; //b2Body* firstNode =ballCenter,lastNode = ballCenter; for(int i(0);i<nodeCount;i++) { ballNodeDef.type = b2_dynamicBody; nodePosition = position + radius*b2Vec2(cos(2*pi*i/nodeCount), sin(2*pi*i/nodeCount)); ballNodeDef.position.Set(nodePosition.x,nodePosition.y); b2Body* ballNode = world->CreateBody(&ballNodeDef); ballNode->CreateFixture(&ballFixtureDef); nodeLinkDef.Initialize(ballCenter,ballNode, ballCenter->GetWorldCenter(), ballNode->GetWorldCenter()); world->CreateJoint(&nodeLinkDef); nodeLinkMotorDef.Initialize(ballCenter,ballNode); world->CreateJoint(&nodeLinkMotorDef); if(i>0) { nodeLinkDef.Initialize(ballNode,ball.getNode(i-1), ballNode->GetWorldCenter(), ball.getNode(i-1)->GetWorldCenter()); world->CreateJoint(&nodeLinkDef); nodeLinkMotorDef.Initialize(ballNode,ball.getNode(i-1)); world->CreateJoint(&nodeLinkMotorDef); } ball.addNode(ballNode); } nodeLinkDef.Initialize(ball.getNode(nodeCount-1),ball.getNode(1), ball.getNode(nodeCount-1)->GetWorldCenter(), ball.getNode(1)->GetWorldCenter()); world->CreateJoint(&nodeLinkDef); nodeLinkMotorDef.Initialize(ball.getNode(nodeCount-1),ball.getNode(1)); world->CreateJoint(&nodeLinkMotorDef); ball.finish(); ball.setName("Ball"); ball.setTransform(physics2graphics); bodyList.append(ball); emit objectListUpdated(bodyList); }