diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 99862cfc98..7e5ce36387 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -107,7 +107,11 @@ Avatar::Avatar(Agent* owningAgent) : _driveKeys[i] = false; } - initializeSkeleton(); + _skeleton.initialize(); + + _maxArmLength = _skeleton.getArmLength(); + _pelvisStandingHeight = _skeleton.getPelvisStandingHeight(); + _pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight(); _avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS); @@ -218,10 +222,20 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { // update balls if (_balls) { _balls->simulate(deltaTime); } - // if other avatar, update head position from network data - + // create orientation directions based on yaw/pitch/roll... + _orientation.setToIdentity(); + _orientation.yaw (_bodyYaw ); + _orientation.pitch(_bodyPitch); + _orientation.roll (_bodyRoll ); + _orientation.rotate(_righting); + // update avatar skeleton - updateSkeleton(); + _skeleton.update(deltaTime, _orientation, _position); + + // if this is not my avatar, then hand position comes from transmitted data + if (_owningAgent) { + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handPosition; + } //detect and respond to collisions with other avatars... if (!_owningAgent) { @@ -405,22 +419,22 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _orientation.getRight() * _head.getLeanSideways() + _orientation.getFront() * _head.getLeanForward(); - _joint[ AVATAR_JOINT_TORSO ].springyPosition += headLean * 0.1f; - _joint[ AVATAR_JOINT_CHEST ].springyPosition += headLean * 0.4f; - _joint[ AVATAR_JOINT_NECK_BASE ].springyPosition += headLean * 0.7f; - _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition += headLean * 1.0f; + _skeleton.joint[ AVATAR_JOINT_TORSO ].springyPosition += headLean * 0.1f; + _skeleton.joint[ AVATAR_JOINT_CHEST ].springyPosition += headLean * 0.4f; + _skeleton.joint[ AVATAR_JOINT_NECK_BASE ].springyPosition += headLean * 0.7f; + _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition += headLean * 1.0f; - _joint[ AVATAR_JOINT_LEFT_COLLAR ].springyPosition += headLean * 0.6f; - _joint[ AVATAR_JOINT_LEFT_SHOULDER ].springyPosition += headLean * 0.6f; - _joint[ AVATAR_JOINT_LEFT_ELBOW ].springyPosition += headLean * 0.2f; - _joint[ AVATAR_JOINT_LEFT_WRIST ].springyPosition += headLean * 0.1f; - _joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].springyPosition += headLean * 0.0f; + _skeleton.joint[ AVATAR_JOINT_LEFT_COLLAR ].springyPosition += headLean * 0.6f; + _skeleton.joint[ AVATAR_JOINT_LEFT_SHOULDER ].springyPosition += headLean * 0.6f; + _skeleton.joint[ AVATAR_JOINT_LEFT_ELBOW ].springyPosition += headLean * 0.2f; + _skeleton.joint[ AVATAR_JOINT_LEFT_WRIST ].springyPosition += headLean * 0.1f; + _skeleton.joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].springyPosition += headLean * 0.0f; - _joint[ AVATAR_JOINT_RIGHT_COLLAR ].springyPosition += headLean * 0.6f; - _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].springyPosition += headLean * 0.6f; - _joint[ AVATAR_JOINT_RIGHT_ELBOW ].springyPosition += headLean * 0.2f; - _joint[ AVATAR_JOINT_RIGHT_WRIST ].springyPosition += headLean * 0.1f; - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition += headLean * 0.0f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_COLLAR ].springyPosition += headLean * 0.6f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].springyPosition += headLean * 0.6f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_ELBOW ].springyPosition += headLean * 0.2f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_WRIST ].springyPosition += headLean * 0.1f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition += headLean * 0.0f; } } @@ -434,8 +448,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } _head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); - _head.setPosition(_joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition); - _head.setScale (_joint[ AVATAR_JOINT_HEAD_BASE ].radius); + _head.setPosition(_skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition); + _head.setScale (_skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].radius); _head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2])); _head.simulate(deltaTime, !_owningAgent); @@ -451,15 +465,15 @@ void Avatar::checkForMouseRayTouching() { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - glm::vec3 directionToBodySphere = glm::normalize(_joint[b].springyPosition - _mouseRayOrigin); + glm::vec3 directionToBodySphere = glm::normalize(_skeleton.joint[b].springyPosition - _mouseRayOrigin); float dot = glm::dot(directionToBodySphere, _mouseRayDirection); - float range = _joint[b].radius * JOINT_TOUCH_RANGE; + float range = _skeleton.joint[b].radius * JOINT_TOUCH_RANGE; if (dot > (1.0f - range)) { - _joint[b].touchForce = (dot - (1.0f - range)) / range; + _skeleton.joint[b].touchForce = (dot - (1.0f - range)) / range; } else { - _joint[b].touchForce = 0.0; + _skeleton.joint[b].touchForce = 0.0; } } } @@ -477,7 +491,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { + _orientation.getUp() * -_movedHandOffset.y * 2.0f + _orientation.getFront() * -_movedHandOffset.y * 2.0f; - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement; + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement; if (!_owningAgent) { _avatarTouch.setMyBodyPosition(_position); @@ -516,7 +530,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { _avatarTouch.setHasInteractingOther(true); _avatarTouch.setYourBodyPosition(_interactingOther->_position); _avatarTouch.setYourOrientation (_interactingOther->_orientation); - _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); + _avatarTouch.setYourHandPosition(_interactingOther->_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); _avatarTouch.setYourHandState (_interactingOther->_handState); //if hand-holding is initiated by either avatar, turn on hand-holding... @@ -531,8 +545,8 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { glm::vec3 vectorFromMyHandToYourHand ( - _interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position + _interactingOther->_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position ); float distanceBetweenOurHands = glm::length(vectorFromMyHandToYourHand); @@ -554,10 +568,10 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { //if holding hands, apply the appropriate forces if (_avatarTouch.getHoldingHands()) { - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += ( - _interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position + _interactingOther->_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position + - _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position ) * 0.5f; if (distanceBetweenOurHands > 0.3) { @@ -577,7 +591,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { //Set right hand position and state to be transmitted, and also tell AvatarTouch about it if (!_owningAgent) { - setHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); + setHandPosition(_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); if (_mousePressed) { _handState = HAND_STATE_GRASPING; @@ -586,7 +600,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { } _avatarTouch.setMyHandState(_handState); - _avatarTouch.setMyHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); + _avatarTouch.setMyHandPosition(_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); } } @@ -598,9 +612,9 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere); if (distanceToBigSphere < myBodyApproximateBoundingRadius + radius) { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - glm::vec3 vectorFromJointToBigSphereCenter(_joint[b].springyPosition - position); + glm::vec3 vectorFromJointToBigSphereCenter(_skeleton.joint[b].springyPosition - position); float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter); - float combinedRadius = _joint[b].radius + radius; + float combinedRadius = _skeleton.joint[b].radius + radius; if (distanceToBigSphereCenter < combinedRadius) { jointCollision = true; @@ -610,9 +624,9 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d float penetration = 1.0 - (distanceToBigSphereCenter / combinedRadius); glm::vec3 collisionForce = vectorFromJointToBigSphereCenter * penetration; - _joint[b].springyVelocity += collisionForce * 0.0f * deltaTime; + _skeleton.joint[b].springyVelocity += collisionForce * 0.0f * deltaTime; _velocity += collisionForce * 40.0f * deltaTime; - _joint[b].springyPosition = position + directionVector * combinedRadius; + _skeleton.joint[b].springyPosition = position + directionVector * combinedRadius; } } } @@ -669,7 +683,7 @@ void Avatar::updateAvatarCollisions(float deltaTime) { } // test other avatar hand position for proximity - glm::vec3 v(_joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position); + glm::vec3 v(_skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position); v -= otherAvatar->getPosition(); float distance = glm::length(v); @@ -688,16 +702,16 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime // loop through the joints of each avatar to check for every possible collision for (int b=1; b_joint[o].isCollidable) { + if (otherAvatar->_skeleton.joint[o].isCollidable) { - glm::vec3 vectorBetweenJoints(_joint[b].springyPosition - otherAvatar->_joint[o].springyPosition); + glm::vec3 vectorBetweenJoints(_skeleton.joint[b].springyPosition - otherAvatar->_skeleton.joint[o].springyPosition); float distanceBetweenJoints = glm::length(vectorBetweenJoints); if (distanceBetweenJoints > 0.0) { // to avoid divide by zero - float combinedRadius = _joint[b].radius + otherAvatar->_joint[o].radius; + float combinedRadius = _skeleton.joint[b].radius + otherAvatar->_skeleton.joint[o].radius; // check for collision if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) { @@ -715,21 +729,21 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime if (ballMomentum < 0.0) { ballMomentum = 0.0;} */ - _joint[b].springyVelocity += ballPushForce; - otherAvatar->_joint[o].springyVelocity -= ballPushForce; + _skeleton.joint[b].springyVelocity += ballPushForce; + otherAvatar->_skeleton.joint[o].springyVelocity -= ballPushForce; /* float shift = distanceBetweenJoints - combinedRadius * COLLISION_RADIUS_SCALAR; - _joint[b].springyPosition += directionVector * 2.0f * deltaTime; - otherAvatar->_joint[o].springyPosition -= directionVector * 2.0f * deltaTime; + _skeleton.joint[b].springyPosition += directionVector * 2.0f * deltaTime; + otherAvatar->_skeleton.joint[o].springyPosition -= directionVector * 2.0f * deltaTime; */ /* - _joint[b].springyVelocity *= ballMomentum; - otherAvatar->_joint[o].springyVelocity *= ballMomentum; + _skeleton.joint[b].springyVelocity *= ballMomentum; + otherAvatar->_skeleton.joint[o].springyVelocity *= ballMomentum; */ // accumulate forces and frictions to apply to the velocities of avatar bodies @@ -810,9 +824,9 @@ void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { float modelview[16]; glGetFloatv(GL_MODELVIEW_MATRIX, modelview); - glTranslatef(_joint[AVATAR_JOINT_HEAD_BASE].springyPosition.x, - _joint[AVATAR_JOINT_HEAD_BASE].springyPosition.y + chatMessageHeight, - _joint[AVATAR_JOINT_HEAD_BASE].springyPosition.z); + glTranslatef(_skeleton.joint[AVATAR_JOINT_HEAD_BASE].springyPosition.x, + _skeleton.joint[AVATAR_JOINT_HEAD_BASE].springyPosition.y + chatMessageHeight, + _skeleton.joint[AVATAR_JOINT_HEAD_BASE].springyPosition.z); glRotatef(atan2(-modelview[2], -modelview[10]) * 180 / PI, 0, 1, 0); glColor3f(0, 0.8, 0); @@ -842,219 +856,20 @@ void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { } } -void Avatar::initializeSkeleton() { - - for (int b=0; b BEYOND_BODY_SPRING_RANGE) { - initializeBodySprings(); + if (glm::length(_position - _skeleton.joint[AVATAR_JOINT_PELVIS].springyPosition) > BEYOND_BODY_SPRING_RANGE) { + _skeleton.initializeBodySprings(); } for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - glm::vec3 springVector(_joint[b].springyPosition); + glm::vec3 springVector(_skeleton.joint[b].springyPosition); - if (_joint[b].parent == AVATAR_JOINT_NULL) { + if (_skeleton.joint[b].parent == AVATAR_JOINT_NULL) { springVector -= _position; } else { - springVector -= _joint[ _joint[b].parent ].springyPosition; + springVector -= _skeleton.joint[ _skeleton.joint[b].parent ].springyPosition; } float length = glm::length(springVector); @@ -1062,44 +877,44 @@ void Avatar::updateBodySprings(float deltaTime) { if (length > 0.0f) { // to avoid divide by zero glm::vec3 springDirection = springVector / length; - float force = (length - _joint[b].length) * BODY_SPRING_FORCE * deltaTime; + float force = (length - _skeleton.joint[b].length) * BODY_SPRING_FORCE * deltaTime; - _joint[b].springyVelocity -= springDirection * force; + _skeleton.joint[b].springyVelocity -= springDirection * force; - if (_joint[b].parent != AVATAR_JOINT_NULL) { - _joint[_joint[b].parent].springyVelocity += springDirection * force; + if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) { + _skeleton.joint[_skeleton.joint[b].parent].springyVelocity += springDirection * force; } } // apply tightness force - (causing springy position to be close to rigid body position) - _joint[b].springyVelocity += (_joint[b].position - _joint[b].springyPosition) * _joint[b].springBodyTightness * deltaTime; + _skeleton.joint[b].springyVelocity += (_skeleton.joint[b].position - _skeleton.joint[b].springyPosition) * _skeleton.joint[b].springBodyTightness * deltaTime; // apply decay float decay = 1.0 - BODY_SPRING_DECAY * deltaTime; if (decay > 0.0) { - _joint[b].springyVelocity *= decay; + _skeleton.joint[b].springyVelocity *= decay; } else { - _joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + _skeleton.joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f); } /* //apply forces from touch... - if (_joint[b].touchForce > 0.0) { - _joint[b].springyVelocity += _mouseRayDirection * _joint[b].touchForce * 0.7f; + if (_skeleton.joint[b].touchForce > 0.0) { + _skeleton.joint[b].springyVelocity += _mouseRayDirection * _skeleton.joint[b].touchForce * 0.7f; } */ //update position by velocity... - _joint[b].springyPosition += _joint[b].springyVelocity * deltaTime; + _skeleton.joint[b].springyPosition += _skeleton.joint[b].springyVelocity * deltaTime; } } void Avatar::updateArmIKAndConstraints(float deltaTime) { // determine the arm vector - glm::vec3 armVector = _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position; - armVector -= _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; + glm::vec3 armVector = _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position; + armVector -= _skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; // test to see if right hand is being dragged beyond maximum arm length float distance = glm::length(armVector); @@ -1107,28 +922,28 @@ void Avatar::updateArmIKAndConstraints(float deltaTime) { // don't let right hand get dragged beyond maximum arm length... if (distance > _maxArmLength) { // reset right hand to be constrained to maximum arm length - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; glm::vec3 armNormal = armVector / distance; armVector = armNormal * _maxArmLength; distance = _maxArmLength; - glm::vec3 constrainedPosition = _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; + glm::vec3 constrainedPosition = _skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position; constrainedPosition += armVector; - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = constrainedPosition; + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = constrainedPosition; } // set elbow position - glm::vec3 newElbowPosition = _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position + armVector * ONE_HALF; + glm::vec3 newElbowPosition = _skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position + armVector * ONE_HALF; glm::vec3 perpendicular = glm::cross( _orientation.getRight(), armVector); newElbowPosition += perpendicular * (1.0f - (_maxArmLength / distance)) * ONE_HALF; - _joint[ AVATAR_JOINT_RIGHT_ELBOW ].position = newElbowPosition; + _skeleton.joint[ AVATAR_JOINT_RIGHT_ELBOW ].position = newElbowPosition; // set wrist position - glm::vec3 vv(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); - vv -= _joint[ AVATAR_JOINT_RIGHT_ELBOW ].position; - glm::vec3 newWristPosition = _joint[ AVATAR_JOINT_RIGHT_ELBOW ].position + vv * 0.7f; - _joint[ AVATAR_JOINT_RIGHT_WRIST ].position = newWristPosition; + glm::vec3 vv(_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); + vv -= _skeleton.joint[ AVATAR_JOINT_RIGHT_ELBOW ].position; + glm::vec3 newWristPosition = _skeleton.joint[ AVATAR_JOINT_RIGHT_ELBOW ].position + vv * 0.7f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_WRIST ].position = newWristPosition; } @@ -1139,7 +954,7 @@ void Avatar::renderBody(bool lookingInMirror) { // Render the body as balls and cones for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - float distanceToCamera = glm::length(_cameraPosition - _joint[b].position); + float distanceToCamera = glm::length(_cameraPosition - _skeleton.joint[b].position); float alpha = glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) / (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f); @@ -1160,26 +975,26 @@ void Avatar::renderBody(bool lookingInMirror) { if (_owningAgent || b == AVATAR_JOINT_RIGHT_ELBOW || b == AVATAR_JOINT_RIGHT_WRIST || b == AVATAR_JOINT_RIGHT_FINGERTIPS ) { - glColor3f(SKIN_COLOR[0] + _joint[b].touchForce * 0.3f, - SKIN_COLOR[1] - _joint[b].touchForce * 0.2f, - SKIN_COLOR[2] - _joint[b].touchForce * 0.1f); + glColor3f(SKIN_COLOR[0] + _skeleton.joint[b].touchForce * 0.3f, + SKIN_COLOR[1] - _skeleton.joint[b].touchForce * 0.2f, + SKIN_COLOR[2] - _skeleton.joint[b].touchForce * 0.1f); } else { - glColor4f(SKIN_COLOR[0] + _joint[b].touchForce * 0.3f, - SKIN_COLOR[1] - _joint[b].touchForce * 0.2f, - SKIN_COLOR[2] - _joint[b].touchForce * 0.1f, + glColor4f(SKIN_COLOR[0] + _skeleton.joint[b].touchForce * 0.3f, + SKIN_COLOR[1] - _skeleton.joint[b].touchForce * 0.2f, + SKIN_COLOR[2] - _skeleton.joint[b].touchForce * 0.1f, alpha); } if ((b != AVATAR_JOINT_HEAD_TOP ) && (b != AVATAR_JOINT_HEAD_BASE )) { glPushMatrix(); - glTranslatef(_joint[b].springyPosition.x, _joint[b].springyPosition.y, _joint[b].springyPosition.z); - glutSolidSphere(_joint[b].radius, 20.0f, 20.0f); + glTranslatef(_skeleton.joint[b].springyPosition.x, _skeleton.joint[b].springyPosition.y, _skeleton.joint[b].springyPosition.z); + glutSolidSphere(_skeleton.joint[b].radius, 20.0f, 20.0f); glPopMatrix(); } // Render the cone connecting this joint to its parent - if (_joint[b].parent != AVATAR_JOINT_NULL) { + if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) { if ((b != AVATAR_JOINT_HEAD_TOP ) && (b != AVATAR_JOINT_HEAD_BASE ) && (b != AVATAR_JOINT_PELVIS ) @@ -1191,15 +1006,15 @@ void Avatar::renderBody(bool lookingInMirror) { && (b != AVATAR_JOINT_RIGHT_SHOULDER)) { glColor3fv(DARK_SKIN_COLOR); - float r1 = _joint[_joint[b].parent ].radius * 0.8; - float r2 = _joint[b ].radius * 0.8; + float r1 = _skeleton.joint[_skeleton.joint[b].parent ].radius * 0.8; + float r2 = _skeleton.joint[b ].radius * 0.8; if (b == AVATAR_JOINT_HEAD_BASE) { r1 *= 0.5f; } renderJointConnectingCone ( - _joint[_joint[b].parent ].springyPosition, - _joint[b ].springyPosition, r2, r2 + _skeleton.joint[_skeleton.joint[b].parent ].springyPosition, + _skeleton.joint[b ].springyPosition, r2, r2 ); } } diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 1ef5675d9b..0518561322 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -67,9 +67,9 @@ public: float getHeadYawRate () const { return _head.yawRate;} float getBodyYaw () const { return _bodyYaw;} bool getIsNearInteractingOther() const { return _avatarTouch.getAbleToReachOtherAvatar();} - const glm::vec3& getHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].position;} - const glm::vec3& getSpringyHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition;} - const glm::vec3& getJointPosition (AvatarJointID j) const { return _joint[j].springyPosition;} + const glm::vec3& getHeadPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].position;} + const glm::vec3& getSpringyHeadPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition;} + const glm::vec3& getJointPosition (AvatarJointID j) const { return _skeleton.joint[j].springyPosition;} const glm::vec3& getBodyUpDirection () const { return _orientation.getUp();} const glm::vec3& getVelocity () const { return _velocity;} float getSpeed () const { return _speed;} @@ -96,6 +96,7 @@ private: Avatar(const Avatar&); Avatar& operator= (const Avatar&); +/* struct AvatarJoint { AvatarJointID parent; // which joint is this joint connected to? @@ -114,6 +115,7 @@ private: bool isCollidable; // when false, the joint position will not register a collision float touchForce; // if being touched, what's the degree of influence? (0 to 1) }; +*/ Head _head; Skeleton _skeleton; @@ -125,7 +127,7 @@ private: float _bodyRollDelta; glm::vec3 _movedHandOffset; glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion - AvatarJoint _joint[ NUM_AVATAR_JOINTS ]; + //AvatarJoint _joint[ NUM_AVATAR_JOINTS ]; AvatarMode _mode; glm::vec3 _cameraPosition; glm::vec3 _handHoldingPosition; @@ -153,7 +155,6 @@ private: glm::vec3 caclulateAverageEyePosition() { return _head.caclulateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat) void renderBody(bool lookingInMirror); void initializeSkeleton(); - void updateSkeleton(); void initializeBodySprings(); void updateBodySprings( float deltaTime ); void calculateBoneLengths(); diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index fa0744bf49..8290e2b418 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -30,7 +30,7 @@ Camera::Camera() { _needsToInitialize = true; _frustumNeedsReshape = true; - _modeShift = 0.0f; + _modeShift = 1.0f; _modeShiftRate = 1.0f; _linearModeShift = 0.0f; _mode = CAMERA_MODE_THIRD_PERSON; diff --git a/interface/src/Skeleton.cpp b/interface/src/Skeleton.cpp index 49e8dea053..37f37516ea 100644 --- a/interface/src/Skeleton.cpp +++ b/interface/src/Skeleton.cpp @@ -6,15 +6,225 @@ #include "Skeleton.h" +const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f; +const float FLOATING_HEIGHT = 0.13f; + +float test = 0.0f; + +/* +float testYaw = 0.0f; +float testPitch = 0.0f; +float testRoll = 0.0f; +*/ + Skeleton::Skeleton() { } void Skeleton::initialize() { + + for (int b=0; b +#include +#include + enum AvatarJointID { AVATAR_JOINT_NULL = -1, @@ -45,10 +49,40 @@ public: Skeleton(); void initialize(); - void simulate(float deltaTime); + void initializeBodySprings(); + void update(float deltaTime, Orientation orientation, glm::vec3 position); void render(); + float getArmLength(); + float getHeight(); + float getPelvisStandingHeight(); + float getPelvisFloatingHeight(); + + struct AvatarJoint + { + AvatarJointID parent; // which joint is this joint connected to? + glm::vec3 position; // the position at the "end" of the joint - in global space + glm::vec3 defaultPosePosition; // the parent relative position when the avatar is in the "T-pose" + glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position) + glm::vec3 springyVelocity; // used for special effects ( the velocity of the springy position) + float springBodyTightness; // how tightly the springy position tries to stay on the position + glm::quat rotation; // this will eventually replace yaw, pitch and roll (and maybe orientation) + float yaw; // the yaw Euler angle of the joint rotation off the parent + float pitch; // the pitch Euler angle of the joint rotation off the parent + float roll; // the roll Euler angle of the joint rotation off the parent + Orientation orientation; // three orthogonal normals determined by yaw, pitch, roll + float length; // the length of vector connecting the joint and its parent + float radius; // used for detecting collisions for certain physical effects + bool isCollidable; // when false, the joint position will not register a collision + float touchForce; // if being touched, what's the degree of influence? (0 to 1) + }; + + AvatarJoint joint[ NUM_AVATAR_JOINTS ]; + private: -}; + + void calculateBoneLengths(); + + }; #endif