layers/boulders/boulder_models.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file | ||
| 2 | /// @brief Boulders as 3D models: placing unit shapes on the ground, and their meshes. | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include "terraingen/layers/boulders/boulder.h" | ||
| 6 | #include "terraingen/layers/boulders/boulder_shape.h" | ||
| 7 | #include "terraingen/mesh/mesh.h" | ||
| 8 | #include "terraingen/util/surface.h" | ||
| 9 | |||
| 10 | #include <cstdint> | ||
| 11 | #include <memory> | ||
| 12 | #include <optional> | ||
| 13 | |||
| 14 | namespace terraingen { | ||
| 15 | |||
| 16 | /// How a unit `BoulderShape` becomes a boulder in the world: scaled per axis by `scale`, | ||
| 17 | /// then moved by `pose`. | ||
| 18 | struct BoulderPlacement { | ||
| 19 | Vec3d scale{1.0, 1.0, 1.0}; ///< Scale along the shape's x, y and z, in metres. | ||
| 20 | RigidTransform pose{}; ///< Rotation and translation after scaling. | ||
| 21 | |||
| 22 | /// Where point `p` of the unit shape lands in the world. | ||
| 23 | 21592729 | Vec3d Apply(const Vec3d& p) const { | |
| 24 | 21592729 | return pose.Apply({p.x * scale.x, p.y * scale.y, p.z * scale.z}); | |
| 25 | } | ||
| 26 | }; | ||
| 27 | |||
| 28 | /// A boulder placed as a 3D model of its own. | ||
| 29 | struct BoulderModel { | ||
| 30 | Boulder boulder; ///< Its record. | ||
| 31 | std::uint64_t shapeSeed = 0; ///< The seed of its shape, or of its parent's for a fragment. | ||
| 32 | std::shared_ptr<const BoulderShape> shape; ///< Its unit shape. | ||
| 33 | BoulderPlacement placement; ///< The shape moved onto the ground beneath it. | ||
| 34 | }; | ||
| 35 | |||
| 36 | /// The height at world (x, y) of the highest upward-facing triangle of `placed` (a mesh in world | ||
| 37 | /// coordinates), or nothing outside its footprint. | ||
| 38 | std::optional<double> TopSurface(const TriangleMesh& placed, double x, double y); | ||
| 39 | |||
| 40 | /// A boulder's placement moved from its own local frame into the local frame of a site. | ||
| 41 | /// | ||
| 42 | /// On a sphere the site frame is east, north and up at `site` on the datum sphere, keeping a scene | ||
| 43 | /// about a site in metre-scale coordinates; on a plane `placement` is returned unchanged. | ||
| 44 | /// @param placement In the boulder's local frame (east, north, up above datum). | ||
| 45 | /// @param boulder Surface coordinates of the boulder. | ||
| 46 | /// @param site Surface coordinates of the site. | ||
| 47 | BoulderPlacement PlacementAtSite(const BoulderPlacement& placement, const Vec2d& boulder, | ||
| 48 | const Vec2d& site, const Surface& surface); | ||
| 49 | |||
| 50 | /// The rotation tipping the vertical by `tilt` radians toward `azimuth` (radians counter-clockwise | ||
| 51 | /// from east), about the horizontal axis square to that direction. | ||
| 52 | RigidTransform TiltRotation(double tilt, double azimuth); | ||
| 53 | |||
| 54 | /// The placement of a shape as a boulder standing on the ground. | ||
| 55 | /// | ||
| 56 | /// The long axis is scaled to the diameter (the intermediate in proportion) and the short axis to | ||
| 57 | /// the height; then stood on the axis `rest` names, leaned by `lean` about the long axis, turned by | ||
| 58 | /// `yaw`, tipped by `tilt` toward `tiltAzimuth`, and set at the boulder's position with `burial` | ||
| 59 | /// of its vertical extent below `groundHeight`. With `settle`, before the tilt it is tipped over | ||
| 60 | /// on level ground, from that pose, until it rests stably with its centre of mass above the face | ||
| 61 | /// or edges it stands on, so no shape is left balanced on a corner. | ||
| 62 | /// @param groundHeight Height of the ground under its centre, in metres. | ||
| 63 | BoulderPlacement PlaceBoulderModel(const Boulder& boulder, const BoulderShape& shape, | ||
| 64 | double groundHeight, bool settle = false); | ||
| 65 | |||
| 66 | /// A boulder as a mesh in world coordinates, its own shape placed by `PlaceBoulderModel`. | ||
| 67 | /// @param groundHeight Height of the ground under its centre, in metres. | ||
| 68 | /// @param prototypes Number of shared shapes, or 0 for a shape per boulder (`BoulderShapeSeed`). | ||
| 69 | /// @throws std::invalid_argument as `ValidateBoulderShapeOptions`. | ||
| 70 | TriangleMesh BoulderMesh(const Boulder& boulder, const BoulderShapeOptions& options, | ||
| 71 | double groundHeight, std::uint32_t prototypes = 0); | ||
| 72 | |||
| 73 | } // namespace terraingen | ||
| 74 |