void CylinderRule::execute(Grammar &grammar, Context &context, Shape &shape) { if (shape.getShapeType() != ST_Prism) { // La règle ne s'applique que sur un prisme throw std::runtime_error("build_cylinder can only be used on Prism primitives"); } Prism const& prism = static_cast<Prism const&>(shape); std::vector<glm::vec2> const &points = prism.poly.getPoints(); const int n = points.size(); // Find the centroid glm::vec2 centroid; for (int i = 0; i < n; i++) { centroid += points[i]; } centroid /= n; glm::vec3 centroid3d(centroid.x, 0, centroid.y); centroid3d = centroid3d + glm::vec3(0, context.terrain->getHeight(centroid), 0); // Build a cylinder of center 'centroid' of radius 'radius' and height 'height' float radius = GRandom.RandomNumber(radius_min, radius_max); float height = GRandom.RandomNumber(height_min, height_max); Circle2D circle(radius, centroid3d); Cylinder cyl(circle, height); // Successeurs if (successors.size() != 1) { throw std::runtime_error("build_cylinder operation must have only one successor"); } CSymbol *succ = *successors.begin(); grammar.resolve(succ, context, cyl); }
void SelectFacesRule::execute(Grammar &grammar, Context &context, Shape &shape) { if (shape.getShapeType() != ST_Cuboid) { throw std::runtime_error("select_faces can only be used on cuboids"); } Cuboid const &cube = static_cast<Cuboid const &>(shape); std::vector<Rectangle2D *> faces(6); CoordSystem const &cs = cube.getCoordSystem(); // compute faces of the cuboid glm::vec3 dimensions = cube.dimensions; float dx = cube.dimensions.x; float dy = cube.dimensions.y; float dz = cube.dimensions.z; glm::vec3 position = cs.position; glm::vec3 vdx = glm::vec3(dimensions.x, 0, 0); glm::vec3 vdy = glm::vec3(0, dimensions.y, 0); glm::vec3 vdz = glm::vec3(0, 0, dimensions.z); glm::vec3 vx = glm::vec3(1, 0, 0); glm::vec3 vy = glm::vec3(0, 1, 0); glm::vec3 vz = glm::vec3(0, 0, 1); // front faces[0] = new Rectangle2D(CoordSystem::fromVectors(cs, vdy + vdx, -vx, -vy), dx, dy); // back faces[1] = new Rectangle2D(CoordSystem::fromVectors(cs, vdz, vy, vx), dy, dx); // up faces[2] = new Rectangle2D(CoordSystem::fromVectors(cs, vdy, vx, vz), dx, dz); // down faces[3] = new Rectangle2D(CoordSystem::fromVectors(cs, glm::vec3(0.f), vx, vz), dx, dz); // left faces[4] = new Rectangle2D(CoordSystem::fromVectors(cs, vdx, vz, vy), dz, dy); // right faces[5] = new Rectangle2D(CoordSystem::fromVectors(cs, glm::vec3(0.f), vy, vz), dy, dz); // Successeurs = faces int i = 0; for (std::list<CSymbol *>::iterator it = successors.begin(); it != successors.end(); it++, i++) { grammar.resolve(*it, context, *(faces[i])); } }
void SplitCylinderRule::execute(Grammar &grammar, Context &context, Shape &shape) { if (shape.getShapeType() != ST_Cylinder) { // La règle ne s'applique que sur un cylindre throw std::runtime_error("split_cylinder can only be used on Cylinder primitives"); } Cylinder const& cylinder = static_cast<Cylinder const&>(shape); std::vector<Cylinder> cylinders; cylinder.split(numDivisions, cylinders); // Successeurs if (successors.size() != 1) { throw std::runtime_error("split_cylinder operation must have only one successor"); } CSymbol *succ = *successors.begin(); for (std::vector<Cylinder>::iterator it = cylinders.begin(); it != cylinders.end(); it++) { grammar.resolve(succ, context, *it); } }
void TranslationRule::execute(Grammar &grammar, Context &context, Shape &shape) { if (shape.getShapeType() != ST_Polygon) { // La règle ne s'applique que sur un polygon throw std::runtime_error("translation can only be used on Polygon2D primitives"); } Polygon2D const& poly = static_cast<Polygon2D const&>(shape); std::vector<glm::vec2> points = poly.getPoints(); const int n = points.size(); for (int i = 0; i < n; i++) { points[i].x += x; points[i].y += y; } CoordSystem cs = poly.getCoordSystem(); cs.position.x += x; cs.position.y += y; Polygon2D res; for (int i = 0; i < n; i++) { res.addPoint(points[i]); } res.getCoordSystem().position = cs.position; res.getCoordSystem().rotation = cs.rotation; // Successeurs if (successors.size() != 1) { throw std::runtime_error("translation operation must have only one successor"); } CSymbol *succ = *successors.begin(); grammar.resolve(succ, context, res); }