Commit 6e4b5ecb authored by Brandon Jones's avatar Brandon Jones Committed by Commit Bot

Support display of multiple controllers in VRShell

Updates the VR UI model to allow an array of controllers, each of which
will be rendered as part of the UI. This update introduces a concept of
a "primary controller" (largely for porting convenience) that is
currently always the controller at index 0 of the array. We may want to
improve the logic around that in future CLs.

Bug: 873274
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:linux_vr;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I1a91f6550f4d051d35d872118c822f1b6716c614
Reviewed-on: https://chromium-review.googlesource.com/c/1171519
Commit-Queue: Brandon Jones <bajones@chromium.org>
Reviewed-by: default avatarChristopher Grant <cjgrant@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612778}
parent 02a45d5f
...@@ -317,7 +317,9 @@ base::TimeDelta BrowserRenderer::ProcessControllerInput( ...@@ -317,7 +317,9 @@ base::TimeDelta BrowserRenderer::ProcessControllerInput(
input_delegate_->GetControllerModel(render_info.head_pose); input_delegate_->GetControllerModel(render_info.head_pose);
ui_->HandleInput(current_time, render_info, controller_model, &reticle_model, ui_->HandleInput(current_time, render_info, controller_model, &reticle_model,
&input_event_list); &input_event_list);
ui_->OnControllerUpdated(controller_model, reticle_model); std::vector<ControllerModel> controller_models;
controller_models.push_back(controller_model);
ui_->OnControllersUpdated(controller_models, reticle_model);
auto controller_time = base::TimeTicks::Now() - timing_start; auto controller_time = base::TimeTicks::Now() - timing_start;
ui_controller_update_time_.AddSample(controller_time); ui_controller_update_time_.AddSample(controller_time);
......
...@@ -37,7 +37,7 @@ class MockUi : public UiInterface { ...@@ -37,7 +37,7 @@ class MockUi : public UiInterface {
MOCK_METHOD4(SetContentOverlayAlertDialogEnabled, MOCK_METHOD4(SetContentOverlayAlertDialogEnabled,
void(bool, PlatformUiInputDelegate*, float, float)); void(bool, PlatformUiInputDelegate*, float, float));
MOCK_METHOD0(OnPause, void()); MOCK_METHOD0(OnPause, void());
void OnControllerUpdated(const ControllerModel&, void OnControllersUpdated(const std::vector<ControllerModel>&,
const ReticleModel&) override {} const ReticleModel&) override {}
void OnProjMatrixChanged(const gfx::Transform&) override {} void OnProjMatrixChanged(const gfx::Transform&) override {}
MOCK_METHOD0(AcceptDoffPromptForTesting, void()); MOCK_METHOD0(AcceptDoffPromptForTesting, void());
......
...@@ -73,7 +73,7 @@ void Laser::Render(UiElementRenderer* renderer, ...@@ -73,7 +73,7 @@ void Laser::Render(UiElementRenderer* renderer,
const CameraModel& model) const { const CameraModel& model) const {
// Find the length of the beam (from hand to target). // Find the length of the beam (from hand to target).
const float laser_length = const float laser_length =
std::sqrt(model_->controller.laser_origin.SquaredDistanceTo( std::sqrt(model_->primary_controller().laser_origin.SquaredDistanceTo(
model_->reticle.target_point)); model_->reticle.target_point));
// Build a beam, originating from the origin. // Build a beam, originating from the origin.
...@@ -90,7 +90,7 @@ void Laser::Render(UiElementRenderer* renderer, ...@@ -90,7 +90,7 @@ void Laser::Render(UiElementRenderer* renderer,
mat = rotation_mat * mat; mat = rotation_mat * mat;
const gfx::Vector3dF beam_direction = const gfx::Vector3dF beam_direction =
model_->reticle.target_point - model_->controller.laser_origin; model_->reticle.target_point - model_->primary_controller().laser_origin;
gfx::Transform beam_direction_mat( gfx::Transform beam_direction_mat(
gfx::Quaternion(gfx::Vector3dF(0.0f, 0.0f, -1.0f), beam_direction)); gfx::Quaternion(gfx::Vector3dF(0.0f, 0.0f, -1.0f), beam_direction));
...@@ -106,9 +106,10 @@ void Laser::Render(UiElementRenderer* renderer, ...@@ -106,9 +106,10 @@ void Laser::Render(UiElementRenderer* renderer,
face_transform = beam_direction_mat * gfx::Transform(rot) * mat; face_transform = beam_direction_mat * gfx::Transform(rot) * mat;
// Move the beam origin to the hand. // Move the beam origin to the hand.
face_transform.matrix().postTranslate(model_->controller.laser_origin.x(), face_transform.matrix().postTranslate(
model_->controller.laser_origin.y(), model_->primary_controller().laser_origin.x(),
model_->controller.laser_origin.z()); model_->primary_controller().laser_origin.y(),
model_->primary_controller().laser_origin.z());
transform = transform =
model.view_proj_matrix * world_space_transform() * face_transform; model.view_proj_matrix * world_space_transform() * face_transform;
renderer->DrawLaser(computed_opacity(), transform); renderer->DrawLaser(computed_opacity(), transform);
......
...@@ -125,4 +125,12 @@ bool Model::reposition_window_permitted() const { ...@@ -125,4 +125,12 @@ bool Model::reposition_window_permitted() const {
!hosted_platform_ui.hosted_ui_enabled; !hosted_platform_ui.hosted_ui_enabled;
} }
const ControllerModel& Model::primary_controller() const {
return controllers[0];
}
ControllerModel& Model::mutable_primary_controller() {
return controllers[0];
}
} // namespace vr } // namespace vr
...@@ -89,7 +89,9 @@ struct VR_UI_EXPORT Model { ...@@ -89,7 +89,9 @@ struct VR_UI_EXPORT Model {
EditedText web_input_text_field_info; EditedText web_input_text_field_info;
// Controller state. // Controller state.
ControllerModel controller; const ControllerModel& primary_controller() const;
ControllerModel& mutable_primary_controller(); // For tests
std::vector<ControllerModel> controllers;
ReticleModel reticle; ReticleModel reticle;
// State affecting both VR browsing and WebVR. // State affecting both VR browsing and WebVR.
......
...@@ -80,7 +80,9 @@ void UiPixelTest::DrawUi(const gfx::Vector3dF& laser_direction, ...@@ -80,7 +80,9 @@ void UiPixelTest::DrawUi(const gfx::Vector3dF& laser_direction,
EXPECT_TRUE(ui_->OnBeginFrame(base::TimeTicks(), render_info.head_pose)); EXPECT_TRUE(ui_->OnBeginFrame(base::TimeTicks(), render_info.head_pose));
ui_->HandleInput(MsToTicks(1), render_info, controller_model, &reticle_model, ui_->HandleInput(MsToTicks(1), render_info, controller_model, &reticle_model,
&input_event_list); &input_event_list);
ui_->OnControllerUpdated(controller_model, reticle_model); std::vector<ControllerModel> controllers;
controllers.push_back(controller_model);
ui_->OnControllersUpdated(controllers, reticle_model);
ui_->Draw(render_info); ui_->Draw(render_info);
// We produce GL errors while rendering. Clear them all so that we can check // We produce GL errors while rendering. Clear them all so that we can check
......
...@@ -86,9 +86,12 @@ void UiTest::CreateSceneInternal( ...@@ -86,9 +86,12 @@ void UiTest::CreateSceneInternal(
ui_ = ui_instance_.get(); ui_ = ui_instance_.get();
scene_ = ui_instance_->scene(); scene_ = ui_instance_->scene();
model_ = ui_instance_->model_for_test(); model_ = ui_instance_->model_for_test();
model_->controller.transform.Translate3d(kStartControllerPosition); model_->controllers[0].transform.Translate3d(kStartControllerPosition);
OnBeginFrame(); OnBeginFrame();
// Need a second BeginFrame here because the first one will add controllers
// to the scene, which need an additional frame to get into a good state.
OnBeginFrame();
} }
void UiTest::CreateScene(const UiInitialState& state) { void UiTest::CreateScene(const UiInitialState& state) {
......
...@@ -453,7 +453,9 @@ ControllerModel VrTestContext::UpdateController(const RenderInfo& render_info, ...@@ -453,7 +453,9 @@ ControllerModel VrTestContext::UpdateController(const RenderInfo& render_info,
controller_model.laser_origin = laser_origin + local_offset; controller_model.laser_origin = laser_origin + local_offset;
controller_model.handedness = handedness_; controller_model.handedness = handedness_;
ui_->OnControllerUpdated(controller_model, reticle_model); std::vector<ControllerModel> controllers;
controllers.push_back(controller_model);
ui_->OnControllersUpdated(controllers, reticle_model);
return controller_model; return controller_model;
} }
......
...@@ -440,12 +440,15 @@ void Ui::OnMenuButtonClicked() { ...@@ -440,12 +440,15 @@ void Ui::OnMenuButtonClicked() {
} }
} }
void Ui::OnControllerUpdated(const ControllerModel& controller_model, void Ui::OnControllersUpdated(
const std::vector<ControllerModel>& controller_models,
const ReticleModel& reticle_model) { const ReticleModel& reticle_model) {
model_->controller = controller_model; model_->controllers = controller_models;
model_->reticle = reticle_model; model_->reticle = reticle_model;
model_->controller.resting_in_viewport = for (auto& controller : model_->controllers) {
controller.resting_in_viewport =
input_manager_->ControllerRestingInViewport(); input_manager_->ControllerRestingInViewport();
}
} }
void Ui::OnProjMatrixChanged(const gfx::Transform& proj_matrix) { void Ui::OnProjMatrixChanged(const gfx::Transform& proj_matrix) {
...@@ -591,6 +594,7 @@ void Ui::InitializeModel(const UiInitialState& ui_initial_state) { ...@@ -591,6 +594,7 @@ void Ui::InitializeModel(const UiInitialState& ui_initial_state) {
model_->standalone_vr_device = ui_initial_state.is_standalone_vr_device; model_->standalone_vr_device = ui_initial_state.is_standalone_vr_device;
model_->use_new_incognito_strings = model_->use_new_incognito_strings =
ui_initial_state.use_new_incognito_strings; ui_initial_state.use_new_incognito_strings;
model_->controllers.push_back(ControllerModel());
} }
void Ui::AcceptDoffPromptForTesting() { void Ui::AcceptDoffPromptForTesting() {
......
...@@ -144,7 +144,8 @@ class VR_UI_EXPORT Ui : public UiInterface, ...@@ -144,7 +144,8 @@ class VR_UI_EXPORT Ui : public UiInterface,
void CancelPlatformToast() override; void CancelPlatformToast() override;
void OnPause() override; void OnPause() override;
void OnControllerUpdated(const ControllerModel& controller_model, void OnControllersUpdated(
const std::vector<ControllerModel>& controller_models,
const ReticleModel& reticle_model) override; const ReticleModel& reticle_model) override;
void OnProjMatrixChanged(const gfx::Transform& proj_matrix) override; void OnProjMatrixChanged(const gfx::Transform& proj_matrix) override;
void OnSwapContents(int new_content_id) override; void OnSwapContents(int new_content_id) override;
......
...@@ -601,9 +601,12 @@ TEST_F(UiInputManagerContentTest, ControllerRestingInViewport) { ...@@ -601,9 +601,12 @@ TEST_F(UiInputManagerContentTest, ControllerRestingInViewport) {
// The controller is initially not in the viewport. // The controller is initially not in the viewport.
EXPECT_FALSE(input_manager_->ControllerRestingInViewport()); EXPECT_FALSE(input_manager_->ControllerRestingInViewport());
std::vector<ControllerModel> controllers;
input_manager_->HandleInput(MsToTicks(1), render_info, controller_model, input_manager_->HandleInput(MsToTicks(1), render_info, controller_model,
&reticle_model, &input_event_list); &reticle_model, &input_event_list);
ui_->OnControllerUpdated(controller_model, reticle_model); controllers.push_back(controller_model);
ui_->OnControllersUpdated(controllers, reticle_model);
scene_->OnBeginFrame(base::TimeTicks(), head_pose_); scene_->OnBeginFrame(base::TimeTicks(), head_pose_);
// Although we are currently looking at the controller, it is not focused yet. // Although we are currently looking at the controller, it is not focused yet.
...@@ -612,17 +615,19 @@ TEST_F(UiInputManagerContentTest, ControllerRestingInViewport) { ...@@ -612,17 +615,19 @@ TEST_F(UiInputManagerContentTest, ControllerRestingInViewport) {
input_manager_->HandleInput(MsToTicks(50000), render_info, controller_model, input_manager_->HandleInput(MsToTicks(50000), render_info, controller_model,
&reticle_model, &input_event_list); &reticle_model, &input_event_list);
ui_->OnControllerUpdated(controller_model, reticle_model); controllers[0] = controller_model;
ui_->OnControllersUpdated(controllers, reticle_model);
scene_->OnBeginFrame(base::TimeTicks(), head_pose_); scene_->OnBeginFrame(base::TimeTicks(), head_pose_);
// Since the controller has been in the viewport for a long time (50s), it // Since the controller has been in the viewport for a long time (50s), it
// must report that it is focused. // must report that it is focused.
EXPECT_TRUE(input_manager_->ControllerRestingInViewport()); EXPECT_TRUE(input_manager_->ControllerRestingInViewport());
ui_->OnControllerUpdated(controller_model, reticle_model); controllers[0] = controller_model;
ui_->OnControllersUpdated(controllers, reticle_model);
scene_->OnBeginFrame(base::TimeTicks(), head_pose_); scene_->OnBeginFrame(base::TimeTicks(), head_pose_);
EXPECT_TRUE(model_->controller.resting_in_viewport); EXPECT_TRUE(model_->controllers[0].resting_in_viewport);
EXPECT_TRUE(IsVisible(kControllerTrackpadLabel)); EXPECT_TRUE(IsVisible(kControllerTrackpadLabel));
} }
......
...@@ -63,7 +63,8 @@ class UiInterface { ...@@ -63,7 +63,8 @@ class UiInterface {
float width_percentage, float width_percentage,
float height_percentage) = 0; float height_percentage) = 0;
virtual void OnPause() = 0; virtual void OnPause() = 0;
virtual void OnControllerUpdated(const ControllerModel& controller_model, virtual void OnControllersUpdated(
const std::vector<ControllerModel>& controller_models,
const ReticleModel& reticle_model) = 0; const ReticleModel& reticle_model) = 0;
virtual void OnProjMatrixChanged(const gfx::Transform& proj_matrix) = 0; virtual void OnProjMatrixChanged(const gfx::Transform& proj_matrix) = 0;
virtual void AcceptDoffPromptForTesting() = 0; virtual void AcceptDoffPromptForTesting() = 0;
......
This diff is collapsed.
...@@ -54,7 +54,7 @@ class UiSceneCreator { ...@@ -54,7 +54,7 @@ class UiSceneCreator {
void CreateWebVrSubtree(); void CreateWebVrSubtree();
void CreateWebVrOverlayElements(); void CreateWebVrOverlayElements();
void CreateWebVrTimeoutScreen(); void CreateWebVrTimeoutScreen();
void CreateController(); void CreateControllers();
void CreateKeyboard(); void CreateKeyboard();
void Create2dBrowsingHostedUi(); void Create2dBrowsingHostedUi();
void CreateExternalPromptNotifcationOverlay(); void CreateExternalPromptNotifcationOverlay();
......
...@@ -1068,7 +1068,7 @@ TEST_F(UiTest, ControllerLabels) { ...@@ -1068,7 +1068,7 @@ TEST_F(UiTest, ControllerLabels) {
EXPECT_FALSE(IsVisible(kControllerExitButtonLabel)); EXPECT_FALSE(IsVisible(kControllerExitButtonLabel));
EXPECT_FALSE(IsVisible(kControllerBackButtonLabel)); EXPECT_FALSE(IsVisible(kControllerBackButtonLabel));
model_->controller.resting_in_viewport = true; model_->mutable_primary_controller().resting_in_viewport = true;
EXPECT_TRUE(IsVisible(kControllerTrackpadLabel)); EXPECT_TRUE(IsVisible(kControllerTrackpadLabel));
EXPECT_FALSE(IsVisible(kControllerTrackpadRepositionLabel)); EXPECT_FALSE(IsVisible(kControllerTrackpadRepositionLabel));
EXPECT_FALSE(IsVisible(kControllerExitButtonLabel)); EXPECT_FALSE(IsVisible(kControllerExitButtonLabel));
...@@ -1111,13 +1111,13 @@ TEST_F(UiTest, ControllerLabels) { ...@@ -1111,13 +1111,13 @@ TEST_F(UiTest, ControllerLabels) {
EXPECT_FALSE(IsVisible(kControllerBackButtonLabel)); EXPECT_FALSE(IsVisible(kControllerBackButtonLabel));
model_->push_mode(kModeRepositionWindow); model_->push_mode(kModeRepositionWindow);
model_->controller.laser_direction = kForwardVector; model_->mutable_primary_controller().laser_direction = kForwardVector;
EXPECT_FALSE(IsVisible(kControllerTrackpadLabel)); EXPECT_FALSE(IsVisible(kControllerTrackpadLabel));
EXPECT_TRUE(IsVisible(kControllerTrackpadRepositionLabel)); EXPECT_TRUE(IsVisible(kControllerTrackpadRepositionLabel));
EXPECT_FALSE(IsVisible(kControllerExitButtonLabel)); EXPECT_FALSE(IsVisible(kControllerExitButtonLabel));
EXPECT_TRUE(IsVisible(kControllerRepositionFinishLabel)); EXPECT_TRUE(IsVisible(kControllerRepositionFinishLabel));
model_->controller.resting_in_viewport = false; model_->mutable_primary_controller().resting_in_viewport = false;
EXPECT_FALSE(IsVisible(kControllerTrackpadRepositionLabel)); EXPECT_FALSE(IsVisible(kControllerTrackpadRepositionLabel));
EXPECT_FALSE(IsVisible(kControllerTrackpadLabel)); EXPECT_FALSE(IsVisible(kControllerTrackpadLabel));
EXPECT_FALSE(IsVisible(kControllerExitButtonLabel)); EXPECT_FALSE(IsVisible(kControllerExitButtonLabel));
...@@ -1140,7 +1140,7 @@ TEST_F(UiTest, ControllerBatteryIndicator) { ...@@ -1140,7 +1140,7 @@ TEST_F(UiTest, ControllerBatteryIndicator) {
ColorScheme scheme = model_->color_scheme(); ColorScheme scheme = model_->color_scheme();
model_->controller.battery_level = 5; model_->mutable_primary_controller().battery_level = 5;
RunForMs(kAnimationTimeMs); RunForMs(kAnimationTimeMs);
EXPECT_EQ(dot_0->center_color(), scheme.controller_battery_full); EXPECT_EQ(dot_0->center_color(), scheme.controller_battery_full);
EXPECT_EQ(dot_1->center_color(), scheme.controller_battery_full); EXPECT_EQ(dot_1->center_color(), scheme.controller_battery_full);
...@@ -1148,7 +1148,7 @@ TEST_F(UiTest, ControllerBatteryIndicator) { ...@@ -1148,7 +1148,7 @@ TEST_F(UiTest, ControllerBatteryIndicator) {
EXPECT_EQ(dot_3->center_color(), scheme.controller_battery_full); EXPECT_EQ(dot_3->center_color(), scheme.controller_battery_full);
EXPECT_EQ(dot_4->center_color(), scheme.controller_battery_full); EXPECT_EQ(dot_4->center_color(), scheme.controller_battery_full);
model_->controller.battery_level = 4; model_->mutable_primary_controller().battery_level = 4;
RunForMs(kAnimationTimeMs); RunForMs(kAnimationTimeMs);
EXPECT_EQ(dot_0->center_color(), scheme.controller_battery_full); EXPECT_EQ(dot_0->center_color(), scheme.controller_battery_full);
EXPECT_EQ(dot_1->center_color(), scheme.controller_battery_full); EXPECT_EQ(dot_1->center_color(), scheme.controller_battery_full);
...@@ -1156,7 +1156,7 @@ TEST_F(UiTest, ControllerBatteryIndicator) { ...@@ -1156,7 +1156,7 @@ TEST_F(UiTest, ControllerBatteryIndicator) {
EXPECT_EQ(dot_3->center_color(), scheme.controller_battery_full); EXPECT_EQ(dot_3->center_color(), scheme.controller_battery_full);
EXPECT_EQ(dot_4->center_color(), scheme.controller_battery_empty); EXPECT_EQ(dot_4->center_color(), scheme.controller_battery_empty);
model_->controller.battery_level = 3; model_->mutable_primary_controller().battery_level = 3;
RunForMs(kAnimationTimeMs); RunForMs(kAnimationTimeMs);
EXPECT_EQ(dot_0->center_color(), scheme.controller_battery_full); EXPECT_EQ(dot_0->center_color(), scheme.controller_battery_full);
EXPECT_EQ(dot_1->center_color(), scheme.controller_battery_full); EXPECT_EQ(dot_1->center_color(), scheme.controller_battery_full);
...@@ -1164,7 +1164,7 @@ TEST_F(UiTest, ControllerBatteryIndicator) { ...@@ -1164,7 +1164,7 @@ TEST_F(UiTest, ControllerBatteryIndicator) {
EXPECT_EQ(dot_3->center_color(), scheme.controller_battery_empty); EXPECT_EQ(dot_3->center_color(), scheme.controller_battery_empty);
EXPECT_EQ(dot_4->center_color(), scheme.controller_battery_empty); EXPECT_EQ(dot_4->center_color(), scheme.controller_battery_empty);
model_->controller.battery_level = 2; model_->mutable_primary_controller().battery_level = 2;
RunForMs(kAnimationTimeMs); RunForMs(kAnimationTimeMs);
EXPECT_EQ(dot_0->center_color(), scheme.controller_battery_full); EXPECT_EQ(dot_0->center_color(), scheme.controller_battery_full);
EXPECT_EQ(dot_1->center_color(), scheme.controller_battery_full); EXPECT_EQ(dot_1->center_color(), scheme.controller_battery_full);
...@@ -1172,7 +1172,7 @@ TEST_F(UiTest, ControllerBatteryIndicator) { ...@@ -1172,7 +1172,7 @@ TEST_F(UiTest, ControllerBatteryIndicator) {
EXPECT_EQ(dot_3->center_color(), scheme.controller_battery_empty); EXPECT_EQ(dot_3->center_color(), scheme.controller_battery_empty);
EXPECT_EQ(dot_4->center_color(), scheme.controller_battery_empty); EXPECT_EQ(dot_4->center_color(), scheme.controller_battery_empty);
model_->controller.battery_level = 1; model_->mutable_primary_controller().battery_level = 1;
RunForMs(kAnimationTimeMs); RunForMs(kAnimationTimeMs);
EXPECT_EQ(dot_0->center_color(), scheme.controller_battery_full); EXPECT_EQ(dot_0->center_color(), scheme.controller_battery_full);
EXPECT_EQ(dot_1->center_color(), scheme.controller_battery_empty); EXPECT_EQ(dot_1->center_color(), scheme.controller_battery_empty);
...@@ -1180,7 +1180,7 @@ TEST_F(UiTest, ControllerBatteryIndicator) { ...@@ -1180,7 +1180,7 @@ TEST_F(UiTest, ControllerBatteryIndicator) {
EXPECT_EQ(dot_3->center_color(), scheme.controller_battery_empty); EXPECT_EQ(dot_3->center_color(), scheme.controller_battery_empty);
EXPECT_EQ(dot_4->center_color(), scheme.controller_battery_empty); EXPECT_EQ(dot_4->center_color(), scheme.controller_battery_empty);
model_->controller.battery_level = 0; model_->mutable_primary_controller().battery_level = 0;
RunForMs(kAnimationTimeMs); RunForMs(kAnimationTimeMs);
EXPECT_EQ(dot_0->center_color(), scheme.controller_battery_empty); EXPECT_EQ(dot_0->center_color(), scheme.controller_battery_empty);
EXPECT_EQ(dot_1->center_color(), scheme.controller_battery_empty); EXPECT_EQ(dot_1->center_color(), scheme.controller_battery_empty);
...@@ -1206,7 +1206,7 @@ TEST_F(UiTest, ResetRepositioner) { ...@@ -1206,7 +1206,7 @@ TEST_F(UiTest, ResetRepositioner) {
EXPECT_NE(original, repositioner->world_space_transform()); EXPECT_NE(original, repositioner->world_space_transform());
repositioner->SetEnabled(false); repositioner->SetEnabled(false);
model_->controller.recentered = true; model_->mutable_primary_controller().recentered = true;
OnBeginFrame(); OnBeginFrame();
EXPECT_EQ(original, repositioner->world_space_transform()); EXPECT_EQ(original, repositioner->world_space_transform());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment