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

Unified Diff: chrome/browser/android/vr_shell/elbow_model.cc

Issue 2795793002: Implementation of elbow model for the controller position and rotation. (Closed)
Patch Set: Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/vr_shell/elbow_model.cc
diff --git a/chrome/browser/android/vr_shell/elbow_model.cc b/chrome/browser/android/vr_shell/elbow_model.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9ab7819b17be0269126c1d95bb2460512140823e
--- /dev/null
+++ b/chrome/browser/android/vr_shell/elbow_model.cc
@@ -0,0 +1,130 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Adapted from:
+// https://github.com/googlevr/gvr-unity-sdk/blob/master/Samples/DaydreamLabsControllerPlayground/Assets/GoogleVR/Scripts/Controller/GvrArmModel.cs
+
+#include "chrome/browser/android/vr_shell/elbow_model.h"
+
+#include <cmath>
+
+#include "chrome/browser/android/vr_shell/vr_math.h"
+
+namespace vr_shell {
+
+namespace {
+
+constexpr gvr::Quatf kNoRotation = {0.f, 0.f, 0.f, 1.f};
+constexpr gvr::Vec3f kDefaultShoulderRight = {0.19f, -0.19f, 0.03f};
+constexpr float kFadeDistanceFromFace = 0.34f;
+constexpr gvr::Vec3f kDefaultRelativeElbow = {0.195f, -0.5f, 0.075f};
+constexpr gvr::Vec3f kDefaultRelativeWrist = {0.f, 0.f, -0.25f};
+constexpr gvr::Vec3f kForward = {0.f, 0.f, -1.f};
+constexpr gvr::Vec3f kUp = {0.f, 1.f, 0.f};
+constexpr float kMinExtensionAngle = 7.f;
+constexpr float kMaxExtenstionAngle = 60.f;
+constexpr float kExtensionWeight = 0.4f;
+constexpr float kDeltaAlpha = 3.f;
+
+} // namespace
+
+ElbowModel::ElbowModel(gvr_controller_handedness handedness)
+ : handedness_(handedness), alpha_value_(1.f), torso_direction_{0, 0, 0} {}
+
+ElbowModel::~ElbowModel() = default;
+
+void ElbowModel::UpdateHandedness() {
+ handed_multiplier_ = {handedness_ == GVR_CONTROLLER_RIGHT_HANDED ? 1.f : -1.f,
+ 1.f, 1.f};
+ shoulder_rotation_ = kNoRotation;
+ shoulder_position_ =
+ PointwiseVectorMul(kDefaultShoulderRight, handed_multiplier_);
+}
+
+void ElbowModel::Update(const UpdateData& update) {
+ UpdateHandedness();
+ UpdateTorsoDirection(update);
+ ApplyArmModel(update);
+ UpdateTransparency(update);
+}
+
+void ElbowModel::UpdateTorsoDirection(const UpdateData& update) {
+ auto head_direction = update.head_direction;
+ head_direction.y = 0;
+ NormalizeVector(head_direction);
+
+ // Determine the gaze direction horizontally.
+ float angular_velocity = VectorLength(update.gyro);
+ float gaze_filter_strength =
+ Clampf((angular_velocity - .2f) / 45.f, 0.f, 0.1f);
cjgrant 2017/04/03 19:24:59 0.2f here (and everywhere please). Ie, not .2f or
acondor_ 2017/04/19 18:44:27 Done.
+ torso_direction_ =
+ QuatSlerp(torso_direction_, head_direction, gaze_filter_strength);
+
+ // Rotate the fixed joints.
+ auto gaze_rotation = FromToRotation(kForward, torso_direction_);
+ shoulder_rotation_ = gaze_rotation;
+ shoulder_position_ =
+ MatrixVectorRotate(QuatToMatrix(gaze_rotation), shoulder_position_);
+}
+
+void ElbowModel::ApplyArmModel(const UpdateData& update) {
+ // Controller's orientation relative to the player.
cjgrant 2017/04/03 19:24:59 s/player/user/ everywhere?
acondor_ 2017/04/19 18:44:27 Done.
+ auto controller_orientation = update.orientation;
+ controller_orientation =
+ QuatMultiply(QuatInverted(shoulder_rotation_), controller_orientation);
+
+ // Relative positions of the joints.
+ elbow_position_ =
+ PointwiseVectorMul(kDefaultRelativeElbow, handed_multiplier_);
+ wrist_position_ =
+ PointwiseVectorMul(kDefaultRelativeWrist, handed_multiplier_);
+ auto arm_extension_offset =
+ PointwiseVectorMul({-0.13f, 0.14f, -0.08f}, handed_multiplier_);
cjgrant 2017/04/03 19:24:59 The vector here should be a constant as well.
acondor_ 2017/04/19 18:44:27 Done.
+
+ // Extract just the x rotation angle.
+ auto controller_forward =
+ MatrixVectorRotate(QuatToMatrix(controller_orientation), kForward);
+ float x_angle = 90.f - VectorAngleDegrees(controller_forward, kUp);
+
+ // Remove the z rotation from the controller
+ auto x_y_rotation = FromToRotation(kForward, controller_forward);
+
+ // Offset the elbow by the extension.
+ float normalized_angle = (x_angle - kMinExtensionAngle) /
+ (kMaxExtenstionAngle - kMinExtensionAngle);
+ float extension_ratio = Clampf(normalized_angle, 0.f, 1.f);
+ elbow_position_ = VectorAdd(
+ elbow_position_, VectorScalarMul(arm_extension_offset, extension_ratio));
+
+ // Calculate the lerp interpolation factor.
+ float total_angle = QuatAngleDegrees(x_y_rotation, kNoRotation);
+ float lerp_suppresion = 1.f - pow(total_angle / 180.f, 6);
+ float lerp_value =
+ lerp_suppresion * (0.4f + 0.6f * extension_ratio * kExtensionWeight);
asimjour1 2017/04/19 18:58:12 please move the magic numbers from here and define
acondor_ 2017/04/21 21:04:31 Done.
+
+ // Apply the absolute rotations to the joints.
+ auto lerp_rotation = QuatLerp(kNoRotation, x_y_rotation, lerp_value);
+ elbow_rotation_ = QuatMultiply(
+ QuatMultiply(shoulder_rotation_, QuatInverted(lerp_rotation)),
+ controller_orientation);
+ wrist_rotation_ = QuatMultiply(shoulder_rotation_, controller_orientation);
+
+ // Determine the relative positions.
+ elbow_position_ =
+ MatrixVectorRotate(QuatToMatrix(shoulder_rotation_), elbow_position_);
+ wrist_position_ = VectorAdd(
+ elbow_position_,
+ MatrixVectorRotate(QuatToMatrix(elbow_rotation_), wrist_position_));
+}
+
+void ElbowModel::UpdateTransparency(const UpdateData& update) {
asimjour1 2017/04/19 18:58:12 IIUC alpha_value/opacity can be obtained from the
acondor_ 2017/04/21 21:04:31 Actually, this is an animation (so it depends on t
+ float distance_to_face = VectorLength(wrist_position_);
+ float alpha_change = kDeltaAlpha * update.delta_time_seconds;
+ alpha_value_ = Clampf(distance_to_face < kFadeDistanceFromFace
+ ? alpha_value_ - alpha_change
+ : alpha_value_ + alpha_change,
+ 0.f, 1.f);
+}
+
+} // namespace vr_shell

Powered by Google App Engine
This is Rietveld 408576698