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_gl.h" | 5 #include "chrome/browser/android/vr_shell/vr_shell_gl.h" |
| 6 | 6 |
| 7 #include <chrono> | 7 #include <chrono> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 35 #include "ui/gl/android/surface_texture.h" | 35 #include "ui/gl/android/surface_texture.h" |
| 36 #include "ui/gl/gl_bindings.h" | 36 #include "ui/gl/gl_bindings.h" |
| 37 #include "ui/gl/gl_context.h" | 37 #include "ui/gl/gl_context.h" |
| 38 #include "ui/gl/gl_surface.h" | 38 #include "ui/gl/gl_surface.h" |
| 39 #include "ui/gl/init/gl_factory.h" | 39 #include "ui/gl/init/gl_factory.h" |
| 40 | 40 |
| 41 namespace vr_shell { | 41 namespace vr_shell { |
| 42 | 42 |
| 43 namespace { | 43 namespace { |
| 44 static constexpr float kZNear = 0.1f; | 44 static constexpr float kZNear = 0.1f; |
| 45 static constexpr float kZFar = 1000.0f; | 45 // This should be kept fairly small with current reticle rendering technique |
| 46 // which requires fairly high precision to draw on top of elements correctly. | |
| 47 static constexpr float kZFar = 100.0f; | |
| 46 | 48 |
| 47 static constexpr float kReticleWidth = 0.025f; | 49 static constexpr float kReticleWidth = 0.025f; |
| 48 static constexpr float kReticleHeight = 0.025f; | 50 static constexpr float kReticleHeight = 0.025f; |
| 49 | 51 |
| 50 static constexpr float kLaserWidth = 0.01f; | 52 static constexpr float kLaserWidth = 0.01f; |
| 51 | 53 |
| 52 static constexpr gfx::Point3F kOrigin = {0.0f, 0.0f, 0.0f}; | 54 static constexpr gfx::Point3F kOrigin = {0.0f, 0.0f, 0.0f}; |
| 53 | 55 |
| 54 // Fraction of the distance to the object the cursor is drawn at to avoid | 56 // Fraction of the distance to the object the reticle is drawn at to avoid |
| 55 // rounding errors drawing the cursor behind the object. | 57 // rounding errors drawing the reticle behind the object. |
| 56 static constexpr float kReticleOffset = 0.99f; | 58 // TODO(mthiesse): Find a better approach for drawing the reticle on an object. |
| 59 // Right now we have to wedge it very precisely between the content window and | |
| 60 // backplane to avoid rendering artifacts. | |
| 61 static constexpr float kReticleOffset = 0.999f; | |
| 57 | 62 |
| 58 // GVR buffer indices for use with viewport->SetSourceBufferIndex | 63 // GVR buffer indices for use with viewport->SetSourceBufferIndex |
| 59 // or frame.BindBuffer. We use one for world content (with reprojection) | 64 // or frame.BindBuffer. We use one for world content (with reprojection) |
| 60 // including main VrShell and WebVR content plus world-space UI. | 65 // including main VrShell and WebVR content plus world-space UI. |
| 61 // The headlocked buffer is for UI that should not use reprojection. | 66 // The headlocked buffer is for UI that should not use reprojection. |
| 62 static constexpr int kFramePrimaryBuffer = 0; | 67 static constexpr int kFramePrimaryBuffer = 0; |
| 63 static constexpr int kFrameHeadlockedBuffer = 1; | 68 static constexpr int kFrameHeadlockedBuffer = 1; |
| 64 | 69 |
| 65 // Pixel dimensions and field of view for the head-locked content. This | 70 // Pixel dimensions and field of view for the head-locked content. This |
| 66 // is currently sized to fit the WebVR "insecure transport" warnings, | 71 // is currently sized to fit the WebVR "insecure transport" warnings, |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 526 QuatToMatrix(controller_quat_, &mat); | 531 QuatToMatrix(controller_quat_, &mat); |
| 527 gfx::Vector3dF controller_direction = | 532 gfx::Vector3dF controller_direction = |
| 528 vr::MatrixVectorMul(mat, ergo_neutral_pose); | 533 vr::MatrixVectorMul(mat, ergo_neutral_pose); |
| 529 | 534 |
| 530 HandleControllerAppButtonActivity(controller_direction); | 535 HandleControllerAppButtonActivity(controller_direction); |
| 531 | 536 |
| 532 if (ShouldDrawWebVr()) | 537 if (ShouldDrawWebVr()) |
| 533 return; | 538 return; |
| 534 gfx::PointF target_local_point; | 539 gfx::PointF target_local_point; |
| 535 gfx::Vector3dF eye_to_target; | 540 gfx::Vector3dF eye_to_target; |
| 536 cursor_render_target_ = nullptr; | 541 reticle_render_target_ = nullptr; |
| 537 GetVisualTargetElement(controller_direction, eye_to_target, target_point_, | 542 GetVisualTargetElement(controller_direction, eye_to_target, target_point_, |
| 538 &cursor_render_target_, target_local_point); | 543 &reticle_render_target_, target_local_point); |
| 539 | 544 |
| 540 UiElement* target_element = nullptr; | 545 UiElement* target_element = nullptr; |
| 541 if (input_locked_element_) { | 546 if (input_locked_element_) { |
| 542 gfx::Point3F plane_intersection_point; | 547 gfx::Point3F plane_intersection_point; |
| 543 float distance_to_plane; | 548 float distance_to_plane; |
| 544 GetTargetLocalPoint(eye_to_target, *input_locked_element_, | 549 GetTargetLocalPoint(eye_to_target, *input_locked_element_, |
| 545 2 * scene_->GetBackgroundDistance(), target_local_point, | 550 2 * scene_->GetBackgroundDistance(), target_local_point, |
| 546 plane_intersection_point, distance_to_plane); | 551 plane_intersection_point, distance_to_plane); |
| 547 target_element = input_locked_element_; | 552 target_element = input_locked_element_; |
| 548 } else if (!in_scroll_ && !in_click_) { | 553 } else if (!in_scroll_ && !in_click_) { |
| 549 target_element = cursor_render_target_; | 554 target_element = reticle_render_target_; |
| 550 } | 555 } |
| 551 | 556 |
| 552 // Handle input targeting on the content quad, ignoring any other elements. | 557 // Handle input targeting on the content quad, ignoring any other elements. |
| 553 // Content is treated specially to accomodate scrolling, flings, etc. | 558 // Content is treated specially to accomodate scrolling, flings, etc. |
| 554 gfx::Point local_point_pixels; | 559 gfx::Point local_point_pixels; |
| 555 if (target_element && (target_element->fill() == Fill::CONTENT)) { | 560 if (target_element && (target_element->fill() == Fill::CONTENT)) { |
| 556 gfx::RectF pixel_rect(0, 0, content_tex_css_width_, | 561 gfx::RectF pixel_rect(0, 0, content_tex_css_width_, |
| 557 content_tex_css_height_); | 562 content_tex_css_height_); |
| 558 local_point_pixels.set_x(pixel_rect.x() + | 563 local_point_pixels.set_x(pixel_rect.x() + |
| 559 pixel_rect.width() * target_local_point.x()); | 564 pixel_rect.width() * target_local_point.x()); |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1065 vr::Mat4f identity_matrix; | 1070 vr::Mat4f identity_matrix; |
| 1066 vr::SetIdentityM(&identity_matrix); | 1071 vr::SetIdentityM(&identity_matrix); |
| 1067 DrawUiView(identity_matrix, elements, render_size_headlocked_, | 1072 DrawUiView(identity_matrix, elements, render_size_headlocked_, |
| 1068 kViewportListHeadlockedOffset, false); | 1073 kViewportListHeadlockedOffset, false); |
| 1069 } | 1074 } |
| 1070 | 1075 |
| 1071 void VrShellGl::DrawUiView(const vr::Mat4f& head_pose, | 1076 void VrShellGl::DrawUiView(const vr::Mat4f& head_pose, |
| 1072 const std::vector<const UiElement*>& elements, | 1077 const std::vector<const UiElement*>& elements, |
| 1073 const gfx::Size& render_size, | 1078 const gfx::Size& render_size, |
| 1074 int viewport_offset, | 1079 int viewport_offset, |
| 1075 bool draw_cursor) { | 1080 bool draw_reticle) { |
| 1076 TRACE_EVENT0("gpu", "VrShellGl::DrawUiView"); | 1081 TRACE_EVENT0("gpu", "VrShellGl::DrawUiView"); |
| 1077 | 1082 |
| 1078 auto elementsInDrawOrder = GetElementsInDrawOrder(head_pose, elements); | 1083 auto elementsInDrawOrder = GetElementsInDrawOrder(head_pose, elements); |
| 1079 | 1084 |
| 1080 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) { | 1085 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) { |
| 1081 buffer_viewport_list_->GetBufferViewport(eye + viewport_offset, | 1086 buffer_viewport_list_->GetBufferViewport(eye + viewport_offset, |
| 1082 buffer_viewport_.get()); | 1087 buffer_viewport_.get()); |
| 1083 | 1088 |
| 1084 vr::Mat4f eye_view_matrix; | 1089 vr::Mat4f eye_view_matrix; |
| 1085 vr::Mat4f eye_matrix; | 1090 vr::Mat4f eye_matrix; |
| 1086 GvrMatToMatf(gvr_api_->GetEyeFromHeadMatrix(eye), &eye_matrix); | 1091 GvrMatToMatf(gvr_api_->GetEyeFromHeadMatrix(eye), &eye_matrix); |
| 1087 vr::MatrixMul(eye_matrix, head_pose, &eye_view_matrix); | 1092 vr::MatrixMul(eye_matrix, head_pose, &eye_view_matrix); |
| 1088 | 1093 |
| 1089 const gfx::RectF& rect = GfxRectFromUV(buffer_viewport_->GetSourceUv()); | 1094 const gfx::RectF& rect = GfxRectFromUV(buffer_viewport_->GetSourceUv()); |
| 1090 const gfx::Rect& pixel_rect = CalculatePixelSpaceRect(render_size, rect); | 1095 const gfx::Rect& pixel_rect = CalculatePixelSpaceRect(render_size, rect); |
| 1091 glViewport(pixel_rect.x(), pixel_rect.y(), pixel_rect.width(), | 1096 glViewport(pixel_rect.x(), pixel_rect.y(), pixel_rect.width(), |
| 1092 pixel_rect.height()); | 1097 pixel_rect.height()); |
| 1093 | 1098 |
| 1094 vr::Mat4f render_matrix; | 1099 vr::Mat4f view_proj_matrix; |
| 1095 vr::Mat4f perspective_matrix; | 1100 vr::Mat4f perspective_matrix; |
| 1096 GvrMatToMatf(PerspectiveMatrixFromView(buffer_viewport_->GetSourceFov(), | 1101 GvrMatToMatf(PerspectiveMatrixFromView(buffer_viewport_->GetSourceFov(), |
| 1097 kZNear, kZFar), | 1102 kZNear, kZFar), |
| 1098 &perspective_matrix); | 1103 &perspective_matrix); |
| 1099 | 1104 |
| 1100 vr::MatrixMul(perspective_matrix, eye_view_matrix, &render_matrix); | 1105 vr::MatrixMul(perspective_matrix, eye_view_matrix, &view_proj_matrix); |
| 1101 | 1106 |
| 1102 DrawElements(render_matrix, elementsInDrawOrder); | 1107 DrawElements(view_proj_matrix, elementsInDrawOrder, draw_reticle); |
| 1103 if (draw_cursor) { | 1108 if (draw_reticle) { |
| 1104 DrawController(render_matrix); | 1109 DrawLaser(view_proj_matrix); |
|
acondor_
2017/05/24 16:34:54
mthiesse, what was the reason for altering this or
mthiesse
2017/05/24 17:37:08
Oh, I didn't mean to invert the order of these two
| |
| 1105 DrawCursor(render_matrix); | 1110 DrawController(view_proj_matrix); |
| 1106 } | 1111 } |
| 1107 } | 1112 } |
| 1108 } | 1113 } |
| 1109 | 1114 |
| 1110 void VrShellGl::DrawElements(const vr::Mat4f& view_proj_matrix, | 1115 void VrShellGl::DrawElements(const vr::Mat4f& view_proj_matrix, |
| 1111 const std::vector<const UiElement*>& elements) { | 1116 const std::vector<const UiElement*>& elements, |
| 1112 for (const auto* rect : elements) { | 1117 bool draw_reticle) { |
| 1113 vr::Mat4f transform; | 1118 if (elements.empty()) |
| 1114 vr::MatrixMul(view_proj_matrix, rect->TransformMatrix(), &transform); | 1119 return; |
| 1120 int initial_draw_phase = elements.front()->draw_phase(); | |
| 1121 bool drawn_reticle = false; | |
| 1122 for (const auto* element : elements) { | |
| 1123 // If we have no element to draw the reticle on, draw it after the | |
| 1124 // background (the initial draw phase). | |
| 1125 if (!reticle_render_target_ && draw_reticle && !drawn_reticle && | |
| 1126 element->draw_phase() > initial_draw_phase) { | |
| 1127 DrawReticle(view_proj_matrix); | |
| 1128 drawn_reticle = true; | |
| 1129 } | |
| 1115 | 1130 |
| 1116 switch (rect->fill()) { | 1131 DrawElement(view_proj_matrix, *element); |
| 1117 case Fill::OPAQUE_GRADIENT: { | 1132 |
| 1118 vr_shell_renderer_->GetGradientQuadRenderer()->Draw( | 1133 if (draw_reticle && (reticle_render_target_ == element)) { |
| 1119 transform, rect->edge_color(), rect->center_color(), | 1134 DrawReticle(view_proj_matrix); |
| 1120 rect->computed_opacity()); | |
| 1121 break; | |
| 1122 } | |
| 1123 case Fill::GRID_GRADIENT: { | |
| 1124 vr_shell_renderer_->GetGradientGridRenderer()->Draw( | |
| 1125 transform, rect->edge_color(), rect->center_color(), | |
| 1126 rect->gridline_count(), rect->computed_opacity()); | |
| 1127 break; | |
| 1128 } | |
| 1129 case Fill::CONTENT: { | |
| 1130 gfx::RectF copy_rect(0, 0, 1, 1); | |
| 1131 vr_shell_renderer_->GetExternalTexturedQuadRenderer()->Draw( | |
| 1132 content_texture_id_, transform, copy_rect, | |
| 1133 rect->computed_opacity()); | |
| 1134 break; | |
| 1135 } | |
| 1136 case Fill::SELF: { | |
| 1137 rect->Render(vr_shell_renderer_.get(), transform); | |
| 1138 break; | |
| 1139 } | |
| 1140 default: | |
| 1141 break; | |
| 1142 } | 1135 } |
| 1143 } | 1136 } |
| 1144 vr_shell_renderer_->Flush(); | 1137 vr_shell_renderer_->Flush(); |
| 1145 } | 1138 } |
| 1146 | 1139 |
| 1140 void VrShellGl::DrawElement(const vr::Mat4f& view_proj_matrix, | |
| 1141 const UiElement& element) { | |
| 1142 vr::Mat4f transform; | |
| 1143 vr::MatrixMul(view_proj_matrix, element.TransformMatrix(), &transform); | |
| 1144 | |
| 1145 switch (element.fill()) { | |
| 1146 case Fill::OPAQUE_GRADIENT: { | |
| 1147 vr_shell_renderer_->GetGradientQuadRenderer()->Draw( | |
| 1148 transform, element.edge_color(), element.center_color(), | |
| 1149 element.computed_opacity()); | |
| 1150 break; | |
| 1151 } | |
| 1152 case Fill::GRID_GRADIENT: { | |
| 1153 vr_shell_renderer_->GetGradientGridRenderer()->Draw( | |
| 1154 transform, element.edge_color(), element.center_color(), | |
| 1155 element.gridline_count(), element.computed_opacity()); | |
| 1156 break; | |
| 1157 } | |
| 1158 case Fill::CONTENT: { | |
| 1159 gfx::RectF copy_rect(0, 0, 1, 1); | |
| 1160 vr_shell_renderer_->GetExternalTexturedQuadRenderer()->Draw( | |
| 1161 content_texture_id_, transform, copy_rect, | |
| 1162 element.computed_opacity()); | |
| 1163 break; | |
| 1164 } | |
| 1165 case Fill::SELF: { | |
| 1166 element.Render(vr_shell_renderer_.get(), transform); | |
| 1167 break; | |
| 1168 } | |
| 1169 default: | |
| 1170 break; | |
| 1171 } | |
| 1172 } | |
| 1173 | |
| 1147 std::vector<const UiElement*> VrShellGl::GetElementsInDrawOrder( | 1174 std::vector<const UiElement*> VrShellGl::GetElementsInDrawOrder( |
| 1148 const vr::Mat4f& view_matrix, | 1175 const vr::Mat4f& view_matrix, |
| 1149 const std::vector<const UiElement*>& elements) { | 1176 const std::vector<const UiElement*>& elements) { |
| 1150 std::vector<const UiElement*> sorted_elements = elements; | 1177 std::vector<const UiElement*> sorted_elements = elements; |
| 1151 | 1178 |
| 1152 // Sort elements primarily based on their draw phase (lower draw phase first) | 1179 // Sort elements primarily based on their draw phase (lower draw phase first) |
| 1153 // and secondarily based on their z-axis distance (more distant first). | 1180 // and secondarily based on their z-axis distance (more distant first). |
| 1154 // TODO(mthiesse, crbug.com/721356): This will not work well for elements not | 1181 // TODO(mthiesse, crbug.com/721356): This will not work well for elements not |
| 1155 // directly in front of the user, but works well enough for our initial | 1182 // directly in front of the user, but works well enough for our initial |
| 1156 // release, and provides a consistent ordering that we can easily design | 1183 // release, and provides a consistent ordering that we can easily design |
| 1157 // around. | 1184 // around. |
| 1158 std::sort(sorted_elements.begin(), sorted_elements.end(), | 1185 std::sort(sorted_elements.begin(), sorted_elements.end(), |
| 1159 [](const UiElement* first, const UiElement* second) { | 1186 [](const UiElement* first, const UiElement* second) { |
| 1160 if (first->draw_phase() != second->draw_phase()) { | 1187 if (first->draw_phase() != second->draw_phase()) { |
| 1161 return first->draw_phase() < second->draw_phase(); | 1188 return first->draw_phase() < second->draw_phase(); |
| 1162 } else { | 1189 } else { |
| 1163 return vr::GetTranslation(first->TransformMatrix()).z() < | 1190 return vr::GetTranslation(first->TransformMatrix()).z() < |
| 1164 vr::GetTranslation(second->TransformMatrix()).z(); | 1191 vr::GetTranslation(second->TransformMatrix()).z(); |
| 1165 } | 1192 } |
| 1166 }); | 1193 }); |
| 1167 | 1194 |
| 1168 return sorted_elements; | 1195 return sorted_elements; |
| 1169 } | 1196 } |
| 1170 | 1197 |
| 1171 void VrShellGl::DrawCursor(const vr::Mat4f& render_matrix) { | 1198 void VrShellGl::DrawReticle(const vr::Mat4f& render_matrix) { |
| 1172 vr::Mat4f mat; | 1199 vr::Mat4f mat; |
| 1173 vr::SetIdentityM(&mat); | 1200 vr::SetIdentityM(&mat); |
| 1174 | 1201 |
| 1175 // Draw the reticle. | 1202 // Scale the reticle to have a fixed FOV size at any distance. |
| 1176 | |
| 1177 // Scale the pointer to have a fixed FOV size at any distance. | |
| 1178 const float eye_to_target = | 1203 const float eye_to_target = |
| 1179 std::sqrt(target_point_.SquaredDistanceTo(kOrigin)); | 1204 std::sqrt(target_point_.SquaredDistanceTo(kOrigin)); |
| 1180 vr::ScaleM( | 1205 vr::ScaleM( |
| 1181 mat, | 1206 mat, |
| 1182 {kReticleWidth * eye_to_target, kReticleHeight * eye_to_target, 1.0f}, | 1207 {kReticleWidth * eye_to_target, kReticleHeight * eye_to_target, 1.0f}, |
| 1183 &mat); | 1208 &mat); |
| 1184 | 1209 |
| 1185 vr::Quatf rotation; | 1210 vr::Quatf rotation; |
| 1186 if (cursor_render_target_ != nullptr) { | 1211 if (reticle_render_target_ != nullptr) { |
| 1187 // Make the reticle planar to the element it's hitting. | 1212 // Make the reticle planar to the element it's hitting. |
| 1188 rotation = GetRotationFromZAxis(cursor_render_target_->GetNormal()); | 1213 rotation = GetRotationFromZAxis(reticle_render_target_->GetNormal()); |
| 1189 } else { | 1214 } else { |
| 1190 // Rotate the cursor to directly face the eyes. | 1215 // Rotate the reticle to directly face the eyes. |
| 1191 rotation = GetRotationFromZAxis(target_point_ - kOrigin); | 1216 rotation = GetRotationFromZAxis(target_point_ - kOrigin); |
| 1192 } | 1217 } |
| 1193 vr::Mat4f rotation_mat; | 1218 vr::Mat4f rotation_mat; |
| 1194 vr::QuatToMatrix(rotation, &rotation_mat); | 1219 vr::QuatToMatrix(rotation, &rotation_mat); |
| 1195 vr::MatrixMul(rotation_mat, mat, &mat); | 1220 vr::MatrixMul(rotation_mat, mat, &mat); |
| 1196 | 1221 |
| 1197 gfx::Point3F target_point = ScalePoint(target_point_, kReticleOffset); | 1222 gfx::Point3F target_point = ScalePoint(target_point_, kReticleOffset); |
| 1198 // Place the pointer slightly in front of the plane intersection point. | 1223 // Place the pointer slightly in front of the plane intersection point. |
| 1199 vr::TranslateM(mat, target_point - kOrigin, &mat); | 1224 vr::TranslateM(mat, target_point - kOrigin, &mat); |
| 1200 | 1225 |
| 1201 vr::Mat4f transform; | 1226 vr::Mat4f transform; |
| 1202 vr::MatrixMul(render_matrix, mat, &transform); | 1227 vr::MatrixMul(render_matrix, mat, &transform); |
| 1203 vr_shell_renderer_->GetReticleRenderer()->Draw(transform); | 1228 vr_shell_renderer_->GetReticleRenderer()->Draw(transform); |
| 1229 } | |
| 1204 | 1230 |
| 1205 // Draw the laser. | 1231 void VrShellGl::DrawLaser(const vr::Mat4f& render_matrix) { |
| 1206 | 1232 gfx::Point3F target_point = ScalePoint(target_point_, kReticleOffset); |
| 1207 // Find the length of the beam (from hand to target). | 1233 // Find the length of the beam (from hand to target). |
| 1208 const float laser_length = | 1234 const float laser_length = |
| 1209 std::sqrt(pointer_start_.SquaredDistanceTo(target_point)); | 1235 std::sqrt(pointer_start_.SquaredDistanceTo(target_point)); |
| 1210 | 1236 |
| 1237 vr::Mat4f mat; | |
| 1211 // Build a beam, originating from the origin. | 1238 // Build a beam, originating from the origin. |
| 1212 vr::SetIdentityM(&mat); | 1239 vr::SetIdentityM(&mat); |
| 1213 | 1240 |
| 1214 // Move the beam half its height so that its end sits on the origin. | 1241 // Move the beam half its height so that its end sits on the origin. |
| 1215 vr::TranslateM(mat, {0.0f, 0.5f, 0.0f}, &mat); | 1242 vr::TranslateM(mat, {0.0f, 0.5f, 0.0f}, &mat); |
| 1216 vr::ScaleM(mat, {kLaserWidth, laser_length, 1}, &mat); | 1243 vr::ScaleM(mat, {kLaserWidth, laser_length, 1}, &mat); |
| 1217 | 1244 |
| 1218 // Tip back 90 degrees to flat, pointing at the scene. | 1245 // Tip back 90 degrees to flat, pointing at the scene. |
| 1219 const vr::Quatf quat = vr::QuatFromAxisAngle({1.0f, 0.0f, 0.0f, -M_PI / 2}); | 1246 const vr::Quatf quat = vr::QuatFromAxisAngle({1.0f, 0.0f, 0.0f, -M_PI / 2}); |
| 1247 vr::Mat4f rotation_mat; | |
| 1220 vr::QuatToMatrix(quat, &rotation_mat); | 1248 vr::QuatToMatrix(quat, &rotation_mat); |
| 1221 vr::MatrixMul(rotation_mat, mat, &mat); | 1249 vr::MatrixMul(rotation_mat, mat, &mat); |
| 1222 | 1250 |
| 1223 const gfx::Vector3dF beam_direction = target_point_ - pointer_start_; | 1251 const gfx::Vector3dF beam_direction = target_point_ - pointer_start_; |
| 1224 | 1252 |
| 1225 vr::Mat4f beam_direction_mat; | 1253 vr::Mat4f beam_direction_mat; |
| 1226 vr::QuatToMatrix(GetRotationFromZAxis(beam_direction), &beam_direction_mat); | 1254 vr::QuatToMatrix(GetRotationFromZAxis(beam_direction), &beam_direction_mat); |
| 1227 | 1255 |
| 1228 float opacity = controller_->GetOpacity(); | 1256 float opacity = controller_->GetOpacity(); |
| 1229 // Render multiple faces to make the laser appear cylindrical. | 1257 // Render multiple faces to make the laser appear cylindrical. |
| 1230 const int faces = 4; | 1258 const int faces = 4; |
| 1259 vr::Mat4f face_transform; | |
| 1260 vr::Mat4f transform; | |
| 1231 for (int i = 0; i < faces; i++) { | 1261 for (int i = 0; i < faces; i++) { |
| 1232 // Rotate around Z. | 1262 // Rotate around Z. |
| 1233 const float angle = M_PI * 2 * i / faces; | 1263 const float angle = M_PI * 2 * i / faces; |
| 1234 const vr::Quatf rot = vr::QuatFromAxisAngle({0.0f, 0.0f, 1.0f, angle}); | 1264 const vr::Quatf rot = vr::QuatFromAxisAngle({0.0f, 0.0f, 1.0f, angle}); |
| 1235 vr::Mat4f face_transform; | |
| 1236 vr::QuatToMatrix(rot, &face_transform); | 1265 vr::QuatToMatrix(rot, &face_transform); |
| 1237 vr::MatrixMul(face_transform, mat, &face_transform); | 1266 vr::MatrixMul(face_transform, mat, &face_transform); |
| 1238 // Orient according to target direction. | 1267 // Orient according to target direction. |
| 1239 vr::MatrixMul(beam_direction_mat, face_transform, &face_transform); | 1268 vr::MatrixMul(beam_direction_mat, face_transform, &face_transform); |
| 1240 | 1269 |
| 1241 // Move the beam origin to the hand. | 1270 // Move the beam origin to the hand. |
| 1242 vr::TranslateM(face_transform, pointer_start_ - kOrigin, &face_transform); | 1271 vr::TranslateM(face_transform, pointer_start_ - kOrigin, &face_transform); |
| 1243 | |
| 1244 vr::MatrixMul(render_matrix, face_transform, &transform); | 1272 vr::MatrixMul(render_matrix, face_transform, &transform); |
| 1245 vr_shell_renderer_->GetLaserRenderer()->Draw(opacity, transform); | 1273 vr_shell_renderer_->GetLaserRenderer()->Draw(opacity, transform); |
| 1246 } | 1274 } |
| 1247 } | 1275 } |
| 1248 | 1276 |
| 1249 void VrShellGl::DrawController(const vr::Mat4f& view_proj_matrix) { | 1277 void VrShellGl::DrawController(const vr::Mat4f& view_proj_matrix) { |
| 1250 if (!vr_shell_renderer_->GetControllerRenderer()->IsSetUp()) | 1278 if (!vr_shell_renderer_->GetControllerRenderer()->IsSetUp()) |
| 1251 return; | 1279 return; |
| 1252 auto state = controller_->GetModelState(); | 1280 auto state = controller_->GetModelState(); |
| 1253 auto opacity = controller_->GetOpacity(); | 1281 auto opacity = controller_->GetOpacity(); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1430 // This assumes that the initial webvr_surface_size_ was set to the | 1458 // This assumes that the initial webvr_surface_size_ was set to the |
| 1431 // appropriate recommended render resolution as the default size during | 1459 // appropriate recommended render resolution as the default size during |
| 1432 // InitializeGl. Revisit if the initialization order changes. | 1460 // InitializeGl. Revisit if the initialization order changes. |
| 1433 device::mojom::VRDisplayInfoPtr info = | 1461 device::mojom::VRDisplayInfoPtr info = |
| 1434 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), | 1462 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), |
| 1435 webvr_surface_size_, device_id); | 1463 webvr_surface_size_, device_id); |
| 1436 browser_->RunVRDisplayInfoCallback(callback, &info); | 1464 browser_->RunVRDisplayInfoCallback(callback, &info); |
| 1437 } | 1465 } |
| 1438 | 1466 |
| 1439 } // namespace vr_shell | 1467 } // namespace vr_shell |
| OLD | NEW |