diff --git a/src/headset/openxr_headset.cpp b/src/headset/openxr_headset.cpp index 1fc6e35462f52758e8446705c9157941e3c2d34e..b12ebc7e093bec6cf104dc849ebfdf3c0375610f 100644 --- a/src/headset/openxr_headset.cpp +++ b/src/headset/openxr_headset.cpp @@ -312,6 +312,7 @@ void OpenXRHeadset::on_destroy() this->destroy_swapchains(); xrDestroySpace(this->space); + xrDestroySpace(this->space2); xrDestroySession(this->session); } @@ -332,6 +333,8 @@ bool OpenXRHeadset::on_interface() bool OpenXRHeadset::on_update(lava::delta delta_time) { + this->get_application()->get_motion_tracking_time()->add_sample(delta_time * 1000.0f); + if (delta_time != 0.0f && !this->poll_events()) { return false; @@ -1238,9 +1241,9 @@ bool OpenXRHeadset::update_views(bool update_matrices) XrQuaternionf quaternion = view.pose.orientation; XrVector3f position = view.pose.position; - glm::mat4 pose_transform = (glm::mat4) glm::inverse(glm::quat(quaternion.w, quaternion.x, quaternion.y, quaternion.z)) * glm::translate(glm::mat4(1.0f), glm::vec3(-position.x, -position.y, -position.z)); - - this->head_to_eye_matrices[index] = glm::diagonal4x4(glm::vec4(1.0f, -1.0f, 1.0f, 1.0f)) * pose_transform; + glm::mat4 pose_transform = (glm::mat4)glm::inverse(glm::quat(quaternion.w, quaternion.x, quaternion.y, quaternion.z)) * glm::translate(glm::mat4(1.0f), glm::vec3(-position.x, -position.y, -position.z)); + + this->head_to_eye_matrices[index] = glm::diagonal4x4(glm::vec4(1.0f, -1.0f, 1.0f, 1.0f)) * pose_transform; float left = this->near_plane * glm::tan(view.fov.angleLeft); float right = this->near_plane * glm::tan(view.fov.angleRight); diff --git a/src/scene.cpp b/src/scene.cpp index c8882f3a6d7e7354a941cdc9c3af0d209ff88392..8d6c76440d5996245b354b2a3107b600827d086c 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -227,71 +227,76 @@ bool Scene::update(lava::delta delta_time, Headset::Ptr headset) if (this->animation_active && !this->animations.empty()) { - const SceneAnimation& active_animation = this->animations[this->animation_index]; - this->animation_time += delta_time * active_animation.ticks_per_second * this->animation_playback_speed; - - if (this->animation_loop) + this->animation_time += delta_time * this->animations[0].ticks_per_second * this->animation_playback_speed; + for (int i = 0; i < this->animations.size(); ++i) { - this->animation_time = std::fmod(this->animation_time, active_animation.duration); - } + const SceneAnimation& active_animation = this->animations[i]; - else - { - this->animation_time = std::min(this->animation_time, active_animation.duration); - } + if (this->animation_loop) + { + this->animation_time = std::fmod(this->animation_time, active_animation.duration); + } - for (const SceneAnimationChannel& channel : active_animation.channels) - { - glm::vec3 position = channel.position_frames.back().second; - aiQuaternion rotation = channel.rotation_frames.back().second; - glm::vec3 scaling = channel.scaling_frames.back().second; + else + { + this->animation_time = std::min(this->animation_time, active_animation.duration); + } - std::pair<float, glm::vec3> last_position_frame = channel.position_frames.front(); - for (const std::pair<float, glm::vec3>& position_frame : channel.position_frames) + for (const SceneAnimationChannel& channel : active_animation.channels) { - if (position_frame.first > this->animation_time) - { - const float fraction = (this->animation_time - last_position_frame.first) / (position_frame.first - last_position_frame.first); - position = glm::mix(last_position_frame.second, position_frame.second, fraction); + glm::vec3 position = channel.position_frames.back().second; + aiQuaternion rotation = channel.rotation_frames.back().second; + glm::vec3 scaling = channel.scaling_frames.back().second; - break; + //std::pair<float, glm::vec3> last_position_frame = channel.position_frames.front(); + for (const std::pair<float, glm::vec3>& position_frame : channel.position_frames) + { + if (position_frame.first > this->animation_time) + { + //const float fraction = (this->animation_time - last_position_frame.first) / (position_frame.first - last_position_frame.first); + //position = glm::mix(last_position_frame.second, position_frame.second, fraction); + position = position_frame.second; + break; + } + //last_position_frame = position_frame; } - last_position_frame = position_frame; - } - - std::pair<float, aiQuaternion> last_rotation_frame = channel.rotation_frames.front(); - for (const std::pair<float, aiQuaternion>& rotation_frame : channel.rotation_frames) - { - if (rotation_frame.first > this->animation_time) + //std::pair<float, aiQuaternion> last_rotation_frame = channel.rotation_frames.front(); + for (const std::pair<float, aiQuaternion>& rotation_frame : channel.rotation_frames) { - const float fraction = (this->animation_time - last_rotation_frame.first) / (rotation_frame.first - last_rotation_frame.first); - aiQuaternion::Interpolate(rotation, last_rotation_frame.second, rotation_frame.second, fraction); + if (rotation_frame.first > this->animation_time) + { + //const float fraction = (this->animation_time - last_rotation_frame.first) / (rotation_frame.first - last_rotation_frame.first); + //aiQuaternion::Interpolate(rotation, last_rotation_frame.second, rotation_frame.second, fraction); + rotation = rotation_frame.second; - break; - } + break; + } - last_rotation_frame = rotation_frame; - } + //last_rotation_frame = rotation_frame; + } - std::pair<float, glm::vec3> last_scaling_frame = channel.scaling_frames.front(); - for (const std::pair<float, glm::vec3>& scaling_frame : channel.scaling_frames) - { - if (scaling_frame.first > this->animation_time) + //std::pair<float, glm::vec3> last_scaling_frame = channel.scaling_frames.front(); + for (const std::pair<float, glm::vec3>& scaling_frame : channel.scaling_frames) { - const float fraction = (this->animation_time - last_scaling_frame.first) / (scaling_frame.first - last_scaling_frame.first); - scaling = glm::mix(last_scaling_frame.second, scaling_frame.second, fraction); + if (scaling_frame.first > this->animation_time) + { + //const float fraction = (this->animation_time - last_scaling_frame.first) / (scaling_frame.first - last_scaling_frame.first); + //scaling = glm::mix(last_scaling_frame.second, scaling_frame.second, fraction); + scaling = scaling_frame.second; + scaling = glm::vec3(1.0); + + break; + } - break; + //last_scaling_frame = scaling_frame; } - last_scaling_frame = scaling_frame; + this->nodes[channel.node_index].current_local_transform = glm::translate(glm::mat4(1.0f), position) * glm::toMat4(glm::make_quat(&rotation.w)) * glm::scale(glm::mat4(1.0f), scaling); } - this->nodes[channel.node_index].current_local_transform = glm::translate(glm::mat4(1.0f), position) * glm::toMat4(glm::make_quat(&rotation.w)) * glm::scale(glm::mat4(1.0f), scaling); + invalid = true; } - - invalid = true; } if (invalid) diff --git a/src/vr_application.cpp b/src/vr_application.cpp index 6722a9ad02bad0cb165c8a88bb6738e0dd6b5f68..496ce3a7f227ac2a05d6d09a2cb5c8b5784880d3 100644 --- a/src/vr_application.cpp +++ b/src/vr_application.cpp @@ -454,6 +454,7 @@ bool VRApplication::on_create() } this->frame_time = make_statistic("Frame Time", 128); + this->motion_tracking_time = make_statistic("Motion Tracking Time", 128); return this->create_config(); } @@ -595,6 +596,7 @@ bool VRApplication::on_interface() this->frame_capture->set_enabled(capture_enabled); this->frame_time->interface(); + this->motion_tracking_time->interface(); this->pass_timer->interface(); this->app->draw_about(true); @@ -663,9 +665,8 @@ bool VRApplication::on_update(lava::delta delta_time) if (this->scene->is_animation_active() && this->scene->is_camera_active()) { - this->stereo_transform->set_view_matrix(this->scene->get_animation_view_matrix()); + this->stereo_transform->set_view_matrix(this->headset->get_view_matrix() * glm::translate(glm::mat4(1.0), glm::vec3(0, -1.5, -5))); } - else { this->stereo_transform->set_view_matrix(this->headset->get_view_matrix()); diff --git a/src/vr_application.cpp.orig b/src/vr_application.cpp.orig new file mode 100644 index 0000000000000000000000000000000000000000..a1eb68761458440848d95586d52d12749e9d0c21 --- /dev/null +++ b/src/vr_application.cpp.orig @@ -0,0 +1,683 @@ +#include "vr_application.hpp" +#include <glm/gtx/matrix_operation.hpp> +#include <iostream> +#include <imgui.h> + +bool VRApplication::setup(lava::name name, argh::parser cmd_line) +{ + if (!this->command_parser.parse_command(cmd_line)) + { + return false; + } + + this->headset = make_headset(this, this->command_parser.get_headset()); + + if (this->headset == nullptr) + { + return false; + } + + this->strategies = make_all_stereo_strategies(this); + this->active_strategy = this->command_parser.get_stereo_strategy(); + + lava::frame_config config(name, std::forward<argh::parser>(cmd_line)); + config.log.debug = true; + config.debug.validation = false; + + if (!this->headset->on_setup_instance(config)) + { + std::cout << "Error during headset setup instance!" << std::endl; + + return false; + } + + for (StereoStrategy::Ptr strategy : this->strategies) + { + if (!strategy->on_setup_instance(config)) + { + std::cout << "Error during strategy setup instance!" << std::endl; + + return false; + } + } + + this->app.emplace(config); + this->app->shading.set_clear_enabled(false); + + this->app->manager.on_create_param = [this](lava::device::create_param& parameters) + { + if (!this->headset->on_setup_device(parameters)) + { + lava::log()->error("Error during headset setup device!"); + + this->app->shut_down(); + } + + for (StereoStrategy::Ptr strategy : this->strategies) + { + if (!strategy->on_setup_device(parameters)) + { + lava::log()->error("Error during strategy setup device!"); + + this->app->shut_down(); + } + } + + parameters.features.fillModeNonSolid = true; + parameters.features.multiViewport = true; + parameters.features.geometryShader = true; + parameters.features.tessellationShader = true; + parameters.features.imageCubeArray = true; + }; + + this->app->on_create = [this]() + { + if (!this->created) + { + this->created = true; + + if (!this->on_create()) + { + this->on_destroy(); + + return false; + } + } + + return true; + }; + + this->app->on_destroy = [this]() + { + this->on_destroy(); + }; + + this->app->window.on_resize = [this](uint32_t width, uint32_t height) + { + return this->on_resize(); + }; + + this->app->on_update = [this](lava::delta time_delta) + { + return this->on_update(time_delta); + }; + + this->app->on_update_tracking = [this](lava::delta time_delta) + { + return this->on_update_tracking(time_delta); + }; + + this->app->imgui.on_draw = [this]() + { + if (!this->on_interface()) + { + this->app->shut_down(); + } + }; + + this->app->on_process = [this](VkCommandBuffer command_buffer, lava::index frame) + { + if (!this->on_render(command_buffer, frame)) + { + this->app->shut_down(); + } + }; + + return this->app->setup(); +} + +void VRApplication::run() +{ + this->app->run(); +} + +Scene::Ptr VRApplication::get_scene() const +{ + return this->scene; +} + +Headset::Ptr VRApplication::get_headset() const +{ + return this->headset; +} + +StereoStrategy::Ptr VRApplication::get_stereo_strategy() const +{ + return this->strategies[this->active_strategy]; +} + +StereoStrategyType VRApplication::get_stereo_strategy_type() const +{ + return this->active_strategy; +} + +CompanionWindow::Ptr VRApplication::get_companion_window() const +{ + return this->companion_window; +} + +PassTimer::Ptr VRApplication::get_pass_timer() const +{ + return this->pass_timer; +} + +FrameCapture::Ptr VRApplication::get_frame_capture() const +{ + return this->frame_capture; +} + +StereoTransform::Ptr VRApplication::get_stereo_transform() const +{ + return this->stereo_transform; +} + +lava::device_ptr VRApplication::get_device() const +{ + return this->app->device; +} + +lava::render_target::ptr VRApplication::get_target() const +{ + return this->app->target; +} + +lava::instance& VRApplication::get_instance() +{ + return lava::instance::singleton(); +} + +lava::window& VRApplication::get_window() +{ + return this->app->window; +} + +lava::renderer& VRApplication::get_renderer() +{ + return this->app->renderer; +} + +lava::input& VRApplication::get_input() +{ + return this->app->input; +} + +lava::camera& VRApplication::get_camera() +{ + return this->app->camera; +} + +lava::index VRApplication::get_frame_index() const +{ + return this->app->renderer.get_frame(); +} + +uint32_t VRApplication::get_frame_count() const +{ + return this->app->target->get_frame_count(); +} + +bool VRApplication::create_config() +{ + if (!this->headset->on_create()) + { + lava::log()->error("Can't create headset!"); + + return false; + } + + StereoStrategy::Ptr strategy = this->get_stereo_strategy(); + + if (!strategy->on_create()) + { + lava::log()->error("Can't create strategy!"); + + return false; + } + + return true; +} + +bool VRApplication::change_config(StereoStrategyType strategy) +{ + this->app->device->wait_for_idle(); + + this->destroy_config(); + + this->active_strategy = strategy; + + return this->create_config(); +} + +void VRApplication::destroy_config() +{ + StereoStrategy::Ptr strategy = this->get_stereo_strategy(); + + if (strategy != nullptr) + { + strategy->on_destroy(); + } + + if (this->headset != nullptr) + { + this->headset->on_destroy(); + } +} + +void VRApplication::begin_render(VkCommandBuffer command_buffer, lava::index frame) +{ + lava::image::ptr window_image = this->app->target->get_backbuffer(frame); + + VkImageMemoryBarrier frame_barrier = lava::image_memory_barrier(window_image->get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + frame_barrier.srcAccessMask = 0; + frame_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + frame_barrier.subresourceRange = window_image->get_subresource_range(); + + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &frame_barrier); + + VkClearColorValue clear_value; + clear_value.float32[0] = 0.086f; + clear_value.float32[1] = 0.086f; + clear_value.float32[2] = 0.094f; + clear_value.float32[3] = 1.0f; + + vkCmdClearColorImage(command_buffer, window_image->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value, 1, &window_image->get_subresource_range()); +} + +void VRApplication::end_render(VkCommandBuffer command_buffer, lava::index frame) +{ + lava::image::ptr window_image = this->app->target->get_backbuffer(frame); + + VkImageMemoryBarrier frame_barrier = lava::image_memory_barrier(window_image->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL); + frame_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + frame_barrier.dstAccessMask = 0; + frame_barrier.subresourceRange = window_image->get_subresource_range(); + + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &frame_barrier); +} + +bool VRApplication::on_create() +{ + lava::file_system::mount(std::string(RESOURCE_FOLDER)); //NOTE: Set absolut path for the resource folder so that also in release all resources can be found. + + SceneConfig config; + config.scene_file = this->command_parser.get_scene_path(); + config.scene_unit = this->command_parser.get_scene_unit(); + config.scene_orientation = SCENE_ORIENTATION_RIGHT_HANDED; + + if (this->command_parser.get_sky_sphere_path().has_value()) + { + config.sky_sphere_file = this->command_parser.get_sky_sphere_path().value(); + } + + if (!this->command_parser.should_benchmark()) + { + config.controller_left_file = std::string(RESOURCE_FOLDER) + "/dpr-controller/ObjModelViveFocus3ControllerLeft.fbx"; + config.controller_left_unit = SCENE_UNIT_CENTIMETERS; + + config.controller_right_file = std::string(RESOURCE_FOLDER) + "/dpr-controller/ObjModelViveFocus3ControllerRight.fbx"; + config.controller_right_unit = SCENE_UNIT_CENTIMETERS; + } + + this->scene = make_scene(); + + if (!this->scene->create(config, this->app->device, this->app->staging, this->get_frame_count())) + { + return false; + } + + if (this->command_parser.should_benchmark()) + { + this->scene->set_animation_active(true); + this->scene->set_animation_loop(false); + + if (this->command_parser.get_animation_name().has_value()) + { + if (!this->scene->set_animation(this->command_parser.get_animation_name().value())) + { + lava::log()->error("Can't find animation with name '{}' !", this->command_parser.get_animation_name().value()); + + return false; + } + } + + else if (this->command_parser.get_animation_index().has_value()) + { + if (!this->scene->set_animation(this->command_parser.get_animation_index().value())) + { + lava::log()->error("Can't find animation with index '{}' !", this->command_parser.get_animation_index().value()); + + return false; + } + } + + else + { + lava::log()->error("No animation selected for benchmark!"); + + return false; + } + + if (this->command_parser.get_camera_name().has_value()) + { + if (!this->scene->set_camera(this->command_parser.get_camera_name().value())) + { + lava::log()->error("Can't find camera with name '{}' !", this->command_parser.get_camera_name().value()); + + return false; + } + } + + else if (this->command_parser.get_camera_index().has_value()) + { + if (!this->scene->set_camera(this->command_parser.get_camera_index().value())) + { + lava::log()->error("Can't find camera with index '{}' !", this->command_parser.get_camera_index().value()); + + return false; + } + } + + else + { + lava::log()->error("No camera selected for benchmark!"); + + return false; + } + } + + this->companion_window = make_companion_window(); + this->companion_window->set_enabled(this->command_parser.should_show_companion_window()); + + if (!this->companion_window->create(this->app->device, this->app->target)) + { + lava::log()->error("Can't create companion window!"); + + return false; + } + + this->frame_capture = make_frame_capture("captures"); + this->frame_capture->set_enabled(this->command_parser.should_write_frames()); + + if (!this->frame_capture->create(this->get_frame_count())) + { + lava::log()->error("Can't create frame capture!"); + + return false; + } + + this->pass_timer = make_pass_timer("statistics"); + + if (!this->pass_timer->create(this->app->device, this->get_frame_count(), 10)) + { + lava::log()->error("Can't create pass timer!"); + + return false; + } + + this->stereo_transform = make_stereo_transform(); + + if (!this->stereo_transform->create(this->app->device, this->get_frame_count())) + { + lava::log()->error("Can't create stereo transform!"); + + return false; + } + + this->frame_time = make_statistic("Frame Time", 128); + + return this->create_config(); +} + +void VRApplication::on_destroy() +{ + this->destroy_config(); + + if (this->pass_timer != nullptr) + { + this->pass_timer->write_to_file(this->app->device); + this->pass_timer->destroy(this->app->device); + } + + if (this->stereo_transform != nullptr) + { + this->stereo_transform->destroy(); + } + + if (this->frame_capture != nullptr) + { + this->frame_capture->destroy(); + } + + if (this->companion_window != nullptr) + { + this->companion_window->destroy(); + } + + if (this->scene != nullptr) + { + this->scene->destroy(); + } +} + +bool VRApplication::on_resize() +{ + this->companion_window->destroy(); + + if (!this->companion_window->create(this->app->device, this->app->target)) + { + lava::log()->error("Can't resize companion window!"); + + return false; + } + + return true; +} + +bool VRApplication::on_interface() +{ + if (this->command_parser.should_benchmark()) + { + return true; + } + + ImGui::SetNextWindowPos(ImVec2(30, 30), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(193, 90), ImGuiCond_FirstUseEver); + + ImGui::Begin("Application"); + + if (ImGui::CollapsingHeader("Scene", ImGuiTreeNodeFlags_DefaultOpen)) + { + if (!this->scene->interface()) + { + lava::log()->error("Error during scene interface!"); + ImGui::End(); + + return false; + } + } + + if (ImGui::CollapsingHeader("Headset", ImGuiTreeNodeFlags_DefaultOpen)) + { + if (!this->headset->on_interface()) + { + lava::log()->error("Error during headset interface!"); + ImGui::End(); + + return false; + } + } + + if (ImGui::CollapsingHeader("Strategy", ImGuiTreeNodeFlags_DefaultOpen)) + { + std::vector<const char*> strategy_names; + + for (StereoStrategy::Ptr strategy : this->strategies) + { + strategy_names.push_back(strategy->get_name()); + } + + int32_t strategy = this->active_strategy; + + if (ImGui::Combo("Stereo Strategy", &strategy, strategy_names.data(), strategy_names.size())) + { + this->selected_strategy = (StereoStrategyType) strategy; + } + + if (!this->get_stereo_strategy()->on_interface()) + { + lava::log()->error("Error during strategy interface!"); + ImGui::End(); + + return false; + } + } + + if (ImGui::CollapsingHeader("Frame rate")) + { + ImGui::InputInt("Max frame rate", &this->app->max_fps); + ImGui::InputInt("Max motion tracking rate", &this->app->max_tracking_rate); + ImGui::InputInt("Sync frame rate", &this->app->sync_fps); + } + + if (ImGui::CollapsingHeader("Debug")) + { + bool companion_enabled = this->companion_window->is_enabled(); + ImGui::Checkbox("Companion Window", &companion_enabled); + this->companion_window->set_enabled(companion_enabled); + + bool capture_enabled = this->frame_capture->is_enabled(); + ImGui::Checkbox("Frame Capture", &capture_enabled); + this->frame_capture->set_enabled(capture_enabled); + + this->frame_time->interface(); + this->pass_timer->interface(); + + this->app->draw_about(true); + } + + ImGui::End(); + + return true; +} + +bool VRApplication::on_update(lava::delta delta_time) +{ + this->frame_time->add_sample(delta_time * 1000.0); + + if (this->selected_strategy.has_value()) + { + if (!this->change_config(this->selected_strategy.value())) + { + return false; + } + + this->selected_strategy.reset(); + } + + // TODO: Place the headset update before the scene update for lower latency. + // However this would cause the controller transformation to be delayed by one frame. + if (!this->headset->on_update(delta_time)) + { + lava::log()->error("Error during headset update!"); + + return false; + } + + if (this->command_parser.should_benchmark()) + { + float time_step = 1.0f / this->command_parser.get_update_rate().value(); + + if (!this->scene->update(time_step, this->headset)) + { + lava::log()->error("Error during scene update!"); + + return false; + } + + if (this->scene->is_animation_complete()) + { + return false; + } + } + + else + { + if (!this->scene->update(delta_time, this->headset)) + { + lava::log()->error("Error during scene update!"); + + return false; + } + } + +<<<<<<< HEAD +#if 0 + if (!this->headset->on_update(delta_time)) + { + lava::log()->error("Error during headset update!"); + + return false; + } +#endif + +======= +>>>>>>> 74bf4a76084e0a7879f0671a4eb1fe97bed604ae + this->stereo_transform->set_head_to_eye_matrix(EYE_LEFT, this->headset->get_head_to_eye_matrix(EYE_LEFT)); + this->stereo_transform->set_head_to_eye_matrix(EYE_RIGHT, this->headset->get_head_to_eye_matrix(EYE_RIGHT)); + + this->stereo_transform->set_projection_matrix(EYE_LEFT, this->headset->get_projection_matrix(EYE_LEFT)); + this->stereo_transform->set_projection_matrix(EYE_RIGHT, this->headset->get_projection_matrix(EYE_RIGHT)); + + if (this->scene->is_animation_active()) + { + this->stereo_transform->set_view_matrix(this->scene->get_animation_view_matrix()); + } + + else + { + this->stereo_transform->set_view_matrix(this->headset->get_view_matrix()); + } + + StereoStrategy::Ptr strategy = this->get_stereo_strategy(); + + if (!strategy->on_update(delta_time)) + { + lava::log()->error("Error during strategy update!"); + + return false; + } + + return true; +} + +bool VRApplication::on_update_tracking(lava::delta delta_time) +{ + // std::cout << "TRACKING " << delta_time << std::endl; + return this->headset->on_update(delta_time); +} + +bool VRApplication::on_render(VkCommandBuffer command_buffer, lava::index frame) +{ + this->frame_capture->next_frame(frame); + this->pass_timer->next_frame(command_buffer, frame, app->device); + + this->scene->write(frame); + this->stereo_transform->write(frame); + + this->begin_render(command_buffer, frame); + + StereoStrategy::Ptr strategy = this->get_stereo_strategy(); + + if (!strategy->on_render(command_buffer, frame)) + { + lava::log()->error("Error during strategy render!"); + + return false; + } + + this->companion_window->render(command_buffer, this->app->target, this->get_frame_index()); + + this->end_render(command_buffer, frame); + + return true; +} \ No newline at end of file diff --git a/src/vr_application.hpp b/src/vr_application.hpp index 52c1e8237ced44db5872f8b20c90acfc9f18210d..8eb61773a77c9419fb79841e9d92c7603ab7124a 100644 --- a/src/vr_application.hpp +++ b/src/vr_application.hpp @@ -60,6 +60,8 @@ public: std::optional<lava::app>& get_app() { return this->app; } + Statistic::Ptr get_motion_tracking_time() { return this->motion_tracking_time; } + private: bool create_config(); bool change_config(StereoStrategyType strategy); @@ -99,4 +101,5 @@ private: bool created = false; Statistic::Ptr frame_time; + Statistic::Ptr motion_tracking_time; }; \ No newline at end of file