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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || | 155 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || |
156 gl::init::InitializeGLOneOff()); | 156 gl::init::InitializeGLOneOff()); |
157 | 157 |
158 content_texture_id_ = content_texture_handle; | 158 content_texture_id_ = content_texture_handle; |
159 ui_texture_id_ = ui_texture_handle; | 159 ui_texture_id_ = ui_texture_handle; |
160 | 160 |
161 gvr_api_->InitializeGl(); | 161 gvr_api_->InitializeGl(); |
162 std::vector<gvr::BufferSpec> specs; | 162 std::vector<gvr::BufferSpec> specs; |
163 specs.push_back(gvr_api_->CreateBufferSpec()); | 163 specs.push_back(gvr_api_->CreateBufferSpec()); |
164 render_size_ = specs[0].GetSize(); | 164 render_size_ = specs[0].GetSize(); |
165 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs))); | 165 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapchain(specs))); |
166 | 166 |
167 vr_shell_renderer_.reset(new VrShellRenderer()); | 167 vr_shell_renderer_.reset(new VrShellRenderer()); |
168 buffer_viewport_list_.reset( | 168 buffer_viewport_list_.reset( |
169 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); | 169 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); |
170 buffer_viewport_.reset( | 170 buffer_viewport_.reset( |
171 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 171 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
172 } | 172 } |
173 | 173 |
174 void VrShell::UpdateController() { | 174 void VrShell::UpdateController() { |
175 if (!controller_active_) { | 175 if (!controller_active_) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 bool is_inside = x >= 0.0f && x < 1.0f && y >= 0.0f && y < 1.0f; | 229 bool is_inside = x >= 0.0f && x < 1.0f && y >= 0.0f && y < 1.0f; |
230 if (is_inside) { | 230 if (is_inside) { |
231 closest_element = distance_to_plane; | 231 closest_element = distance_to_plane; |
232 cursor_distance_ = desktop_dist * distance_to_plane; | 232 cursor_distance_ = desktop_dist * distance_to_plane; |
233 look_at_vector_ = plane_intersection_point; | 233 look_at_vector_ = plane_intersection_point; |
234 } | 234 } |
235 } | 235 } |
236 } | 236 } |
237 } | 237 } |
238 | 238 |
| 239 void ApplyNeckModel(gvr::Mat4f& mat_forward) { |
| 240 // This assumes that the input matrix is a pure rotation matrix. The |
| 241 // input object_from_reference matrix has the inverse rotation of |
| 242 // the head rotation. Invert it (this is just a transpose). |
| 243 gvr::Mat4f mat = MatrixTranspose(mat_forward); |
| 244 |
| 245 // Position of the point between the eyes, relative to the neck pivot: |
| 246 const float kNeckHorizontalOffset = -0.080f; // meters in Z |
| 247 const float kNeckVerticalOffset = 0.075f; // meters in Y |
| 248 |
| 249 std::array<float, 4> neckOffset = { |
| 250 {0.0f, kNeckVerticalOffset, kNeckHorizontalOffset, 1.0f}}; |
| 251 |
| 252 // Rotate eyes around neck pivot point. |
| 253 auto offset = MatrixVectorMul(mat, neckOffset); |
| 254 |
| 255 // Measure new position relative to original center of head, because |
| 256 // applying a neck model should not elevate the camera. |
| 257 offset[1] -= kNeckVerticalOffset; |
| 258 |
| 259 // Right-multiply the inverse translation onto the |
| 260 // object_from_reference_matrix. |
| 261 TranslateMRight(mat_forward, mat_forward, -offset[0], -offset[1], -offset[2]); |
| 262 } |
| 263 |
239 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 264 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
240 buffer_viewport_list_->SetToRecommendedBufferViewports(); | 265 buffer_viewport_list_->SetToRecommendedBufferViewports(); |
241 | 266 |
242 gvr::Frame frame = swap_chain_->AcquireFrame(); | 267 gvr::Frame frame = swap_chain_->AcquireFrame(); |
243 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); | 268 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); |
244 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; | 269 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; |
245 head_pose_ = gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time); | 270 head_pose_ = gvr_api_->GetHeadPoseInStartSpace(target_time); |
246 head_pose_ = gvr_api_->ApplyNeckModel(head_pose_, 1.0f); | |
247 | 271 |
248 // Bind back to the default framebuffer. | 272 // Bind back to the default framebuffer. |
249 frame.BindBuffer(0); | 273 frame.BindBuffer(0); |
250 | 274 |
251 if (webvr_mode_) { | 275 if (webvr_mode_) { |
252 DrawWebVr(); | 276 DrawWebVr(); |
253 } else { | 277 } else { |
254 DrawVrShell(target_time.monotonic_system_time_nanos); | 278 DrawVrShell(target_time.monotonic_system_time_nanos); |
255 } | 279 } |
256 | 280 |
257 frame.Unbind(); | 281 frame.Unbind(); |
258 frame.Submit(*buffer_viewport_list_, head_pose_); | 282 frame.Submit(*buffer_viewport_list_, head_pose_); |
259 } | 283 } |
260 | 284 |
261 void VrShell::DrawVrShell(int64_t time) { | 285 void VrShell::DrawVrShell(int64_t time) { |
262 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; | 286 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; |
263 | 287 |
| 288 gvr::Vec3f headPos = getTranslation(head_pose_); |
| 289 if (headPos.x == 0.0f && headPos.y == 0.0f && headPos.z == 0.0f) { |
| 290 // This appears to be a 3DOF pose without a neck model. Add one. |
| 291 // The head pose has redundant data. Assume we're only using the |
| 292 // object_from_reference_matrix, we're not updating position_external. |
| 293 // TODO: Not sure what object_from_reference_matrix is. The new api removed |
| 294 // it. For now, removing it seems working fine. |
| 295 ApplyNeckModel(head_pose_); |
| 296 } |
| 297 |
264 forward_vector_ = getForwardVector(head_pose_); | 298 forward_vector_ = getForwardVector(head_pose_); |
265 | 299 |
266 desktop_plane_->translation = desktop_position_; | 300 desktop_plane_->translation = desktop_position_; |
267 | 301 |
268 // Update the render position of all UI elements (including desktop). | 302 // Update the render position of all UI elements (including desktop). |
269 scene_.UpdateTransforms(screen_tilt, time); | 303 scene_.UpdateTransforms(screen_tilt, time); |
270 | 304 |
271 UpdateController(); | 305 UpdateController(); |
272 | 306 |
273 // Everything should be positioned now, ready for drawing. | 307 // Everything should be positioned now, ready for drawing. |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 void VrShell::DrawWebVr() { | 428 void VrShell::DrawWebVr() { |
395 // Don't need face culling, depth testing, blending, etc. Turn it all off. | 429 // Don't need face culling, depth testing, blending, etc. Turn it all off. |
396 glDisable(GL_CULL_FACE); | 430 glDisable(GL_CULL_FACE); |
397 glDepthMask(GL_FALSE); | 431 glDepthMask(GL_FALSE); |
398 glDisable(GL_DEPTH_TEST); | 432 glDisable(GL_DEPTH_TEST); |
399 glDisable(GL_SCISSOR_TEST); | 433 glDisable(GL_SCISSOR_TEST); |
400 glDisable(GL_BLEND); | 434 glDisable(GL_BLEND); |
401 glDisable(GL_POLYGON_OFFSET_FILL); | 435 glDisable(GL_POLYGON_OFFSET_FILL); |
402 | 436 |
403 // Don't need to clear, since we're drawing over the entire render target. | 437 // Don't need to clear, since we're drawing over the entire render target. |
404 glClear(GL_COLOR_BUFFER_BIT); | |
405 | 438 |
406 glViewport(0, 0, render_size_.width, render_size_.height); | 439 glViewport(0, 0, render_size_.width, render_size_.height); |
407 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); | 440 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); |
408 } | 441 } |
409 | 442 |
410 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 443 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
411 if (gvr_api_ == nullptr) | 444 if (gvr_api_ == nullptr) |
412 return; | 445 return; |
413 gvr_api_->PauseTracking(); | 446 gvr_api_->PauseTracking(); |
414 } | 447 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 content::WebContents::FromJavaWebContents(content_web_contents)); | 521 content::WebContents::FromJavaWebContents(content_web_contents)); |
489 content::ContentViewCore* ui_core = content::ContentViewCore::FromWebContents( | 522 content::ContentViewCore* ui_core = content::ContentViewCore::FromWebContents( |
490 content::WebContents::FromJavaWebContents(ui_web_contents)); | 523 content::WebContents::FromJavaWebContents(ui_web_contents)); |
491 return reinterpret_cast<intptr_t>(new VrShell( | 524 return reinterpret_cast<intptr_t>(new VrShell( |
492 env, obj, c_core, | 525 env, obj, c_core, |
493 reinterpret_cast<ui::WindowAndroid*>(content_window_android), ui_core, | 526 reinterpret_cast<ui::WindowAndroid*>(content_window_android), ui_core, |
494 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); | 527 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); |
495 } | 528 } |
496 | 529 |
497 } // namespace vr_shell | 530 } // namespace vr_shell |
OLD | NEW |