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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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. |
| 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 |