Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/android/vr_shell/vr_shell.h" | 5 #include "chrome/browser/android/vr_shell/vr_shell.h" |
| 6 | 6 |
| 7 #include <thread> | 7 #include <thread> |
| 8 | 8 |
| 9 #include "chrome/browser/android/vr_shell/ui_scene.h" | 9 #include "chrome/browser/android/vr_shell/ui_scene.h" |
| 10 #include "chrome/browser/android/vr_shell/vr_compositor.h" | 10 #include "chrome/browser/android/vr_shell/vr_compositor.h" |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 135 const JavaParamRef<jobject>& obj, | 135 const JavaParamRef<jobject>& obj, |
| 136 jint texture_data_handle) { | 136 jint texture_data_handle) { |
| 137 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || | 137 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || |
| 138 gl::init::InitializeGLOneOff()); | 138 gl::init::InitializeGLOneOff()); |
| 139 | 139 |
| 140 content_texture_id_ = texture_data_handle; | 140 content_texture_id_ = texture_data_handle; |
| 141 gvr_api_->InitializeGl(); | 141 gvr_api_->InitializeGl(); |
| 142 std::vector<gvr::BufferSpec> specs; | 142 std::vector<gvr::BufferSpec> specs; |
| 143 specs.push_back(gvr_api_->CreateBufferSpec()); | 143 specs.push_back(gvr_api_->CreateBufferSpec()); |
| 144 render_size_ = specs[0].GetSize(); | 144 render_size_ = specs[0].GetSize(); |
| 145 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapchain(specs))); | 145 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs))); |
| 146 | 146 |
| 147 vr_shell_renderer_.reset(new VrShellRenderer()); | 147 vr_shell_renderer_.reset(new VrShellRenderer()); |
| 148 buffer_viewport_list_.reset( | 148 buffer_viewport_list_.reset( |
| 149 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); | 149 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); |
| 150 buffer_viewport_.reset( | 150 buffer_viewport_.reset( |
| 151 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 151 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
| 152 } | 152 } |
| 153 | 153 |
| 154 void VrShell::UpdateController() { | 154 void VrShell::UpdateController() { |
| 155 if (!controller_active_) { | 155 if (!controller_active_) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 216 closest_element_index = i; | 216 closest_element_index = i; |
| 217 pixel_x = int((plane.copy_rect.width * x) + plane.copy_rect.x); | 217 pixel_x = int((plane.copy_rect.width * x) + plane.copy_rect.x); |
| 218 pixel_y = int((plane.copy_rect.height * y) + plane.copy_rect.y); | 218 pixel_y = int((plane.copy_rect.height * y) + plane.copy_rect.y); |
| 219 look_at_vector_ = plane_intersection_point; | 219 look_at_vector_ = plane_intersection_point; |
| 220 } | 220 } |
| 221 } | 221 } |
| 222 } | 222 } |
| 223 // TODO(mthiesse): Create input events for CVC using pixel_x/y. | 223 // TODO(mthiesse): Create input events for CVC using pixel_x/y. |
| 224 } | 224 } |
| 225 | 225 |
| 226 void ApplyNeckModel(gvr::Mat4f& mat_forward) { | |
| 227 // This assumes that the input matrix is a pure rotation matrix. The | |
| 228 // input object_from_reference matrix has the inverse rotation of | |
| 229 // the head rotation. Invert it (this is just a transpose). | |
| 230 gvr::Mat4f mat = MatrixTranspose(mat_forward); | |
| 231 | |
| 232 // Position of the point between the eyes, relative to the neck pivot: | |
| 233 const float kNeckHorizontalOffset = -0.080f; // meters in Z | |
| 234 const float kNeckVerticalOffset = 0.075f; // meters in Y | |
| 235 | |
| 236 std::array<float, 4> neckOffset = { | |
| 237 {0.0f, kNeckVerticalOffset, kNeckHorizontalOffset, 1.0f}}; | |
| 238 | |
| 239 // Rotate eyes around neck pivot point. | |
| 240 auto offset = MatrixVectorMul(mat, neckOffset); | |
| 241 | |
| 242 // Measure new position relative to original center of head, because | |
| 243 // applying a neck model should not elevate the camera. | |
| 244 offset[1] -= kNeckVerticalOffset; | |
| 245 | |
| 246 // Right-multiply the inverse translation onto the | |
| 247 // object_from_reference_matrix. | |
| 248 TranslateMRight(mat_forward, mat_forward, -offset[0], -offset[1], -offset[2]); | |
| 249 } | |
| 250 | |
| 251 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 226 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| 252 buffer_viewport_list_->SetToRecommendedBufferViewports(); | 227 buffer_viewport_list_->SetToRecommendedBufferViewports(); |
| 253 | 228 |
| 254 gvr::Frame frame = swap_chain_->AcquireFrame(); | 229 gvr::Frame frame = swap_chain_->AcquireFrame(); |
| 255 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); | 230 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); |
| 256 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; | 231 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; |
| 257 head_pose_ = gvr_api_->GetHeadPoseInStartSpace(target_time); | 232 head_pose_ = gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time); |
| 233 head_pose_ = gvr_api_->ApplyNeckModel(head_pose_, 1.0f); | |
| 258 | 234 |
| 259 // Bind back to the default framebuffer. | 235 // Bind back to the default framebuffer. |
| 260 frame.BindBuffer(0); | 236 frame.BindBuffer(0); |
| 261 | 237 |
| 262 if (webvr_mode_) { | 238 if (webvr_mode_) { |
| 263 DrawWebVr(); | 239 DrawWebVr(); |
| 264 } else { | 240 } else { |
| 265 DrawVrShell(target_time.monotonic_system_time_nanos); | 241 DrawVrShell(target_time.monotonic_system_time_nanos); |
| 266 } | 242 } |
| 267 | 243 |
| 268 frame.Unbind(); | 244 frame.Unbind(); |
| 269 frame.Submit(*buffer_viewport_list_, head_pose_); | 245 frame.Submit(*buffer_viewport_list_, head_pose_); |
| 270 } | 246 } |
| 271 | 247 |
| 272 void VrShell::DrawVrShell(int64_t time) { | 248 void VrShell::DrawVrShell(int64_t time) { |
| 273 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; | 249 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; |
| 274 | 250 |
| 275 gvr::Vec3f headPos = getTranslation(head_pose_); | |
| 276 if (headPos.x == 0.0f && headPos.y == 0.0f && headPos.z == 0.0f) { | |
| 277 // This appears to be a 3DOF pose without a neck model. Add one. | |
| 278 // The head pose has redundant data. Assume we're only using the | |
| 279 // object_from_reference_matrix, we're not updating position_external. | |
| 280 // TODO: Not sure what object_from_reference_matrix is. The new api removed | |
| 281 // it. For now, removing it seems working fine. | |
| 282 ApplyNeckModel(head_pose_); | |
| 283 } | |
| 284 | |
| 285 forward_vector_ = getForwardVector(head_pose_); | 251 forward_vector_ = getForwardVector(head_pose_); |
| 286 | 252 |
| 287 desktop_plane_->translation = desktop_position_; | 253 desktop_plane_->translation = desktop_position_; |
| 288 | 254 |
| 289 // Update the render position of all UI elements (including desktop). | 255 // Update the render position of all UI elements (including desktop). |
| 290 scene_.UpdateTransforms(screen_tilt, time); | 256 scene_.UpdateTransforms(screen_tilt, time); |
| 291 | 257 |
| 292 UpdateController(); | 258 UpdateController(); |
| 293 | 259 |
| 294 // Everything should be positioned now, ready for drawing. | 260 // Everything should be positioned now, ready for drawing. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 414 | 380 |
| 415 void VrShell::DrawWebVr() { | 381 void VrShell::DrawWebVr() { |
| 416 // Don't need face culling, depth testing, blending, etc. Turn it all off. | 382 // Don't need face culling, depth testing, blending, etc. Turn it all off. |
| 417 glDisable(GL_CULL_FACE); | 383 glDisable(GL_CULL_FACE); |
| 418 glDepthMask(GL_FALSE); | 384 glDepthMask(GL_FALSE); |
| 419 glDisable(GL_DEPTH_TEST); | 385 glDisable(GL_DEPTH_TEST); |
| 420 glDisable(GL_SCISSOR_TEST); | 386 glDisable(GL_SCISSOR_TEST); |
| 421 glDisable(GL_BLEND); | 387 glDisable(GL_BLEND); |
| 422 glDisable(GL_POLYGON_OFFSET_FILL); | 388 glDisable(GL_POLYGON_OFFSET_FILL); |
| 423 | 389 |
| 424 // Don't need to clear, since we're drawing over the entire render target. | 390 // Don't need to clear, since we're drawing over the entire render target. |
|
billorr
2016/09/23 17:26:24
out of date comment
| |
| 391 glClear(GL_COLOR_BUFFER_BIT); | |
| 425 | 392 |
| 426 glViewport(0, 0, render_size_.width, render_size_.height); | 393 glViewport(0, 0, render_size_.width, render_size_.height); |
| 427 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); | 394 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); |
| 428 } | 395 } |
| 429 | 396 |
| 430 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 397 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| 431 if (gvr_api_ == nullptr) | 398 if (gvr_api_ == nullptr) |
| 432 return; | 399 return; |
| 433 gvr_api_->PauseTracking(); | 400 gvr_api_->PauseTracking(); |
| 434 } | 401 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 const JavaParamRef<jobject>& content_web_contents, | 467 const JavaParamRef<jobject>& content_web_contents, |
| 501 jlong content_window_android) { | 468 jlong content_window_android) { |
| 502 content::ContentViewCore* c_core = content::ContentViewCore::FromWebContents( | 469 content::ContentViewCore* c_core = content::ContentViewCore::FromWebContents( |
| 503 content::WebContents::FromJavaWebContents(content_web_contents)); | 470 content::WebContents::FromJavaWebContents(content_web_contents)); |
| 504 return reinterpret_cast<intptr_t>(new VrShell( | 471 return reinterpret_cast<intptr_t>(new VrShell( |
| 505 env, obj, c_core, | 472 env, obj, c_core, |
| 506 reinterpret_cast<ui::WindowAndroid*>(content_window_android))); | 473 reinterpret_cast<ui::WindowAndroid*>(content_window_android))); |
| 507 } | 474 } |
| 508 | 475 |
| 509 } // namespace vr_shell | 476 } // namespace vr_shell |
| OLD | NEW |