void CollisionMap::findCollidableTiles(std::vector<CollisionRect> &rects) const
{
	sf::Vector2i worldTileSize = container->getTileSize();

	// find collidable tiles
	sf::Vector2f size(Constants::tileSizef, Constants::tileSizef); // todo: assuming all tiles are the same size
	for (auto y = 0; y < worldTileSize.y; ++y)
	{
		for (auto x = 0; x < worldTileSize.x; ++x)
		{
			BlockType bt = container->getBlockAt({x, y}, LAYER_TERRAIN); // the only collidable tile layer
			bool collide = isCollidable(bt);
			bool interact = isInteractable(bt);

			if (!collide && !interact)
				continue;

			sf::Vector2f pos(Utils::toPixel(sf::Vector2f(x, y)));
			rects.emplace_back(sf::FloatRect(pos, size), 0.f, bt);
		}
	}

	// objects
	auto objects = container->getTerrain().getObjects();
	for (auto &obj : objects)
	{
		auto pos = obj.tilePos;
		pos.y -= 1 / Constants::scale;
		pos = Math::multiply(pos, Constants::tileScale);

		rects.emplace_back(sf::FloatRect(pos, size), obj.rotation, obj.type);
	}
}
Example #2
0
bool Entity::collidesWith(Entity *other)
{
    if (other == this || !isCollidable() || !other->isCollidable())
    {
        return false;
    }

    int ax1 = mX, ay1 = mY,
		ax2 = mX + mW, ay2 = mY + mH;
	int bx1 = other->mX, by1 = other->mY,
		bx2 = other->mX + other->mW, by2 = other->mY + other->mH;

	return ax1 < bx2 && ay1 < by2 && bx1 < ax2 && by1 < ay2;
}
Example #3
0
//==============================================================================
bool BodyNodeDistanceFilter::needDistance(
    const collision::CollisionObject* object1,
    const collision::CollisionObject* object2) const
{
  if (object1 == object2)
    return false;

  auto shapeNode1 = object1->getShapeFrame()->asShapeNode();
  auto shapeNode2 = object2->getShapeFrame()->asShapeNode();

  if (!shapeNode1 || !shapeNode2)
    return true;
  // We assume that non-ShapeNode is always being checked collision.

  auto bodyNode1 = shapeNode1->getBodyNodePtr();
  auto bodyNode2 = shapeNode2->getBodyNodePtr();

  if (!bodyNode1->isCollidable() || !bodyNode2->isCollidable())
    return false;

  if (bodyNode1->getSkeleton() == bodyNode2->getSkeleton())
  {
    auto skeleton = bodyNode1->getSkeleton();

    if (!skeleton->isEnabledSelfCollisionCheck())
      return false;

    if (!skeleton->isEnabledAdjacentBodyCheck())
    {
      if (areAdjacentBodies(bodyNode1, bodyNode2))
        return false;
    }
  }

  return true;
}
bool FCLMESHCollisionDetector::checkCollision(bool _checkAllCollisions,
                                              bool _calculateContactPoints)
{
    int num_max_contact = 100;
    clearAllContacts();
    bool collision = false;

    FCLMESHCollisionNode* FCLMESHCollisionNode1 = NULL;
    FCLMESHCollisionNode* FCLMESHCollisionNode2 = NULL;

    for (int i = 0; i < mCollisionNodes.size(); i++)
    {
        mCollisionNodes[i]->getBodyNode()->setColliding(false);
    }

    for (int i = 0; i < mCollisionNodes.size(); i++)
    {
        FCLMESHCollisionNode1 = static_cast<FCLMESHCollisionNode*>(mCollisionNodes[i]);

        for (int j = i + 1; j < mCollisionNodes.size(); j++)
        {
            FCLMESHCollisionNode2 = static_cast<FCLMESHCollisionNode*>(mCollisionNodes[j]);

            if (!isCollidable(FCLMESHCollisionNode1, FCLMESHCollisionNode2))
            {
                continue;
            }
            
            if(FCLMESHCollisionNode1->checkCollision(FCLMESHCollisionNode2,
                    _calculateContactPoints ? &mContacts : NULL,
                    num_max_contact))
            {
                collision = true;
                mCollisionNodes[i]->getBodyNode()->setColliding(true);
                mCollisionNodes[j]->getBodyNode()->setColliding(true);

                if(!_checkAllCollisions)
                {
                    return true;
                }
            }
        }
    }

    return collision;
}
Example #5
0
bool object::checkCollision(object &obj)
{
	if ( !isCollidable() || !obj.isCollidable() )
	{
		return false;
	}
	if ( 
		x < obj.getX() + obj.getBoundX() - 1 &&
		y < obj.getY() + obj.getBoundY() - 1 &&
		x + boundX -1 > obj.getX() &&
		y + boundY - 1 > obj.getY() 
	   )
	{
		collision();
		obj.collision();
		return true;
	}

	return false;
}
bool FCLMeshCollisionDetector::detectCollision(bool _checkAllCollisions,
                                               bool _calculateContactPoints)
{
    clearAllContacts();
    bool collision = false;

    FCLMeshCollisionNode* FCLMeshCollisionNode1 = NULL;
    FCLMeshCollisionNode* FCLMeshCollisionNode2 = NULL;

    for (int i = 0; i < mCollisionNodes.size(); i++)
        mCollisionNodes[i]->getBodyNode()->setColliding(false);

    for (int i = 0; i < mCollisionNodes.size(); i++)
    {
        FCLMeshCollisionNode1 = static_cast<FCLMeshCollisionNode*>(mCollisionNodes[i]);

        for (int j = i + 1; j < mCollisionNodes.size(); j++)
        {
            FCLMeshCollisionNode2 = static_cast<FCLMeshCollisionNode*>(mCollisionNodes[j]);

            if (!isCollidable(FCLMeshCollisionNode1, FCLMeshCollisionNode2))
                continue;
            
            if(FCLMeshCollisionNode1->detectCollision(FCLMeshCollisionNode2,
                    _calculateContactPoints ? &mContacts : NULL,
                    mNumMaxContacts))
            {
                collision = true;
                mCollisionNodes[i]->getBodyNode()->setColliding(true);
                mCollisionNodes[j]->getBodyNode()->setColliding(true);

                if(!_checkAllCollisions)
                    return true;
            }
        }
    }

    return collision;
}
bool DARTCollisionDetector::detectCollision(bool /*_checkAllCollisions*/,
                                            bool /*_calculateContactPoints*/) {
  clearAllContacts();

  // Set all the body nodes are not in colliding
  for (size_t i = 0; i < mCollisionNodes.size(); i++)
    mCollisionNodes[i]->getBodyNode()->setColliding(false);

  std::vector<Contact> contacts;

  for (size_t i = 0; i < mCollisionNodes.size(); i++) {
    for (size_t j = i + 1; j < mCollisionNodes.size(); j++) {
      CollisionNode* collNode1 = mCollisionNodes[i];
      CollisionNode* collNode2 = mCollisionNodes[j];
      dynamics::BodyNode* BodyNode1 = collNode1->getBodyNode();
      dynamics::BodyNode* BodyNode2 = collNode2->getBodyNode();

      if (!isCollidable(collNode1, collNode2))
        continue;

      for (size_t k = 0; k < BodyNode1->getNumCollisionShapes(); k++) {
        for (size_t l = 0; l < BodyNode2->getNumCollisionShapes(); l++) {
          int currContactNum = mContacts.size();

          contacts.clear();
          collide(BodyNode1->getCollisionShape(k),
                  BodyNode1->getTransform()
                  * BodyNode1->getCollisionShape(k)->getLocalTransform(),
                  BodyNode2->getCollisionShape(l),
                  BodyNode2->getTransform()
                  * BodyNode2->getCollisionShape(l)->getLocalTransform(),
                  &contacts);

          size_t numContacts = contacts.size();

          for (unsigned int m = 0; m < numContacts; ++m) {
            Contact contactPair;
            contactPair = contacts[m];
            contactPair.bodyNode1 = BodyNode1;
            contactPair.bodyNode2 = BodyNode2;
            assert(contactPair.bodyNode1 != NULL);
            assert(contactPair.bodyNode2 != NULL);

            mContacts.push_back(contactPair);
          }

          std::vector<bool> markForDeletion(numContacts, false);
          for (size_t m = 0; m < numContacts; m++) {
            for (size_t n = m + 1; n < numContacts; n++) {
              Eigen::Vector3d diff =
                  mContacts[currContactNum + m].point -
                  mContacts[currContactNum + n].point;
              if (diff.dot(diff) < 1e-6) {
                markForDeletion[m] = true;
                break;
              }
            }
          }

          for (int m = numContacts - 1; m >= 0; m--)
          {
            if (markForDeletion[m])
              mContacts.erase(mContacts.begin() + currContactNum + m);
          }
        }
      }
    }
  }

  for (size_t i = 0; i < mContacts.size(); ++i)
  {
    // Set these two bodies are in colliding
    mContacts[i].bodyNode1->setColliding(true);
    mContacts[i].bodyNode2->setColliding(true);
  }

  return !mContacts.empty();
}