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); } }
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; }
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; }
Feature convertFeature(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) { Feature feature { convertGeometry(geometryTileFeature, tileID) }; feature.properties = geometryTileFeature.getProperties(); feature.id = geometryTileFeature.getID(); return feature; }