From 40dee3b39eb01b1adf69b8d56f3eae1212ff8c21 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 25 Jun 2014 05:24:22 -0700 Subject: [PATCH] Added JS calls for left/right estimated palm position on skeleton model, improved toy ball to use them --- examples/toyball.js | 17 +------- interface/src/avatar/Avatar.cpp | 65 ++++++++++++++++++++++++++----- interface/src/avatar/MyAvatar.cpp | 19 +++++++++ interface/src/avatar/MyAvatar.h | 5 ++- 4 files changed, 80 insertions(+), 26 deletions(-) diff --git a/examples/toyball.js b/examples/toyball.js index 5fd522ef4a..e03fd67a5d 100644 --- a/examples/toyball.js +++ b/examples/toyball.js @@ -51,25 +51,12 @@ function debugPrint(message) { } function getBallHoldPosition(whichSide) { - var normal; - var tipPosition; if (whichSide == LEFT_PALM) { - normal = Controller.getSpatialControlNormal(LEFT_PALM); - tipPosition = Controller.getSpatialControlPosition(LEFT_TIP); + position = MyAvatar.getLeftPalmPosition(); } else { - normal = Controller.getSpatialControlNormal(RIGHT_PALM); - tipPosition = Controller.getSpatialControlPosition(RIGHT_TIP); + position = MyAvatar.getRightPalmPosition(); } - var BALL_FORWARD_OFFSET = 0.15; // put the ball a bit forward of fingers - position = { x: BALL_FORWARD_OFFSET * normal.x, - y: BALL_FORWARD_OFFSET * normal.y, - z: BALL_FORWARD_OFFSET * normal.z }; - - position.x += tipPosition.x; - position.y += tipPosition.y; - position.z += tipPosition.z; - return position; } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ee65b9c170..ee8e7266cb 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -382,25 +382,46 @@ void Avatar::renderBody(RenderMode renderMode, float glowLevel) { const float HAIR_LENGTH = 0.2f; const float HAIR_LINK_LENGTH = HAIR_LENGTH / HAIR_LINKS; const float HAIR_DAMPING = 0.99f; -const float HEAD_RADIUS = 0.15f; -const float COLLISION_RELAXATION = 10.f; -const float CONSTRAINT_RELAXATION = 10.0f; -const glm::vec3 HAIR_GRAVITY(0.f, -0.005f, 0.f); +const float HEAD_RADIUS = 0.18f; +const float CONSTRAINT_RELAXATION = 20.0f; +const glm::vec3 HAIR_GRAVITY(0.f, -0.015f, 0.f); const float HAIR_ACCELERATION_COUPLING = 0.025f; const float HAIR_ANGULAR_VELOCITY_COUPLING = 0.10f; const float HAIR_MAX_LINEAR_ACCELERATION = 4.f; -const float HAIR_THICKNESS = 0.025f; -const float HAIR_STIFFNESS = 0.002f; +const float HAIR_THICKNESS = 0.020f; +const float HAIR_STIFFNESS = 0.0006f; const glm::vec3 HAIR_COLOR1(0.98f, 0.92f, 0.843f); const glm::vec3 HAIR_COLOR2(0.545f, 0.533f, 0.47f); const glm::vec3 WIND_DIRECTION(0.5f, -1.0f, 0.f); const float MAX_WIND_STRENGTH = 0.01f; +const float FINGER_LENGTH = 0.25; +const float FINGER_RADIUS = 0.10; void Avatar::renderHair() { // // Render the avatar's moveable hair // + glm::vec3 headPosition = getHead()->getPosition(); + /* + glm::vec3 leftHandPosition, rightHandPosition; + getSkeletonModel().getLeftHandPosition(leftHandPosition); + getSkeletonModel().getRightHandPosition(rightHandPosition); + glm::quat leftRotation, rightRotation; + getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation); + rightHandPosition += glm::vec3(0.0f, FINGER_LENGTH, 0.f) * glm::inverse(rightRotation); + + glPushMatrix(); + glTranslatef(leftHandPosition.x, leftHandPosition.y, leftHandPosition.z); + glColor4f(1.0f, 0.0f, 0.0f, 0.5f); + glutSolidSphere(FINGER_RADIUS, 20, 20); + glPopMatrix(); + glPushMatrix(); + glTranslatef(rightHandPosition.x, rightHandPosition.y, rightHandPosition.z); + glColor4f(1.0f, 0.0f, 0.0f, 0.5f); + glutSolidSphere(FINGER_RADIUS, 20, 20); + glPopMatrix(); + */ glPushMatrix(); glTranslatef(headPosition.x, headPosition.y, headPosition.z); @@ -431,13 +452,12 @@ void Avatar::renderHair() { } glEnd(); - //glColor4f(1.0f, 0.0f, 0.0f, 0.5f); - //glutSolidSphere(HEAD_RADIUS, 20, 20); glPopMatrix(); } void Avatar::simulateHair(float deltaTime) { + deltaTime = glm::clamp(deltaTime, 0.f, 1.f / 30.f); glm::vec3 acceleration = getAcceleration(); if (glm::length(acceleration) > HAIR_MAX_LINEAR_ACCELERATION) { @@ -447,6 +467,20 @@ void Avatar::simulateHair(float deltaTime) { acceleration = acceleration * rotation; glm::vec3 angularVelocity = getAngularVelocity() + getHead()->getAngularVelocity(); + // Get hand positions to allow touching hair + glm::vec3 leftHandPosition, rightHandPosition; + getSkeletonModel().getLeftHandPosition(leftHandPosition); + getSkeletonModel().getRightHandPosition(rightHandPosition); + leftHandPosition -= getHead()->getPosition(); + rightHandPosition -= getHead()->getPosition(); + glm::quat leftRotation, rightRotation; + getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation); + getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation); + leftHandPosition += glm::vec3(0.0f, FINGER_LENGTH, 0.f) * glm::inverse(leftRotation); + rightHandPosition += glm::vec3(0.0f, FINGER_LENGTH, 0.f) * glm::inverse(rightRotation); + leftHandPosition = leftHandPosition * rotation; + rightHandPosition = rightHandPosition * rotation; + float windIntensity = randFloat() * MAX_WIND_STRENGTH; for (int strand = 0; strand < HAIR_STRANDS; strand++) { @@ -462,11 +496,22 @@ void Avatar::simulateHair(float deltaTime) { glm::vec3 thisPosition = _hairPosition[vertexIndex]; glm::vec3 diff = thisPosition - _hairLastPosition[vertexIndex]; _hairPosition[vertexIndex] += diff * HAIR_DAMPING; - // Attempt to resolve collision with head sphere + // Resolve collision with head sphere if (glm::length(_hairPosition[vertexIndex]) < HEAD_RADIUS) { _hairPosition[vertexIndex] += glm::normalize(_hairPosition[vertexIndex]) * - (HEAD_RADIUS - glm::length(_hairPosition[vertexIndex])) * COLLISION_RELAXATION * deltaTime; + (HEAD_RADIUS - glm::length(_hairPosition[vertexIndex])); // * COLLISION_RELAXATION * deltaTime; } + // Collide with hands + if (glm::length(_hairPosition[vertexIndex] - leftHandPosition) < FINGER_RADIUS) { + _hairPosition[vertexIndex] += glm::normalize(_hairPosition[vertexIndex] - leftHandPosition) * + (FINGER_RADIUS - glm::length(_hairPosition[vertexIndex] - leftHandPosition)); + } + if (glm::length(_hairPosition[vertexIndex] - rightHandPosition) < FINGER_RADIUS) { + _hairPosition[vertexIndex] += glm::normalize(_hairPosition[vertexIndex] - rightHandPosition) * + (FINGER_RADIUS - glm::length(_hairPosition[vertexIndex] - rightHandPosition)); + } + + // Add a little gravity _hairPosition[vertexIndex] += HAIR_GRAVITY * rotation * deltaTime; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index bbdf041341..5d6b381296 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -422,6 +422,25 @@ void MyAvatar::renderHeadMouse(int screenWidth, int screenHeight) const { } } +const glm::vec3 HAND_TO_PALM_OFFSET(0.0f, 0.12f, 0.08f); + +glm::vec3 MyAvatar::getLeftPalmPosition() { + glm::vec3 leftHandPosition; + getSkeletonModel().getLeftHandPosition(leftHandPosition); + glm::quat leftRotation; + getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation); + leftHandPosition += HAND_TO_PALM_OFFSET * glm::inverse(leftRotation); + return leftHandPosition; +} +glm::vec3 MyAvatar::getRightPalmPosition() { + glm::vec3 rightHandPosition; + getSkeletonModel().getRightHandPosition(rightHandPosition); + glm::quat rightRotation; + getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation); + rightHandPosition += HAND_TO_PALM_OFFSET * glm::inverse(rightRotation); + return rightHandPosition; +} + void MyAvatar::setLocalGravity(glm::vec3 gravity) { _motionBehaviors |= AVATAR_MOTION_OBEY_LOCAL_GRAVITY; // Environmental and Local gravities are incompatible. Since Local is being set here diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index e7023b45a1..0ee76c6b45 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -139,7 +139,10 @@ public slots: void setThrust(glm::vec3 newThrust) { _thrust = newThrust; } void updateMotionBehaviorsFromMenu(); - + + glm::vec3 getLeftPalmPosition(); + glm::vec3 getRightPalmPosition(); + signals: void transformChanged();