Ejemplo n.º 1
0
void processRemoval(b2Vec2 removalPosition, float removalRadius, b2World& world, bool simplifyGeometry)
{
	auto foundBodies = queryDestructibleBodies(removalPosition, removalRadius, world);
	auto batch = matchBodiesToRings(foundBodies.begin(), foundBodies.end());

	// Partition the shapes by area, so that elements to be processed are at the beginning
	auto borderIt = std::partition(batch.begin(), batch.end(), [](const match_t& m) {
		const double areaEpsilon = 0.02;
		return bg::area(m.second) > areaEpsilon;
	});

	// Remove small shapes
	std::for_each(borderIt, batch.end(), [&](const match_t& m) {
		world.DestroyBody(m.first);
	});

	// Subtract the input polygon from each shape returned from the query
	ring_t diff = makeConvexRing(removalPosition, removalRadius, 16);
	boost::geometry::correct(diff);

	typedef std::pair<std::unique_ptr<b2ChainShape>, b2Filter> shape_property_t;
	std::vector<shape_property_t> resultShapes;
	std::for_each(batch.begin(), borderIt, [&](const match_t& m) {
		auto subtractionResult = subtract(m.second, diff);
		// Simplify the results
		if (simplifyGeometry)
		{
			simplify(subtractionResult);
		}
		
		// Convert the rings to b2ChainShapes and add to result shapes
		auto converted = convertGeometry(subtractionResult);

		auto moveBegin = std::make_move_iterator(converted.begin());
		auto moveEnd = std::make_move_iterator(converted.end());
		std::transform(moveBegin, moveEnd, std::back_inserter(resultShapes),
			[&](std::unique_ptr<b2ChainShape> converted) {
			auto filter = m.first->GetFixtureList()->GetFilterData();
			return std::make_pair(std::move(converted), filter);
		});
		
		if (!subtractionResult.empty())
		{
			world.DestroyBody(m.first);
		}
	});

	for (auto&& s : resultShapes)
	{
		b2BodyDef bd;
		b2Body* body = world.CreateBody(&bd);
		auto fixture = body->CreateFixture(s.first.get(), 0.0f);
		fixture->SetFilterData(s.second);
	}
}
Ejemplo n.º 2
0
PolygonalGeometry * AssimpMeshLoader::load(const std::string & filename, const reflectionzeug::Variant & options, std::function<void(int, int)> /*progress*/) const
{
    bool smoothNormals = false;

    // Get options
    const reflectionzeug::VariantMap * map = options.asMap();
    if (map) {
        if (map->count("smoothNormals") > 0) smoothNormals = map->at("smoothNormals").value<bool>();
    }

    // Import scene
    auto scene = aiImportFile(
        filename.c_str(),
        aiProcess_Triangulate           |
        aiProcess_JoinIdenticalVertices |
        aiProcess_SortByPType |
        (smoothNormals ? aiProcess_GenSmoothNormals : aiProcess_GenNormals));

    // Check for errors
    if (!scene)
    {
        std::cout << aiGetErrorString();
        return nullptr;
    }

    // Convert first mesh found in the scene
    PolygonalGeometry * geometry = nullptr;
    if (scene->mNumMeshes > 0) {
        geometry = convertGeometry(scene->mMeshes[0]);
    }

    // Release scene
    aiReleaseImport(scene);

    // Return loaded mesh
    return geometry;
}
Ejemplo n.º 3
0
Scene * AssimpSceneLoader::convertScene(const aiScene * scene) const
{
    // Create new scene
    Scene * sceneOut = new Scene;

    // Convert meshes from the scene
    for (size_t i = 0; i < scene->mNumMeshes; ++i)
    {
        sceneOut->meshes().push_back(convertGeometry(scene->mMeshes[i]));
    }

    for (unsigned int i = 0; i < scene->mNumMaterials; ++i)
    {
        aiString filename;
        // only fetch texture with index 0
        if (scene->mMaterials[i]->GetTexture(aiTextureType_DIFFUSE, 0, &filename) == aiReturn_SUCCESS)
        {
            sceneOut->materials()[i] = std::string(filename.C_Str());
        }
    }

    // Return scene
    return sceneOut;
}
Ejemplo n.º 4
0
Feature convertFeature(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) {
    Feature feature { convertGeometry(geometryTileFeature, tileID) };
    feature.properties = geometryTileFeature.getProperties();
    feature.id = geometryTileFeature.getID();
    return feature;
}