The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

m/space: Refactor apply_relation

Before, apply_relation had unclear semantics and "upgraded" relation flags
to valid if either one of the relations had them. Most likely this was
because poses were considered to be not tracked and not having a velocity.

But OpenXR behavior says that something that is just an offset to something
else, for example local stage in stage space should have tracked flags, and
probably velocity valid flags.

The only time when something is not tracked in OpenXR is when the path
through the space graph passes through a space that actually tracks
something with a tracking system that currently can not track that something.
(Or when two spaces are in disjunct partitions of the space graph).

Therefore, insert poses as fully tracked relations with zero velocities
into the relation chain and remove all the "upgrade" behavior.

+43 -43
+23 -37
src/xrt/auxiliary/math/m_space.cpp
··· 133 133 flags af = get_flags(a); 134 134 flags bf = get_flags(b); 135 135 136 + // If either of the relations does not have a valid or tracked flag, the entire chain loses that flag. 136 137 flags nf = {}; 138 + nf.has_orientation = af.has_orientation && bf.has_orientation; 139 + nf.has_position = af.has_position && bf.has_position; 140 + nf.has_tracked_orientation = af.has_tracked_orientation && bf.has_tracked_orientation; 141 + nf.has_tracked_position = af.has_tracked_position && bf.has_tracked_position; 142 + nf.has_linear_velocity = af.has_linear_velocity && bf.has_linear_velocity; 143 + nf.has_angular_velocity = af.has_angular_velocity && bf.has_angular_velocity; 144 + 137 145 struct xrt_pose pose = XRT_POSE_IDENTITY; 138 146 struct xrt_vec3 linear_velocity = XRT_VEC3_ZERO; 139 147 struct xrt_vec3 angular_velocity = XRT_VEC3_ZERO; ··· 146 154 struct xrt_pose body_pose = XRT_POSE_IDENTITY; // aka valid_a_pose 147 155 struct xrt_pose base_pose = XRT_POSE_IDENTITY; // aka valid_b_pose 148 156 149 - // Only valid poses handled in chain. Flags are determined later. 157 + // If either orientation or position component is not valid, make that component identity so that transforms 158 + // work. The flags of the result are determined in nf and not taken from the result of the transform. 150 159 make_valid_pose(af, &a->pose, &body_pose); 151 160 make_valid_pose(bf, &b->pose, &base_pose); 152 161 153 - // Pose will be undefined if we don't have at least rotation. 162 + // Not already valid poses needed to be made valid because the transoformed pose would be undefined otherwise 163 + // and we still want e.g. valid positions. 154 164 math_pose_transform(&base_pose, &body_pose, &pose); 155 165 156 166 ··· 158 168 * Linear velocity. 159 169 */ 160 170 161 - if (af.has_linear_velocity) { 162 - nf.has_linear_velocity = true; 171 + // We only need to bother with velocities if we know that we will pass them on. 172 + if (nf.has_linear_velocity) { 163 173 struct xrt_vec3 tmp = XRT_VEC3_ZERO; 164 174 165 175 math_quat_rotate_vec3(&base_pose.orientation, // Base rotation ··· 167 177 &tmp); // Output 168 178 169 179 linear_velocity += tmp; 170 - } 171 - 172 - if (bf.has_linear_velocity) { 173 - nf.has_linear_velocity = true; 174 180 linear_velocity += b->linear_velocity; 175 181 } 176 182 ··· 179 185 * Angular velocity. 180 186 */ 181 187 182 - if (af.has_angular_velocity) { 183 - nf.has_angular_velocity = true; 188 + if (nf.has_angular_velocity) { 184 189 struct xrt_vec3 tmp = XRT_VEC3_ZERO; 185 190 186 191 math_quat_rotate_derivative(&base_pose.orientation, // Base rotation ··· 188 193 &tmp); // Output 189 194 190 195 angular_velocity += tmp; 191 - } 192 - 193 - if (bf.has_angular_velocity) { 194 - nf.has_angular_velocity = true; 195 - nf.has_linear_velocity = true; 196 196 angular_velocity += b->angular_velocity; 197 197 198 198 // handle tangential velocity AKA "lever arm" effect on velocity: ··· 223 223 224 224 int new_flags = 0; 225 225 226 - /* 227 - * Make sure to not drop a space relation, even if only either position 228 - * or orintation is valid. We should not be getting here if neither 229 - * position and orintation is valid. 230 - * 231 - * When position is valid, always set orientation valid to "upgrade" 232 - * poses with valid position but invalid orientation to fully valid 233 - * pose using identity quat, @see make_valid_pose. 234 - * 235 - * When orientation is valid, always set position valid to "upgrade" 236 - * poses with valid orientation but invalid position to fully valid 237 - * pose using identity vec3, @see make_valid_pose. 238 - */ 239 - assert(af.has_position || af.has_orientation); 240 - assert(bf.has_position || bf.has_orientation); 241 - 242 - new_flags |= XRT_SPACE_RELATION_POSITION_VALID_BIT; 243 - new_flags |= XRT_SPACE_RELATION_ORIENTATION_VALID_BIT; 244 - 245 - //! @todo combining these flags with OR is probably okay for now 246 - if (af.has_tracked_position || bf.has_tracked_position) { 226 + if (nf.has_orientation) { 227 + new_flags |= XRT_SPACE_RELATION_ORIENTATION_VALID_BIT; 228 + } 229 + if (nf.has_position) { 230 + new_flags |= XRT_SPACE_RELATION_POSITION_VALID_BIT; 231 + } 232 + if (nf.has_tracked_position) { 247 233 new_flags |= XRT_SPACE_RELATION_POSITION_TRACKED_BIT; 248 234 } 249 - if (af.has_tracked_orientation || bf.has_tracked_orientation) { 235 + if (nf.has_tracked_orientation) { 250 236 new_flags |= XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT; 251 237 } 252 238 if (nf.has_linear_velocity) {
+20 -6
src/xrt/auxiliary/math/m_space.h
··· 53 53 * 54 54 */ 55 55 56 + /*! 57 + * Create an xrt_space_relation from a pose. If @p set_tracked is false, only orientation and position valid flags are 58 + * set. 59 + */ 56 60 static inline void 57 - m_space_relation_from_pose(const struct xrt_pose *pose, struct xrt_space_relation *out_relation) 61 + m_space_relation_from_pose(const struct xrt_pose *pose, bool set_tracked, struct xrt_space_relation *out_relation) 58 62 { 59 - enum xrt_space_relation_flags flags = (enum xrt_space_relation_flags)(XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | 60 - XRT_SPACE_RELATION_POSITION_VALID_BIT); 63 + enum xrt_space_relation_flags flags = 64 + set_tracked ? XRT_SPACE_RELATION_BITMASK_ALL 65 + : (enum xrt_space_relation_flags)(XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | 66 + XRT_SPACE_RELATION_POSITION_VALID_BIT); 67 + 61 68 struct xrt_space_relation relation = { 62 69 flags, 63 70 *pose, ··· 68 75 *out_relation = relation; 69 76 } 70 77 78 + /*! 79 + * Create an xrt_space_relation with only orientation and position valid flags. 80 + */ 71 81 static inline void 72 82 m_space_relation_ident(struct xrt_space_relation *out_relation) 73 83 { 74 84 struct xrt_pose identity = XRT_POSE_IDENTITY; 75 85 76 - m_space_relation_from_pose(&identity, out_relation); 86 + m_space_relation_from_pose(&identity, false, out_relation); 77 87 } 78 88 79 89 void ··· 146 156 } 147 157 148 158 /*! 149 - * Append a new pose as a relation without velocity 159 + * Append a new pose as a fully tracked relation. 160 + * This follows OpenXR conventions where a space that is purely an offset to another space is fully tracked in that 161 + * space. 162 + * Conceptually, a pose is only considered not fully tracked when it is related to an xrt_space_relation that is not 163 + * fully tracked. 150 164 * 151 165 * @public @memberof xrt_relation_chain 152 166 */ ··· 154 168 m_relation_chain_push_pose(struct xrt_relation_chain *xrc, const struct xrt_pose *pose) 155 169 { 156 170 struct xrt_space_relation relation; 157 - m_space_relation_from_pose(pose, &relation); 171 + m_space_relation_from_pose(pose, true, &relation); 158 172 m_relation_chain_push_relation(xrc, &relation); 159 173 } 160 174