Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(709)

Side by Side Diff: chrome/browser/android/vr_shell/elbow_model.cc

Issue 2795793002: Implementation of elbow model for the controller position and rotation. (Closed)
Patch Set: nit Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 // Adapted from:
6 // https://github.com/googlevr/gvr-unity-sdk/blob/master/Samples/DaydreamLabsCon trollerPlayground/Assets/GoogleVR/Scripts/Controller/GvrArmModel.cs
7
8 #include "chrome/browser/android/vr_shell/elbow_model.h"
9
10 #include <cmath>
11
12 #include "device/vr/vr_math.h"
13
14 namespace vr_shell {
15
16 namespace {
17
18 constexpr vr::Quatf kNoRotation = {0.0f, 0.0f, 0.0f, 1.0f};
19 constexpr gfx::Point3F kDefaultShoulderRight = {0.19f, -0.19f, 0.03f};
20 constexpr float kFadeDistanceFromFace = 0.34f;
21 constexpr gfx::Point3F kDefaultRelativeElbow = {0.195f, -0.5f, 0.075f};
22 constexpr gfx::Point3F kDefaultRelativeWrist = {0.0f, 0.0f, -0.25f};
23 constexpr gfx::Vector3dF kForward = {0.0f, 0.0f, -1.0f};
24 constexpr gfx::Vector3dF kUp = {0.0f, 1.0f, 0.0f};
25 constexpr gfx::Vector3dF kDefaultArmExtensionOffset = {-0.13f, 0.14f, -0.08f};
26 constexpr float kMinExtensionAngle = 7.0f;
27 constexpr float kMaxExtenstionAngle = 60.0f;
28 constexpr float kExtensionWeight = 0.4f;
29 constexpr float kDeltaAlpha = 3.0f;
30 constexpr float kDefaultElbowRotationRatio = 0.4f;
31
32 } // namespace
33
34 ElbowModel::ElbowModel(gvr::ControllerHandedness handedness)
35 : handedness_(handedness),
36 alpha_value_(1.0f),
37 torso_direction_{0.0f, 0.0f, 0.0f} {}
38
39 ElbowModel::~ElbowModel() = default;
40
41 void ElbowModel::UpdateHandedness() {
42 handed_multiplier_ = {
43 handedness_ == GVR_CONTROLLER_RIGHT_HANDED ? 1.0f : -1.0f, 1.0f, 1.0f};
44 shoulder_rotation_ = kNoRotation;
45 shoulder_position_ =
46 vr::ScalePoint(kDefaultShoulderRight, handed_multiplier_);
47 }
48
49 void ElbowModel::Update(const UpdateData& update) {
50 UpdateHandedness();
51 UpdateTorsoDirection(update);
52 ApplyArmModel(update);
53 UpdateTransparency(update);
54 }
55
56 void ElbowModel::UpdateTorsoDirection(const UpdateData& update) {
57 auto head_direction = update.head_direction;
58 head_direction.set_y(0);
59 vr::NormalizeVector(&head_direction);
60
61 // Determine the gaze direction horizontally.
62 float angular_velocity = update.gyro.Length();
63 float gaze_filter_strength =
64 vr::Clampf((angular_velocity - 0.2f) / 45.0f, 0.0f, 0.1f);
65 torso_direction_ =
66 vr::QuatSlerp(torso_direction_, head_direction, gaze_filter_strength);
67
68 // Rotate the fixed joints.
69 auto gaze_rotation = vr::GetVectorRotation(kForward, torso_direction_);
70 shoulder_rotation_ = gaze_rotation;
71 vr::Mat4f gaze_rotation_mat;
72 vr::QuatToMatrix(gaze_rotation, &gaze_rotation_mat);
73 shoulder_position_ = vr::ToPoint(vr::MatrixVectorRotate(
74 gaze_rotation_mat, vr::ToVector(shoulder_position_)));
75 }
76
77 void ElbowModel::ApplyArmModel(const UpdateData& update) {
78 // Controller's orientation relative to the user.
79 auto controller_orientation = update.orientation;
80 controller_orientation = vr::QuatProduct(vr::InvertQuat(shoulder_rotation_),
81 controller_orientation);
82
83 // Relative positions of the joints.
84 elbow_position_ = vr::ScalePoint(kDefaultRelativeElbow, handed_multiplier_);
85 wrist_position_ = vr::ScalePoint(kDefaultRelativeWrist, handed_multiplier_);
86 auto arm_extension_offset =
87 vr::ScaleVector(kDefaultArmExtensionOffset, handed_multiplier_);
88
89 // Extract just the x rotation angle.
90 vr::Mat4f controller_orientation_mat;
91 QuatToMatrix(controller_orientation, &controller_orientation_mat);
92 auto controller_forward =
93 vr::MatrixVectorRotate(controller_orientation_mat, kForward);
94 float x_angle =
95 90.0f - gfx::AngleBetweenVectorsInDegrees(controller_forward, kUp);
96
97 // Remove the z rotation from the controller
98 auto x_y_rotation = vr::GetVectorRotation(kForward, controller_forward);
99
100 // Offset the elbow by the extension.
101 float normalized_angle = (x_angle - kMinExtensionAngle) /
102 (kMaxExtenstionAngle - kMinExtensionAngle);
103 float extension_ratio = vr::Clampf(normalized_angle, 0.0f, 1.0f);
104 elbow_position_ = elbow_position_ +
105 gfx::ScaleVector3d(arm_extension_offset, extension_ratio);
106
107 // Calculate the lerp interpolation factor.
108 float total_angle = vr::QuatAngleDegrees(x_y_rotation, kNoRotation);
109 float lerp_suppresion = 1.0f - pow(total_angle / 180.0f, 6);
110 float lerp_value = lerp_suppresion * (kDefaultElbowRotationRatio +
111 (1.0f - kDefaultElbowRotationRatio) *
112 extension_ratio * kExtensionWeight);
113
114 // Apply the absolute rotations to the joints.
115 auto lerp_rotation = vr::QuatLerp(kNoRotation, x_y_rotation, lerp_value);
116 elbow_rotation_ = vr::QuatProduct(
117 vr::QuatProduct(shoulder_rotation_, vr::InvertQuat(lerp_rotation)),
118 controller_orientation);
119 wrist_rotation_ = vr::QuatProduct(shoulder_rotation_, controller_orientation);
120
121 // Determine the relative positions.
122 vr::Mat4f shoulder_rotation_mat;
123 QuatToMatrix(shoulder_rotation_, &shoulder_rotation_mat);
124 elbow_position_ = vr::ToPoint(vr::MatrixVectorRotate(
125 shoulder_rotation_mat, vr::ToVector(elbow_position_)));
126 vr::Mat4f elbow_rotation_mat;
127 QuatToMatrix(elbow_rotation_, &elbow_rotation_mat);
128 wrist_position_ =
129 elbow_position_ +
130 vr::MatrixVectorRotate(elbow_rotation_mat, vr::ToVector(wrist_position_));
131 }
132
133 void ElbowModel::UpdateTransparency(const UpdateData& update) {
134 float distance_to_face = vr::ToVector(wrist_position_).Length();
135 float alpha_change = kDeltaAlpha * update.delta_time_seconds;
136 alpha_value_ = vr::Clampf(distance_to_face < kFadeDistanceFromFace
137 ? alpha_value_ - alpha_change
138 : alpha_value_ + alpha_change,
139 0.0f, 1.0f);
140 }
141
142 } // namespace vr_shell
OLDNEW
« no previous file with comments | « chrome/browser/android/vr_shell/elbow_model.h ('k') | chrome/browser/android/vr_shell/vr_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698