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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 const JavaParamRef<jobject>& obj, | 125 const JavaParamRef<jobject>& obj, |
| 126 jint texture_data_handle) { | 126 jint texture_data_handle) { |
| 127 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || | 127 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || |
| 128 gl::init::InitializeGLOneOff()); | 128 gl::init::InitializeGLOneOff()); |
| 129 | 129 |
| 130 content_texture_id_ = texture_data_handle; | 130 content_texture_id_ = texture_data_handle; |
| 131 gvr_api_->InitializeGl(); | 131 gvr_api_->InitializeGl(); |
| 132 std::vector<gvr::BufferSpec> specs; | 132 std::vector<gvr::BufferSpec> specs; |
| 133 specs.push_back(gvr_api_->CreateBufferSpec()); | 133 specs.push_back(gvr_api_->CreateBufferSpec()); |
| 134 render_size_ = specs[0].GetSize(); | 134 render_size_ = specs[0].GetSize(); |
| 135 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapchain(specs))); | 135 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs))); |
| 136 | 136 |
| 137 vr_shell_renderer_.reset(new VrShellRenderer()); | 137 vr_shell_renderer_.reset(new VrShellRenderer()); |
| 138 buffer_viewport_list_.reset( | 138 buffer_viewport_list_.reset( |
| 139 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); | 139 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); |
| 140 buffer_viewport_.reset( | 140 buffer_viewport_.reset( |
| 141 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 141 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
| 142 } | 142 } |
| 143 | 143 |
| 144 void VrShell::UpdateController() { | 144 void VrShell::UpdateController() { |
| 145 if (!controller_active_) { | 145 if (!controller_active_) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 176 translation.y += kHandPosition.y; | 176 translation.y += kHandPosition.y; |
| 177 translation.z += kHandPosition.z; | 177 translation.z += kHandPosition.z; |
| 178 } | 178 } |
| 179 | 179 |
| 180 // We can only be intersecting the desktop plane at the moment. | 180 // We can only be intersecting the desktop plane at the moment. |
| 181 float distance_to_plane = desktop_plane_->GetRayDistance(translation, | 181 float distance_to_plane = desktop_plane_->GetRayDistance(translation, |
| 182 forward); | 182 forward); |
| 183 look_at_vector_ = GetRayPoint(translation, forward, distance_to_plane); | 183 look_at_vector_ = GetRayPoint(translation, forward, distance_to_plane); |
| 184 } | 184 } |
| 185 | 185 |
| 186 void ApplyNeckModel(gvr::Mat4f& mat_forward) { | |
| 187 // This assumes that the input matrix is a pure rotation matrix. The | |
| 188 // input object_from_reference matrix has the inverse rotation of | |
| 189 // the head rotation. Invert it (this is just a transpose). | |
| 190 gvr::Mat4f mat = MatrixTranspose(mat_forward); | |
| 191 | |
| 192 // Position of the point between the eyes, relative to the neck pivot: | |
| 193 const float kNeckHorizontalOffset = -0.080f; // meters in Z | |
| 194 const float kNeckVerticalOffset = 0.075f; // meters in Y | |
| 195 | |
| 196 std::array<float, 4> neckOffset = { | |
| 197 {0.0f, kNeckVerticalOffset, kNeckHorizontalOffset, 1.0f}}; | |
| 198 | |
| 199 // Rotate eyes around neck pivot point. | |
| 200 auto offset = MatrixVectorMul(mat, neckOffset); | |
| 201 | |
| 202 // Measure new position relative to original center of head, because | |
| 203 // applying a neck model should not elevate the camera. | |
| 204 offset[1] -= kNeckVerticalOffset; | |
| 205 | |
| 206 // Right-multiply the inverse translation onto the | |
| 207 // object_from_reference_matrix. | |
| 208 TranslateMRight(mat_forward, mat_forward, -offset[0], -offset[1], -offset[2]); | |
| 209 } | |
| 210 | |
| 211 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 186 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| 212 buffer_viewport_list_->SetToRecommendedBufferViewports(); | 187 buffer_viewport_list_->SetToRecommendedBufferViewports(); |
| 213 | 188 |
| 214 gvr::Frame frame = swap_chain_->AcquireFrame(); | 189 gvr::Frame frame = swap_chain_->AcquireFrame(); |
| 215 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); | 190 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); |
| 216 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; | 191 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; |
| 217 head_pose_ = gvr_api_->GetHeadPoseInStartSpace(target_time); | 192 head_pose_ = gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time); |
| 193 head_pose_ = gvr_api_->ApplyNeckModel(head_pose_, 1.0f); | |
| 218 | 194 |
| 219 // Bind back to the default framebuffer. | 195 // Bind back to the default framebuffer. |
| 220 frame.BindBuffer(0); | 196 frame.BindBuffer(0); |
| 221 | 197 |
| 222 if (webvr_mode_) { | 198 if (webvr_mode_) { |
| 223 DrawWebVr(); | 199 DrawWebVr(); |
| 224 } else { | 200 } else { |
| 225 DrawVrShell(target_time.monotonic_system_time_nanos); | 201 DrawVrShell(target_time.monotonic_system_time_nanos); |
| 226 } | 202 } |
| 227 | 203 |
| 228 frame.Unbind(); | 204 frame.Unbind(); |
| 229 frame.Submit(*buffer_viewport_list_, head_pose_); | 205 frame.Submit(*buffer_viewport_list_, head_pose_); |
| 230 } | 206 } |
| 231 | 207 |
| 232 void VrShell::DrawVrShell(int64_t time) { | 208 void VrShell::DrawVrShell(int64_t time) { |
| 233 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; | 209 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; |
| 234 | 210 |
| 235 forward_vector_ = getForwardVector(head_pose_); | 211 forward_vector_ = getForwardVector(head_pose_); |
| 236 | 212 |
| 237 gvr::Vec3f headPos = getTranslation(head_pose_); | |
| 238 if (headPos.x == 0.0f && headPos.y == 0.0f && headPos.z == 0.0f) { | |
| 239 // This appears to be a 3DOF pose without a neck model. Add one. | |
| 240 // The head pose has redundant data. Assume we're only using the | |
| 241 // object_from_reference_matrix, we're not updating position_external. | |
| 242 // TODO: Not sure what object_from_reference_matrix is. The new api removed | |
| 243 // it. For now, removing it seems working fine. | |
| 244 ApplyNeckModel(head_pose_); | |
| 245 } | |
| 246 | |
| 247 desktop_plane_->translation.x = desktop_position_.x; | 213 desktop_plane_->translation.x = desktop_position_.x; |
| 248 desktop_plane_->translation.y = desktop_position_.y; | 214 desktop_plane_->translation.y = desktop_position_.y; |
| 249 desktop_plane_->translation.z = desktop_position_.z; | 215 desktop_plane_->translation.z = desktop_position_.z; |
| 250 | 216 |
| 251 // Update the render position of all UI elements (including desktop). | 217 // Update the render position of all UI elements (including desktop). |
| 252 scene_.UpdateTransforms(screen_tilt, time); | 218 scene_.UpdateTransforms(screen_tilt, time); |
| 253 | 219 |
| 254 UpdateController(); | 220 UpdateController(); |
| 255 | 221 |
| 256 // Everything should be positioned now, ready for drawing. | 222 // Everything should be positioned now, ready for drawing. |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 | 338 |
| 373 void VrShell::DrawWebVr() { | 339 void VrShell::DrawWebVr() { |
| 374 // Don't need face culling, depth testing, blending, etc. Turn it all off. | 340 // Don't need face culling, depth testing, blending, etc. Turn it all off. |
| 375 glDisable(GL_CULL_FACE); | 341 glDisable(GL_CULL_FACE); |
| 376 glDepthMask(GL_FALSE); | 342 glDepthMask(GL_FALSE); |
| 377 glDisable(GL_DEPTH_TEST); | 343 glDisable(GL_DEPTH_TEST); |
| 378 glDisable(GL_SCISSOR_TEST); | 344 glDisable(GL_SCISSOR_TEST); |
| 379 glDisable(GL_BLEND); | 345 glDisable(GL_BLEND); |
| 380 glDisable(GL_POLYGON_OFFSET_FILL); | 346 glDisable(GL_POLYGON_OFFSET_FILL); |
| 381 | 347 |
| 382 // Don't need to clear, since we're drawing over the entire render target. | 348 // Don't need to clear, since we're drawing over the entire render target. |
|
billorr
2016/09/23 17:26:24
comment is now out of date
| |
| 349 glClear(GL_COLOR_BUFFER_BIT); | |
| 383 | 350 |
| 384 glViewport(0, 0, render_size_.width, render_size_.height); | 351 glViewport(0, 0, render_size_.width, render_size_.height); |
| 385 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); | 352 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); |
| 386 } | 353 } |
| 387 | 354 |
| 388 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 355 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| 389 if (gvr_api_ == nullptr) | 356 if (gvr_api_ == nullptr) |
| 390 return; | 357 return; |
| 391 gvr_api_->PauseTracking(); | 358 gvr_api_->PauseTracking(); |
| 392 } | 359 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 const JavaParamRef<jobject>& content_web_contents, | 407 const JavaParamRef<jobject>& content_web_contents, |
| 441 jlong content_window_android) { | 408 jlong content_window_android) { |
| 442 content::ContentViewCore* c_core = content::ContentViewCore::FromWebContents( | 409 content::ContentViewCore* c_core = content::ContentViewCore::FromWebContents( |
| 443 content::WebContents::FromJavaWebContents(content_web_contents)); | 410 content::WebContents::FromJavaWebContents(content_web_contents)); |
| 444 return reinterpret_cast<intptr_t>(new VrShell( | 411 return reinterpret_cast<intptr_t>(new VrShell( |
| 445 env, obj, c_core, | 412 env, obj, c_core, |
| 446 reinterpret_cast<ui::WindowAndroid*>(content_window_android))); | 413 reinterpret_cast<ui::WindowAndroid*>(content_window_android))); |
| 447 } | 414 } |
| 448 | 415 |
| 449 } // namespace vr_shell | 416 } // namespace vr_shell |
| OLD | NEW |