| 2184 | } |
| 2185 | |
| 2186 | void InputController::handleGoToCamView(const lfs::core::events::cmd::GoToCamView& event) { |
| 2187 | LOG_TIMER_TRACE("HandleGoToCamView"); |
| 2188 | auto& target_viewport = activeKeyboardViewport(); |
| 2189 | |
| 2190 | std::shared_ptr<const lfs::core::Camera> cam_data; |
| 2191 | if (auto* trainer = services().trainerOrNull()) { |
| 2192 | cam_data = trainer->getCamById(event.cam_id); |
| 2193 | } |
| 2194 | if (!cam_data) { |
| 2195 | if (auto* scene_mgr = services().sceneOrNull()) { |
| 2196 | cam_data = scene_mgr->getScene().getCameraByUid(event.cam_id); |
| 2197 | } |
| 2198 | } |
| 2199 | if (!cam_data) { |
| 2200 | LOG_ERROR("Camera ID {} not found", event.cam_id); |
| 2201 | return; |
| 2202 | } |
| 2203 | if (input_router_) |
| 2204 | input_router_->focusViewportKeyboard(); |
| 2205 | |
| 2206 | // Get rotation and translation tensors and ensure they're on CPU |
| 2207 | auto R_tensor = cam_data->R().cpu(); |
| 2208 | auto T_tensor = cam_data->T().cpu(); |
| 2209 | |
| 2210 | // Get raw CPU pointers - safer and more efficient |
| 2211 | const float* R_data = R_tensor.ptr<float>(); |
| 2212 | const float* T_data = T_tensor.ptr<float>(); |
| 2213 | |
| 2214 | if (!R_data || !T_data) { |
| 2215 | LOG_ERROR("Failed to get camera R/T data pointers"); |
| 2216 | return; |
| 2217 | } |
| 2218 | |
| 2219 | // Apply scene transform (handles user rotation/translation of the scene) |
| 2220 | glm::mat4 scene_transform(1.0f); |
| 2221 | if (auto* scene_mgr = services().sceneOrNull()) { |
| 2222 | if (const auto transform = |
| 2223 | scene_mgr->getScene().getCameraSceneTransformByUid(cam_data->uid())) { |
| 2224 | scene_transform = lfs::rendering::dataWorldTransformToVisualizerWorld(*transform); |
| 2225 | } |
| 2226 | } |
| 2227 | |
| 2228 | const auto pose = lfs::rendering::visualizerCameraPoseFromDataWorldToCamera( |
| 2229 | lfs::rendering::mat3FromRowMajor3x3(R_data), |
| 2230 | glm::vec3(T_data[0], T_data[1], T_data[2]), |
| 2231 | scene_transform); |
| 2232 | |
| 2233 | float pivot_distance = glm::length(target_viewport.camera.getPivot() - target_viewport.camera.t); |
| 2234 | if (!std::isfinite(pivot_distance) || pivot_distance < 0.1f) |
| 2235 | pivot_distance = 5.0f; |
| 2236 | |
| 2237 | target_viewport.setViewMatrix(pose.rotation, pose.translation); |
| 2238 | |
| 2239 | target_viewport.camera.updatePivotFromCamera(pivot_distance); |
| 2240 | |
| 2241 | // Save as home position if this is the first camera view |
| 2242 | if (!target_viewport.camera.home_saved) { |
| 2243 | target_viewport.camera.saveHomePosition(); |
nothing calls this directly
no test coverage detected