GCC Code Coverage Report


ernie/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
1 / 1
100.0%
Branches:
-
-%
Functions:
-
-%

scene/xform.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 /// @file xform.h
3 /// @brief UsdGeomXformable's transform ops: composing them, and authoring them from parts.
4 #pragma once
5
6 #include "ernie/export.h"
7 #include "ernie/scene/scene.h"
8
9 #include <glm/glm.hpp>
10 #include <glm/gtc/quaternion.hpp>
11
12 #include <cstdint>
13 #include <optional>
14 #include <string>
15 #include <string_view>
16 #include <vector>
17
18 namespace ernie {
19
20 /// The order Euler rotation ops (`rotateXYZ` ...) turn about their axes, first axis first.
21 enum class RotationOrder : std::uint8_t { XYZ, XZY, YXZ, YZX, ZXY, ZYX };
22
23 /// @return The op name of an order, as `xformOp:rotateXYZ`.
24 ERNIE_API std::string_view RotateOp(RotationOrder order);
25 /// @return The rotation of Euler angles in degrees, the order's first axis turning first.
26 ERNIE_API glm::dmat3 EulerRotation(const glm::dvec3& degrees, RotationOrder order);
27 /// @return Angles in degrees that `EulerRotation` turns back into `rotation`.
28 ERNIE_API glm::dvec3 EulerAngles(const glm::dmat3& rotation, RotationOrder order);
29
30 /// @brief A transform as translate, rotate or orient, and scale ops; unset parts are left out.
31 struct XformOps {
32 std::optional<glm::dvec3> translate;
33 /// Euler angles in degrees, in `rotationOrder`.
34 std::optional<glm::dvec3> rotate;
35 RotationOrder rotationOrder = RotationOrder::XYZ;
36 std::optional<glm::dquat> orient;
37 std::optional<glm::dvec3> scale;
38 };
39
40 /// @return A camera's transform at `eye` looking at `target`, `up` upward in the view: cameras
41 /// look down their -z with +y up, as USD's do.
42 /// @throws std::invalid_argument when `target` is `eye`, or `up` is along the view.
43 ERNIE_API glm::dmat4 LookAtTransform(const glm::dvec3& eye, const glm::dvec3& target,
44 const glm::dvec3& up = glm::dvec3(0.0, 0.0, 1.0));
45 /// @return A distant light's transform shining from `towardLight`, the direction to its source:
46 /// distant lights shine down their -z, so their +z is turned to it.
47 /// @throws std::invalid_argument for a zero direction.
48 ERNIE_API glm::dmat4 DistantLightTransform(const glm::dvec3& towardLight);
49
50 /// @brief Authors a prim's ops and their order, keeping a reset stack.
51 /// @throws std::invalid_argument if there is no prim at `path`, or `xform` has both rotate and
52 /// orient.
53 ERNIE_API void SetXform(Scene& scene, const Path& path, const XformOps& xform);
54
55 /// @return The prim's local transform from its ops in `xformOpOrder`; without an order,
56 /// `xformOp:transform` alone.
57 /// @throws std::invalid_argument for an op Ernie does not know or a value of the wrong kind.
58 ERNIE_API glm::dmat4 ComposeXformOps(const Scene& scene, PrimId prim);
59 /// @return Whether the prim's transform ignores its ancestors' (`!resetXformStack!`).
60 ERNIE_API bool ResetsXformStack(const Scene& scene, PrimId prim);
61
62 /// The transform ops Ernie knows; the Euler rotations in `RotationOrder`'s order.
63 enum class XformOpKind : std::uint8_t {
64 Translate,
65 Scale,
66 RotateX,
67 RotateY,
68 RotateZ,
69 RotateXYZ,
70 RotateXZY,
71 RotateYXZ,
72 RotateYZX,
73 RotateZXY,
74 RotateZYX,
75 Orient,
76 Transform,
77 };
78
79 /// @return The kind of an op attribute, as `xformOp:rotateXYZ:arm` is a `RotateXYZ`; none for an
80 /// attribute that is no op Ernie knows.
81 ERNIE_API std::optional<XformOpKind> ParseXformOpKind(std::string_view attribute);
82
83 /// @brief One op of a prim's transform: its attribute, kind and whether the order inverts it.
84 11292 struct XformOp {
85 std::string attribute;
86 XformOpKind kind = XformOpKind::Transform;
87 bool invert = false;
88 /// The attribute's token, when interned as the order was read, to read its value by.
89 std::optional<Token> token;
90 bool operator==(const XformOp&) const = default;
91 };
92 /// @return The prim's ops, outermost first, as `ComposeXformOps` multiplies them: those of
93 /// `xformOpOrder` without its reset token, or without an order `xformOp:transform` alone.
94 /// @throws std::invalid_argument for an entry that is no xformOp, or an op Ernie does not know.
95 ERNIE_API std::vector<XformOp> XformOpsInOrder(const Scene& scene, PrimId prim);
96 /// @return One op's matrix, inverted if the order says so; identity when it has no value.
97 /// @throws std::invalid_argument for a value of the wrong kind.
98 ERNIE_API glm::dmat4 XformOpMatrix(const Scene& scene, PrimId prim, const XformOp& op);
99
100 } // namespace ernie
101