void Bird::Contact(b2Vec2 impulse, GameItem *gameItem) { if(impulse.Length()>0) { remove=1; travel=false; isOut = 2; setScore(impulse.Length()); } else { isContact = false; } }
bool Neural_SB::accumForce(b2Vec2 & totForce, b2Vec2 force) const { //std::cout << "\t\tTotalForce : " << totForce.x << " " << totForce.y << std::endl; b2Vec2 tot = totForce + force; if( tot.LengthSquared() <= m_fMaxForce*m_fMaxForce ) { totForce += force; return true; } force.Normalize(); force *= abs(m_fMaxForce - totForce.Length()); totForce += force; return false; }
void LiquidFunScene::ccTouchEnded(cocos2d::CCTouch* touch, cocos2d::CCEvent* event){ if (m_startSprite != NULL) { const CCPoint& startSpritePosition = m_startSprite->getPosition(); const CCPoint& endSpritePosition = m_endSprite->getPosition(); // Calculate the start / end and length of the vector between them in // world coordinates. const b2Vec2 startPosition = ConvertScreenPositionToWorld( b2Vec2(startSpritePosition.x, startSpritePosition.y)); const b2Vec2 endPosition = ConvertScreenPositionToWorld( b2Vec2(endSpritePosition.x, endSpritePosition.y)); const b2Vec2 startEndVector = endPosition - startPosition; const float32 startEndLength = startEndVector.Length(); // Calculate the middle point along the vector between startPosition and // endPosition. b2Vec2 midPoint; midPoint = startEndVector; midPoint *= 0.5f; midPoint += startPosition; b2PolygonShape box; box.SetAsBox(startEndLength * 0.5f, k_drawableBoxThickness * m_worldExtentMin); b2BodyDef bodyDef; bodyDef.type = b2_staticBody; bodyDef.position = midPoint; bodyDef.angle = atan2(startEndVector.y, startEndVector.x); b2Body* body = m_world->CreateBody(&bodyDef); body->CreateFixture(&box, 0); removeChild(m_startSprite); removeChild(m_endSprite); // These will be cleaned up by the autorelease system since they were // allocated by init() m_startSprite = NULL; m_endSprite = NULL; } }
void Flamethrower::onFire(b2Vec2 direction, bool constantFire, bool isPlayer) { direction.Normalize(); b2Mat22 matrix1 = b2Mat22(degree2radian(float(rand() % 600) / 100.0f)); b2Mat22 matrix2 = b2Mat22(degree2radian(float(rand() % 600) / 100.0f)); b2Mat22 matrix3 = b2Mat22(degree2radian(float(rand() % 600 - 300) / 100.0f)); direction = b2Mul(matrix1, direction); b2Vec2 direction2 = b2Mul(matrix2, direction); b2Vec2 direction3 = b2Mul(matrix3, direction); EntityFactory *entityFactory = new FlamethrowerBulletFactory(); EntityProperties& properties = entityFactory->getDefaultProperties(); properties.x = meter2pixel(this->getBody(0)->GetPosition().x); properties.y = meter2pixel(this->getBody(0)->GetPosition().y); properties.special = true; float speed = 0.7f; FlamethrowerBullet *flamethrowerBullet = (FlamethrowerBullet*)entityFactory->create(properties); flamethrowerBullet->getBody(0)->ApplyForce(speed * 0.75f * direction, this->getBody(0)->GetPosition()); flamethrowerBullet = (FlamethrowerBullet*)entityFactory->create(properties); flamethrowerBullet->getBody(0)->ApplyForce(speed * 0.75f * direction2, this->getBody(0)->GetPosition()); flamethrowerBullet = (FlamethrowerBullet*)entityFactory->create(properties); flamethrowerBullet->getBody(0)->ApplyForce(speed * 0.82f * direction3, this->getBody(0)->GetPosition()); }
// Compute allowable normal ranges based on adjacency. // A normal n is allowable iff: // cross(n, n1) >= 0.0f && cross(n2, n) >= 0.0f // n points from A to B (edge to polygon) void b2EPCollider::ComputeAdjacency() { b2Vec2 v0 = m_edgeA.v0; b2Vec2 v1 = m_edgeA.v1; b2Vec2 v2 = m_edgeA.v2; b2Vec2 v3 = m_edgeA.v3; // Determine allowable the normal regions based on adjacency. // Note: it may be possible that no normal is admissable. b2Vec2 centerB = m_proxyB.centroid; if (m_edgeA.hasVertex0) { b2Vec2 e0 = v1 - v0; b2Vec2 e1 = v2 - v1; b2Vec2 n0(e0.y, -e0.x); b2Vec2 n1(e1.y, -e1.x); n0.Normalize(); n1.Normalize(); bool convex = b2Cross(n0, n1) >= 0.0f; bool front0 = b2Dot(n0, centerB - v0) >= 0.0f; bool front1 = b2Dot(n1, centerB - v1) >= 0.0f; if (convex) { if (front0 || front1) { m_limit11 = n1; m_limit12 = n0; } else { m_limit11 = -n1; m_limit12 = -n0; } } else { if (front0 && front1) { m_limit11 = n0; m_limit12 = n1; } else { m_limit11 = -n0; m_limit12 = -n1; } } } else { m_limit11.SetZero(); m_limit12.SetZero(); } if (m_edgeA.hasVertex3) { b2Vec2 e1 = v2 - v1; b2Vec2 e2 = v3 - v2; b2Vec2 n1(e1.y, -e1.x); b2Vec2 n2(e2.y, -e2.x); n1.Normalize(); n2.Normalize(); bool convex = b2Cross(n1, n2) >= 0.0f; bool front1 = b2Dot(n1, centerB - v1) >= 0.0f; bool front2 = b2Dot(n2, centerB - v2) >= 0.0f; if (convex) { if (front1 || front2) { m_limit21 = n2; m_limit22 = n1; } else { m_limit21 = -n2; m_limit22 = -n1; } } else { if (front1 && front2) { m_limit21 = n1; m_limit22 = n2; } else { m_limit21 = -n1; m_limit22 = -n2; } } } else { m_limit21.SetZero(); m_limit22.SetZero(); } }
bool GameLevelState::update(yam2d::ESContext* _context, float _deltaTime) { compFac->getPhysicsWorld()->Step(_deltaTime, 10, 10); map->update(_deltaTime); static bool ballHit = false; static bool ballHitThisFrame; static b2Vec2 directionVec;//Vector from player to ball when hit ballHitThisFrame = false; //Collisions unsigned int numContacts = contactListener->contacts.size(); for (unsigned int i = 0; i < numContacts; i++) { const Contact& contact = contactListener->contacts[i]; yam2d::GameObject* A = ((PhysicsBody*) contact.fixtureA->GetBody()->GetUserData())->getGameObject(); yam2d::GameObject* B = ((PhysicsBody*) contact.fixtureB->GetBody()->GetUserData())->getGameObject(); if ((A->getName() == "Ball" && B->getName() == "Player")) { //Physics if (!ballHit) { //Reverse last movements ( separate objects ) A->getComponent<PhysicsBody>()->getBody()->SetTransform(b2Vec2(A->getComponent<PhysicsBody>()->getBody()->GetPosition().x - ballVelocity.x, A->getComponent<PhysicsBody>()->getBody()->GetPosition().y - ballVelocity.y), A->getComponent<PhysicsBody>()->getBody()->GetAngle()); B->getComponent<PhysicsBody>()->getBody()->SetTransform(b2Vec2(B->getComponent<PhysicsBody>()->getBody()->GetPosition().x - playerSpeed.x, B->getComponent<PhysicsBody>()->getBody()->GetPosition().y - playerSpeed.y), B->getComponent<PhysicsBody>()->getBody()->GetAngle()); //Direction directionVec = A->getComponent<PhysicsBody>()->getBody()->GetPosition() - B->getComponent<PhysicsBody>()->getBody()->GetPosition(); directionVec.Normalize(); directionVec *= 0.1f; //Check for side hits if (A->getComponent<PhysicsBody>()->getBody()->GetPosition().x + A->getSizeInTiles().x * 0.5f < B->getComponent<PhysicsBody>()->getBody()->GetPosition().x - B->getSizeInTiles().x * 0.5f || A->getComponent<PhysicsBody>()->getBody()->GetPosition().x - A->getSizeInTiles().x * 0.5f > B->getComponent<PhysicsBody>()->getBody()->GetPosition().x + B->getSizeInTiles().x * 0.5f) { ballVelocity.x = -ballVelocity.x + playerSpeed.x; ballVelocity.y -= directionVec.y; } else //No side hit { ballVelocity.y = -ballVelocity.y; } ballVelocity.x -= (playerObject->getComponent<PhysicsBody>()->getBody()->GetPosition().x - ballObject->getComponent<PhysicsBody>()->getBody()->GetPosition().x) / 22.0f; ballHit = true; ballHitThisFrame = true; } } else if ((B->getName() == "Ball" && A->getName() == "Player")) { //Physics if (!ballHit) { //Reverse last movements ( separate objects ) B->getComponent<PhysicsBody>()->getBody()->SetTransform(b2Vec2(B->getComponent<PhysicsBody>()->getBody()->GetPosition().x - ballVelocity.x, B->getComponent<PhysicsBody>()->getBody()->GetPosition().y - ballVelocity.y), B->getComponent<PhysicsBody>()->getBody()->GetAngle()); A->getComponent<PhysicsBody>()->getBody()->SetTransform(b2Vec2(A->getComponent<PhysicsBody>()->getBody()->GetPosition().x - playerSpeed.x, A->getComponent<PhysicsBody>()->getBody()->GetPosition().y - playerSpeed.y), A->getComponent<PhysicsBody>()->getBody()->GetAngle()); //Direction directionVec = B->getComponent<PhysicsBody>()->getBody()->GetPosition() - A->getComponent<PhysicsBody>()->getBody()->GetPosition(); directionVec.Normalize(); directionVec *= 0.1f; //Check for side hits if (B->getComponent<PhysicsBody>()->getBody()->GetPosition().x + B->getSizeInTiles().x * 0.5f < A->getComponent<PhysicsBody>()->getBody()->GetPosition().x - A->getSizeInTiles().x * 0.5f || B->getComponent<PhysicsBody>()->getBody()->GetPosition().x - B->getSizeInTiles().x * 0.5f > A->getComponent<PhysicsBody>()->getBody()->GetPosition().x + A->getSizeInTiles().x * 0.5f) { ballVelocity.x = -ballVelocity.x + playerSpeed.x; ballVelocity.y -= directionVec.y; } else //No side hit { ballVelocity.y = -ballVelocity.y; } ballVelocity.x -= (playerObject->getComponent<PhysicsBody>()->getBody()->GetPosition().x - ballObject->getComponent<PhysicsBody>()->getBody()->GetPosition().x) / 22.0f; ballHit = true; ballHitThisFrame = true; } } if ((A->getName() == "Ball" && B->getName() == "Tile")) { //Physics if (!ballHit) { //Check for side hits if (A->getComponent<PhysicsBody>()->getBody()->GetPosition().x + A->getSizeInTiles().x * 0.5f < B->getComponent<PhysicsBody>()->getBody()->GetPosition().x - B->getSizeInTiles().x * 0.5 || A->getComponent<PhysicsBody>()->getBody()->GetPosition().x - A->getSizeInTiles().x * 0.5f > B->getComponent<PhysicsBody>()->getBody()->GetPosition().x + B->getSizeInTiles().x * 0.5) { ballVelocity.x = -ballVelocity.x; } else { ballVelocity.y = -ballVelocity.y; } ballHit = true; ballHitThisFrame = true; } //Tile actions map->deleteGameObject(B); tileAmount--; } else if ((B->getName() == "Ball" && A->getName() == "Tile")) { //Physics if (!ballHit) { //Check for side hits if (B->getComponent<PhysicsBody>()->getBody()->GetPosition().x + B->getSizeInTiles().x * 0.5f < A->getComponent<PhysicsBody>()->getBody()->GetPosition().x - A->getSizeInTiles().x * 0.5 || B->getComponent<PhysicsBody>()->getBody()->GetPosition().x - B->getSizeInTiles().x * 0.5f > A->getComponent<PhysicsBody>()->getBody()->GetPosition().x + A->getSizeInTiles().x * 0.5) { ballVelocity.x = -ballVelocity.x; } else { ballVelocity.y = -ballVelocity.y; } ballHit = true; ballHitThisFrame = true; } //Tile actionss map->deleteGameObject(A); tileAmount--; } } if (!ballHitThisFrame) { ballHit = false; } //Restrict ball if (ballObject->getComponent<PhysicsBody>()->getBody()->GetPosition().x + ballObject->getSizeInTiles().x * 0.5f > tileSize.x || ballObject->getComponent<PhysicsBody>()->getBody()->GetPosition().x - ballObject->getSizeInTiles().x * 0.5f < 0.0f) { ballVelocity.x = -ballVelocity.x; } if (ballObject->getComponent<PhysicsBody>()->getBody()->GetPosition().y - ballObject->getSizeInTiles().x * 0.5f < 0.0f) { ballVelocity.y = -ballVelocity.y; } //Win-Lose if (tileAmount == 0) { //Win textObject->getComponent<yam2d::TextComponent>()->getText()->setText("YOU WIN!"); textObject->setPosition(tileSize.x * 0.5f, tileSize.y * 0.5f); endTimer -= _deltaTime; } else if (ballObject->getComponent<PhysicsBody>()->getBody()->GetPosition().y > tileSize.y) { //Lose textObject->getComponent<yam2d::TextComponent>()->getText()->setText("YOU LOSE!"); textObject->setPosition(tileSize.x * 0.5f, tileSize.y * 0.5f); endTimer -= _deltaTime; } if (endTimer <= 0.0f) { stateManager->setState(new MainMenuState(stateManager)); return true; } //Input if (yam2d::getKeyState(yam2d::KEY_BACK) || yam2d::getKeyState(yam2d::KEY_ESCAPE)) { stateManager->setState(new MainMenuState(stateManager)); return true; } playerSpeed = yam2d::vec2(0.0f); if (!ballHit) { if (yam2d::getKeyState(yam2d::KEY_D)) { playerSpeed = yam2d::vec2(0.1f, 0.0f); } if (yam2d::getKeyState(yam2d::KEY_A)) { playerSpeed = yam2d::vec2(-0.1f, 0.0f); } } playerObject->getComponent<PhysicsBody>()->getBody()->SetTransform(playerObject->getPosition() + playerSpeed, 0.0f); //Restrict if (playerObject->getComponent<PhysicsBody>()->getBody()->GetPosition().x + playerObject->getSizeInTiles().x * 0.5f > tileSize.x) { playerObject->getComponent<PhysicsBody>()->getBody()->SetTransform(playerObject->getPosition() - b2Vec2(0.1f, 0.0f), 0.0f); } else if (playerObject->getComponent<PhysicsBody>()->getBody()->GetPosition().x - playerObject->getSizeInTiles().x * 0.5f < 0.0f) { playerObject->getComponent<PhysicsBody>()->getBody()->SetTransform(playerObject->getPosition() + b2Vec2(0.1f, 0.0f), 0.0f); } // ballObject->getComponent<PhysicsBody>()->getBody()->SetTransform(ballObject->getPosition() + (ballVelocity), 0.0f); if (endTimer >= 3.0f) { textObject->getComponent<yam2d::TextComponent>()->getText()->setText("Tiles Left: " + std::to_string(tileAmount)); } return true; }
float RadiansOf(b2Vec2 vec) { static b2Vec2 vertical(0, -1); float dot = (vertical.x * vec.x) + (vertical.y * vec.y); float angle_r = acos(dot / (vertical.Length() * vec.Length())); return angle_r; }
//Chase firing bool Enemy::chaseFire(b2Vec2 & rFireV) { bool trigger = false; //Did we fire? if (fired_) { angry_ = fmaxf(angry_ - triggerSatisfaction_[brainStem_.weapon_training], 0); fired_ = false; } //Fire at player? if (play_) { b2Vec2 myPos = getPosition(); b2Vec2 pPos = player_->getPosition(); b2Vec2 between = (pPos - myPos); float dist = between.Length(); //Fire if in visible range and if (dist < visRange_[brainStem_.sensitivity] && chill_ > freezingPoint_) { rFireV = LJP(pPos, 100, 0, 2.0, 0); //*//Fire LJP const? } } //DECIDE TO FIRE float seePlayer = rFireV.Length(); float ammo = (float)getWeaponBar() / (float)getWeaponBarMAX(); //Otherwise, heat up, chill first if (seePlayer != 0) { orient(rFireV); if (chill_ != 0) chill_ = fminf(chill_ += seePlayer * 4 * moodMult_[brainStem_.aggression], 0); else angry_ = fminf(angry_ + seePlayer * moodMult_[brainStem_.aggression], angryMAX_); } //If we're mad enough and we can see the player, fire if (angry_ > boilingPoint_ && seePlayer != 0) { trigger = true; } //Reload if we're cool enough if (angry_ - boilingPoint_ > (angryMAX_ - boilingPoint_) * accuracy_[brainStem_.weapon_training] * moodMult_[brainStem_.aggression]) //*//weapon training, aggression { if (ammo < accuracy_[brainStem_.weapon_training]) //*// weapon training causes later reloads reup(); } //Chill out when idle if (angry_ == 0 && seePlayer == 0) { chill_ -= 1 * moodMult_[brainStem_.inner_peace]; if (chill_ <= freezingPoint_) { if (ammo < 1.f) reup(); spin(-0.05f); } } chill_ = fmax(chill_, chillMIN_); return trigger; }
// Algorithm: // 1. Classify v1 and v2 // 2. Classify polygon centroid as front or back // 3. Flip normal if necessary // 4. Initialize normal range to [-pi, pi] about face normal // 5. Adjust normal range according to adjacent edges // 6. Visit each separating axes, only accept axes within the range // 7. Return if _any_ axis indicates separation // 8. Clip void b2EPCollider::Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA, const b2PolygonShape* polygonB, const b2Transform& xfB) { m_xf = b2MulT(xfA, xfB); m_centroidB = b2Mul(m_xf, polygonB->m_centroid); m_v0 = edgeA->m_vertex0; m_v1 = edgeA->m_vertex1; m_v2 = edgeA->m_vertex2; m_v3 = edgeA->m_vertex3; bool hasVertex0 = edgeA->m_hasVertex0; bool hasVertex3 = edgeA->m_hasVertex3; b2Vec2 edge1 = m_v2 - m_v1; edge1.Normalize(); m_normal1.Set(edge1.y, -edge1.x); float32 offset1 = b2Dot(m_normal1, m_centroidB - m_v1); float32 offset0 = 0.0f, offset2 = 0.0f; bool convex1 = false, convex2 = false; // Is there a preceding edge? if (hasVertex0) { b2Vec2 edge0 = m_v1 - m_v0; edge0.Normalize(); m_normal0.Set(edge0.y, -edge0.x); convex1 = b2Cross(edge0, edge1) >= 0.0f; offset0 = b2Dot(m_normal0, m_centroidB - m_v0); } // Is there a following edge? if (hasVertex3) { b2Vec2 edge2 = m_v3 - m_v2; edge2.Normalize(); m_normal2.Set(edge2.y, -edge2.x); convex2 = b2Cross(edge1, edge2) > 0.0f; offset2 = b2Dot(m_normal2, m_centroidB - m_v2); } // Determine front or back collision. Determine collision normal limits. if (hasVertex0 && hasVertex3) { if (convex1 && convex2) { m_front = offset0 >= 0.0f || offset1 >= 0.0f || offset2 >= 0.0f; if (m_front) { m_normal = m_normal1; m_lowerLimit = m_normal0; m_upperLimit = m_normal2; } else { m_normal = -m_normal1; m_lowerLimit = -m_normal1; m_upperLimit = -m_normal1; } } else if (convex1) { m_front = offset0 >= 0.0f || (offset1 >= 0.0f && offset2 >= 0.0f); if (m_front) { m_normal = m_normal1; m_lowerLimit = m_normal0; m_upperLimit = m_normal1; } else { m_normal = -m_normal1; m_lowerLimit = -m_normal2; m_upperLimit = -m_normal1; } } else if (convex2) { m_front = offset2 >= 0.0f || (offset0 >= 0.0f && offset1 >= 0.0f); if (m_front) { m_normal = m_normal1; m_lowerLimit = m_normal1; m_upperLimit = m_normal2; } else { m_normal = -m_normal1; m_lowerLimit = -m_normal1; m_upperLimit = -m_normal0; } } else { m_front = offset0 >= 0.0f && offset1 >= 0.0f && offset2 >= 0.0f; if (m_front) { m_normal = m_normal1; m_lowerLimit = m_normal1; m_upperLimit = m_normal1; } else { m_normal = -m_normal1; m_lowerLimit = -m_normal2; m_upperLimit = -m_normal0; } } } else if (hasVertex0) { if (convex1) { m_front = offset0 >= 0.0f || offset1 >= 0.0f; if (m_front) { m_normal = m_normal1; m_lowerLimit = m_normal0; m_upperLimit = -m_normal1; } else { m_normal = -m_normal1; m_lowerLimit = m_normal1; m_upperLimit = -m_normal1; } } else { m_front = offset0 >= 0.0f && offset1 >= 0.0f; if (m_front) { m_normal = m_normal1; m_lowerLimit = m_normal1; m_upperLimit = -m_normal1; } else { m_normal = -m_normal1; m_lowerLimit = m_normal1; m_upperLimit = -m_normal0; } } } else if (hasVertex3) { if (convex2) { m_front = offset1 >= 0.0f || offset2 >= 0.0f; if (m_front) { m_normal = m_normal1; m_lowerLimit = -m_normal1; m_upperLimit = m_normal2; } else { m_normal = -m_normal1; m_lowerLimit = -m_normal1; m_upperLimit = m_normal1; } } else { m_front = offset1 >= 0.0f && offset2 >= 0.0f; if (m_front) { m_normal = m_normal1; m_lowerLimit = -m_normal1; m_upperLimit = m_normal1; } else { m_normal = -m_normal1; m_lowerLimit = -m_normal2; m_upperLimit = m_normal1; } } } else { m_front = offset1 >= 0.0f; if (m_front) { m_normal = m_normal1; m_lowerLimit = -m_normal1; m_upperLimit = -m_normal1; } else { m_normal = -m_normal1; m_lowerLimit = m_normal1; m_upperLimit = m_normal1; } } // Get polygonB in frameA m_polygonB.count = polygonB->m_vertexCount; for (int32 i = 0; i < polygonB->m_vertexCount; ++i) { m_polygonB.vertices[i] = b2Mul(m_xf, polygonB->m_vertices[i]); m_polygonB.normals[i] = b2Mul(m_xf.q, polygonB->m_normals[i]); } m_radius = 2.0f * b2_polygonRadius; manifold->pointCount = 0; b2EPAxis edgeAxis = ComputeEdgeSeparation(); // If no valid normal can be found than this edge should not collide. if (edgeAxis.type == b2EPAxis::e_unknown) { return; } if (edgeAxis.separation > m_radius) { return; } b2EPAxis polygonAxis = ComputePolygonSeparation(); if (polygonAxis.type != b2EPAxis::e_unknown && polygonAxis.separation > m_radius) { return; } // Use hysteresis for jitter reduction. const float32 k_relativeTol = 0.98f; const float32 k_absoluteTol = 0.001f; b2EPAxis primaryAxis; if (polygonAxis.type == b2EPAxis::e_unknown) { primaryAxis = edgeAxis; } else if (polygonAxis.separation > k_relativeTol * edgeAxis.separation + k_absoluteTol) { primaryAxis = polygonAxis; } else { primaryAxis = edgeAxis; } b2ClipVertex ie[2]; b2ReferenceFace rf; if (primaryAxis.type == b2EPAxis::e_edgeA) { manifold->type = b2Manifold::e_faceA; // Search for the polygon normal that is most anti-parallel to the edge normal. int32 bestIndex = 0; float32 bestValue = b2Dot(m_normal, m_polygonB.normals[0]); for (int32 i = 1; i < m_polygonB.count; ++i) { float32 value = b2Dot(m_normal, m_polygonB.normals[i]); if (value < bestValue) { bestValue = value; bestIndex = i; } } int32 i1 = bestIndex; int32 i2 = i1 + 1 < m_polygonB.count ? i1 + 1 : 0; ie[0].v = m_polygonB.vertices[i1]; ie[0].id.cf.indexA = 0; ie[0].id.cf.indexB = i1; ie[0].id.cf.typeA = b2ContactFeature::e_face; ie[0].id.cf.typeB = b2ContactFeature::e_vertex; ie[1].v = m_polygonB.vertices[i2]; ie[1].id.cf.indexA = 0; ie[1].id.cf.indexB = i2; ie[1].id.cf.typeA = b2ContactFeature::e_face; ie[1].id.cf.typeB = b2ContactFeature::e_vertex; if (m_front) { rf.i1 = 0; rf.i2 = 1; rf.v1 = m_v1; rf.v2 = m_v2; rf.normal = m_normal1; } else { rf.i1 = 1; rf.i2 = 0; rf.v1 = m_v2; rf.v2 = m_v1; rf.normal = -m_normal1; } } else { manifold->type = b2Manifold::e_faceB; ie[0].v = m_v1; ie[0].id.cf.indexA = 0; ie[0].id.cf.indexB = primaryAxis.index; ie[0].id.cf.typeA = b2ContactFeature::e_vertex; ie[0].id.cf.typeB = b2ContactFeature::e_face; ie[1].v = m_v2; ie[1].id.cf.indexA = 0; ie[1].id.cf.indexB = primaryAxis.index; ie[1].id.cf.typeA = b2ContactFeature::e_vertex; ie[1].id.cf.typeB = b2ContactFeature::e_face; rf.i1 = primaryAxis.index; rf.i2 = rf.i1 + 1 < m_polygonB.count ? rf.i1 + 1 : 0; rf.v1 = m_polygonB.vertices[rf.i1]; rf.v2 = m_polygonB.vertices[rf.i2]; rf.normal = m_polygonB.normals[rf.i1]; } rf.sideNormal1.Set(rf.normal.y, -rf.normal.x); rf.sideNormal2 = -rf.sideNormal1; rf.sideOffset1 = b2Dot(rf.sideNormal1, rf.v1); rf.sideOffset2 = b2Dot(rf.sideNormal2, rf.v2); // Clip incident edge against extruded edge1 side edges. b2ClipVertex clipPoints1[2]; b2ClipVertex clipPoints2[2]; int32 np; // Clip to box side 1 np = b2ClipSegmentToLine(clipPoints1, ie, rf.sideNormal1, rf.sideOffset1, rf.i1); if (np < b2_maxManifoldPoints) { return; } // Clip to negative box side 1 np = b2ClipSegmentToLine(clipPoints2, clipPoints1, rf.sideNormal2, rf.sideOffset2, rf.i2); if (np < b2_maxManifoldPoints) { return; } // Now clipPoints2 contains the clipped points. if (primaryAxis.type == b2EPAxis::e_edgeA) { manifold->localNormal = rf.normal; manifold->localPoint = rf.v1; } else { manifold->localNormal = polygonB->m_normals[rf.i1]; manifold->localPoint = polygonB->m_vertices[rf.i1]; } int32 pointCount = 0; for (int32 i = 0; i < b2_maxManifoldPoints; ++i) { float32 separation; separation = b2Dot(rf.normal, clipPoints2[i].v - rf.v1); if (separation <= m_radius) { b2ManifoldPoint* cp = manifold->points + pointCount; if (primaryAxis.type == b2EPAxis::e_edgeA) { cp->localPoint = b2MulT(m_xf, clipPoints2[i].v); cp->id = clipPoints2[i].id; } else { cp->localPoint = clipPoints2[i].v; cp->id.cf.typeA = clipPoints2[i].id.cf.typeB; cp->id.cf.typeB = clipPoints2[i].id.cf.typeA; cp->id.cf.indexA = clipPoints2[i].id.cf.indexB; cp->id.cf.indexB = clipPoints2[i].id.cf.indexA; } ++pointCount; } } manifold->pointCount = pointCount; }
void set_length(float l) { length = l; self.Set(l * std::cos(angle), -l * std::sin(angle)); }
void Init() { GameWin.create(sf::VideoMode(800, 600, 32), "Physics Test - [SFML & Box2D]"); if (!font.loadFromFile("arial.ttf")) { exit(0); } PauseText.setFont(font); pauseText = to_string(Paused); PauseText.setCharacterSize(10); PauseText.setString("PAUSED:" + pauseText); PauseText.setPosition(sf::Vector2f(700, 10)); PauseText.setFillColor(sf::Color::Yellow); box.setPosition(sf::Vector2f(15, 5)); box.setSize(sf::Vector2f(10, 10)); box.setFillColor(sf::Color(255, 0, 0)); box2.setPosition(sf::Vector2f(50, 5)); box2.setSize(sf::Vector2f(15, 15)); box2.setFillColor(sf::Color(0, 255, 0)); ground.setPosition(sf::Vector2f(0, 540)); ground.setSize(sf::Vector2f(800, 560)); ground.setFillColor(sf::Color(0, 0,255)); wall.setPosition(sf::Vector2f(1, 1)); wall.setSize(sf::Vector2f(10, 580)); wall.setFillColor(sf::Color(0, 0, 255)); wall2.setPosition(sf::Vector2f(790, 1)); wall2.setSize(sf::Vector2f(10, 580)); wall2.setFillColor(sf::Color(0, 0, 255)); World = new b2World(gravity); World->SetGravity(gravity); groundBodyDef.type = b2_staticBody; groundBodyDef.position.Set(0, 540); groundBody = World->CreateBody(&groundBodyDef); wallBodyDef.type = b2_staticBody; wallBodyDef.position.Set(10, 580); wallBody = World->CreateBody(&wallBodyDef); wallBodyDef2.type = b2_staticBody; wallBodyDef2.position.Set(790, 1); wallBody2 = World->CreateBody(&wallBodyDef2); ballBodyDef.type = b2_dynamicBody; ballVector.Set(10, 10); ballBodyDef.angularVelocity = 0.0f; ballBodyDef.linearVelocity = ballVector; ballBodyDef2.type = b2_dynamicBody; ballVector2.Set(15, 15); ballBodyDef2.angularVelocity = 0.0f; ballBodyDef2.linearVelocity = ballVector2; ballBodyDef.position.Set(15, 0); ballBodyDef.awake = true; Body = World->CreateBody(&ballBodyDef); ballBodyDef2.position.Set(30, 0); ballBodyDef2.awake = true; Body2 = World->CreateBody(&ballBodyDef2); boxShapeDef.shape = &groundBox; boxShapeDef.density = 2.0f; boxShapeDef.restitution = 0.5f; groundBox.SetAsBox(800, 0); groundBody->CreateFixture(&groundBox, 0); wallBoxDef.shape = &wallBox; wallBoxDef.density = 2.0f; wallBoxDef.restitution = 0.5f; wallBox.SetAsBox(1, 600); wallBody->CreateFixture(&wallBox, 0); wallBoxDef2.shape = &wallBox2; wallBoxDef2.density = 2.0f; wallBoxDef2.restitution = 0.5f; wallBox2.SetAsBox(1, 600); wallBody2->CreateFixture(&wallBox2, 0); dynamicBox.SetAsBox(10.0f, 10.0f); dynamicBox2.SetAsBox(10.0f, 10.0f); fixtureDef.shape = &dynamicBox; fixtureDef.density = 2.0f; fixtureDef.friction = 1.5f; fixtureDef.restitution = 0.9f; Body->CreateFixture(&fixtureDef); fixtureDef2.shape = &dynamicBox2; fixtureDef2.density = 5.0f; fixtureDef2.friction = 5.0f; fixtureDef2.restitution = 1.0f; Body2->CreateFixture(&fixtureDef2); timeStep = 1.0f / 600.0f; velIter = 1; posIter = 1; World->Step(timeStep, velIter, posIter); b2Vec2 pos = Body->GetPosition(); float angle = Body->GetAngle(); box.setPosition(pos.x, pos.y); box.setRotation(angle); b2Vec2 pos2 = Body2->GetPosition(); float angle2 = Body2->GetAngle(); box2.setPosition(pos2.x, pos2.y); box2.setRotation(angle2); }
float sumMagnitude(sf::Vector2f& V1, b2Vec2& V2) { return sqrtf(V1.x*V1.x + V1.y*V1.y) + V2.Length(); }
float sumMagnitude(b2Vec2& V1, sf::Vector2f& V2) { return V1.Length() + sqrtf(V2.x * V2.x + V2.y * V2.y); }
float sumMagnitude(const b2Vec2& V1, const b2Vec2& V2) { return V1.Length() + V2.Length(); }