1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//! # Rerun spatial transform processing
//!
//! ## Concepts
//!
//! ### Transform frames
//!
//! A transform frame is a geometric reference frame that may be connected via an affine transform to another reference frame.
//! For instance, the transform frame of a robot body may be connected to the transform frame of the robot's arm
//! via a translation & rotation.
//!
//! Transform frames are identified by a string identifier, see [`re_sdk_types::components::TransformFrameId`].
//!
//! Spatial transforms may change over time to model movement of an object and its parts.
//! While typically fairly fixed, the topology of the transform graph may change over time.
//!
//! A valid transform graph is expected to form a forest, i.e. one or more trees.
//!
//! #### Entity relationship & built-in transform frames
//!
//! Every entity is associated with a transform frame.
//! The transform frame can be set with [`re_sdk_types::archetypes::CoordinateFrame`].
//!
//! However, by default, it points to an implicit, entity-derived transform frame.
//! The name of the implicit transform frames is the entity path, prefixed with `tf#`, e.g. `tf#/world/robot/arm`.
//!
//! Entity derived transform frames automatically have an identity transform relationship
//! to their respective parent (unless overwritten by e.g. [`re_sdk_types::archetypes::Transform3D`]).
//!
//! Example:
//! Given an entity hierarchy:
//! ```text
//! world
//! |-- robot
//! | |-- left_arm
//! | |-- right_arm
//! ```
//! Without setting any transform frames, this means we have a identity connected tree
//! shown to the left that is associated with individual entities on the right:
//! ```text
//! ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌──────────────────┐
//! tf#world ◀ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│ world │
//! └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └──────────────────┘
//! │ │
//! │ │
//! │ │
//! │ │
//! ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌──────────────────┐
//! tf#world/robot ◀ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ world/robot │
//! └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └──────────────────┘
//! Λ Λ
//! ╱ ╲ ╱ ╲
//! ╱ ╲ ╱ ╲
//! ╱────────╱ ╲────────╲ ╱──────╱ ╲──────╲
//! ╱ ╲ ╱ ╲
//! ╱ ╲ ╱ ╲
//! ╱ ╲ ╱ ╲
//! ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌──────────────────┐ ┌──────────────────┐
//! tf#world/robot/left tf#world/robot/right │ world/robot/left │ │world/robot/right │
//! └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └──────────────────┘ └──────────────────┘
//! ▲ ▲ │ │
//! │
//! ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │
//! ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
//! ```
//!
//! You can interact with these implicitly generated frames like with any other transform frame!
//! For example, let's say we log a manual transform relationship between two new frames called `robot_frame`
//! and `left_frame`, associate them with `world/robot` and `world/robot/left` respectively.
//! That would create two unconnected trees, but this can be handled by specifying another
//! relationship from `robot_frame` to `tf#world/robot`, leading to this setup:
//! ```text
//! ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌──────────────────┐
//! tf#world ◀ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│ world │
//! └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └──────────────────┘
//! │ │
//! ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │
//! │ │
//! ▼ │ │ │
//! ┌ ─ ─ ─ ─ ─ ─ ─ ┐ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌──────────────────┐
//! robot_frame ─────────────────── tf#world/robot └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ world/robot │
//! └ ─ ─ ─ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └──────────────────┘
//! │ Λ Λ
//! │ ╱ ╲ ╱ ╲
//! │ ╱ ╲ ╱ ╲
//! │ ╱────────╱ ╲────────╲ ╱──────╱ ╲──────╲
//! │ ╱ ╲ ╱ ╲
//! │ ╱ ╲ ╱ ╲
//! │ ╱ ╲ ╱ ╲
//! ┌ ─ ─ ─ ─ ─ ─ ─ ┐ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌──────────────────┐ ┌──────────────────┐
//! left_frame tf#world/robot/left tf#world/robot/right │ world/robot/left │ │world/robot/right │
//! └ ─ ─ ─ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └──────────────────┘ └──────────────────┘
//! ▲ ▲ │ │
//! │ │
//! ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │
//! └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
//! ```
//!
//! ### Instance poses
//!
//! Instance poses (or just poses) define a transform on top of a frame which are independent of the
//! frame graph structure and are not propagated through the transform tree.
//!
//! Conceptually, each pose transform forms a relationship from a frame-instance to its hosting frame.
//!
//! For more details see [`re_sdk_types::archetypes::InstancePoses3D`].
//!
//!
//! ## Implementation
//!
//!
//! ### [`TransformForest`]
//!
//! Analyzes & propagates the transform graph such that querying relationships from
//! any source frame to any target frames for a given time can be done efficiently.
//!
//! ### [`TransformResolutionCache`]
//!
//! Resolves transform relationships over time to standardized affine (mat3x3 + translation) transforms.
//! This is a fairly complex workload since combining everything in [`re_sdk_types::archetypes::Transform3D`]
//! and other transform archetypes into a single affine transform is not trivial and needs to be done
//! in the correct order.
//!
//! The [`TransformResolutionCache`] makes sure that (latest-at) lookups of affine transforms
//! can be performed efficiently while heeding the query rules established by [`re_entity_db::external::re_query`].
//!
//!
//! ### [`TransformFrameIdHash`]
//!
//! Throughout this crate, we almost always use pre-hashed [`re_sdk_types::components::TransformFrameId`]s, i.e. [`TransformFrameIdHash`].
//! Hashes are assumed to be collision free, allowing use as keys in maps.
//!
//! For performance & convenience, there's a 1:1 mapping from [`re_log_types::EntityPathHash`] to [`TransformFrameIdHash`]
//! for referring to built-in transform frames.
//!
// Re-export the transform frame id types from re_sdk_types.
pub use TransformFrameIdHash;
pub use TransformFrameId;
pub use FrameIdRegistry;
pub use ;
pub use ;
pub use ;
/// Returns the view coordinates used for 2D (image) views.
///
/// TODO(#1387): Image coordinate space should be configurable.